Add more Web Audio layout tests
authorcrogers@google.com <crogers@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 9 Aug 2011 20:26:15 +0000 (20:26 +0000)
committercrogers@google.com <crogers@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 9 Aug 2011 20:26:15 +0000 (20:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=65786

Reviewed by Kenneth Russell.

* webaudio/audiobuffersource-expected.wav: Added.
* webaudio/audiobuffersource-playbackrate-expected.wav: Added.
* webaudio/audiobuffersource-playbackrate.html: Added.
* webaudio/audiobuffersource.html: Added.
* webaudio/mixing-expected.wav: Added.
* webaudio/mixing.html: Added.
* webaudio/resources/hyper-reality: Added.
* webaudio/resources/hyper-reality/br-jam-loop.wav: Added.
* webaudio/resources/hyper-reality/laughter.wav: Added.
* webaudio/sample-accurate-scheduling-expected.txt: Added.
* webaudio/sample-accurate-scheduling.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@92704 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/webaudio/audiobuffersource-expected.wav [new file with mode: 0644]
LayoutTests/webaudio/audiobuffersource-playbackrate-expected.wav [new file with mode: 0644]
LayoutTests/webaudio/audiobuffersource-playbackrate.html [new file with mode: 0644]
LayoutTests/webaudio/audiobuffersource.html [new file with mode: 0644]
LayoutTests/webaudio/mixing-expected.wav [new file with mode: 0644]
LayoutTests/webaudio/mixing.html [new file with mode: 0644]
LayoutTests/webaudio/resources/hyper-reality/br-jam-loop.wav [new file with mode: 0644]
LayoutTests/webaudio/resources/hyper-reality/laughter.wav [new file with mode: 0644]
LayoutTests/webaudio/sample-accurate-scheduling-expected.txt [new file with mode: 0644]
LayoutTests/webaudio/sample-accurate-scheduling.html [new file with mode: 0644]

index de4f97a..e19bc7a 100644 (file)
@@ -1,3 +1,22 @@
+2011-08-09  Chris Rogers  <crogers@google.com>
+
+        Add more Web Audio layout tests
+        https://bugs.webkit.org/show_bug.cgi?id=65786
+
+        Reviewed by Kenneth Russell.
+
+        * webaudio/audiobuffersource-expected.wav: Added.
+        * webaudio/audiobuffersource-playbackrate-expected.wav: Added.
+        * webaudio/audiobuffersource-playbackrate.html: Added.
+        * webaudio/audiobuffersource.html: Added.
+        * webaudio/mixing-expected.wav: Added.
+        * webaudio/mixing.html: Added.
+        * webaudio/resources/hyper-reality: Added.
+        * webaudio/resources/hyper-reality/br-jam-loop.wav: Added.
+        * webaudio/resources/hyper-reality/laughter.wav: Added.
+        * webaudio/sample-accurate-scheduling-expected.txt: Added.
+        * webaudio/sample-accurate-scheduling.html: Added.
+
 2011-08-09  Anders Carlsson  <andersca@apple.com>
 
         More Lion skipped list goodness.
diff --git a/LayoutTests/webaudio/audiobuffersource-expected.wav b/LayoutTests/webaudio/audiobuffersource-expected.wav
new file mode 100644 (file)
index 0000000..ec4af88
Binary files /dev/null and b/LayoutTests/webaudio/audiobuffersource-expected.wav differ
diff --git a/LayoutTests/webaudio/audiobuffersource-playbackrate-expected.wav b/LayoutTests/webaudio/audiobuffersource-playbackrate-expected.wav
new file mode 100644 (file)
index 0000000..f3b236e
Binary files /dev/null and b/LayoutTests/webaudio/audiobuffersource-playbackrate-expected.wav differ
diff --git a/LayoutTests/webaudio/audiobuffersource-playbackrate.html b/LayoutTests/webaudio/audiobuffersource-playbackrate.html
new file mode 100644 (file)
index 0000000..f51c3ae
--- /dev/null
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+
+<!--
+Tests that AudioBufferSourceNode can playback at different rates properly.
+Render 72 notes over a 6 octave range.
+-->
+
+<html>
+<head>
+<script type="text/javascript" src="resources/audio-testing.js"></script>
+<script type="text/javascript" src="resources/buffer-loader.js"></script>
+
+</head>
+<body>
+
+<script>
+
+window.onload = init;
+
+var sampleRate = 44100.0;
+var numberOfNotes = 72; // play over a 6 octave range
+var noteDuration = 0.050;
+var noteSpacing = noteDuration + 0.005; // leave 5ms of silence between each "note"
+var lengthInSeconds = numberOfNotes * noteSpacing;
+
+var context = 0;
+var sinWaveBuffer = 0;
+
+function createOneCycleSinWaveBuffer(frequency, sampleRate) {
+    var duration = 1 / frequency;
+    var sampleFrameLength = duration * sampleRate;
+    
+    var audioBuffer = context.createBuffer(2, sampleFrameLength, sampleRate);
+
+    var n = audioBuffer.length;
+    var channelL = audioBuffer.getChannelData(0);
+    var channelR = audioBuffer.getChannelData(1);
+
+    for (var i = 0; i < n; ++i) {
+        channelL[i] = Math.sin(frequency * 2.0*Math.PI * i / sampleRate);
+        channelR[i] = channelL[i];
+    }
+
+    return audioBuffer;
+}
+
+function playNote(time, duration, playbackRate) {
+    var source = context.createBufferSource();
+    source.buffer = sinWaveBuffer;
+    source.playbackRate.value = playbackRate;
+    
+    var gainNode = context.createGainNode();
+    source.connect(gainNode);
+    gainNode.connect(context.destination);
+
+    // Loop and play for the given duration.
+    source.loop = true;
+    source.noteOn(time);
+    source.noteOff(time + duration);
+    
+    // Apply quick fade-in and fade-out to avoid clicks.
+    gainNode.gain.value = 0;
+    gainNode.gain.setValueAtTime(0, time);
+    gainNode.gain.linearRampToValueAtTime(1, time + 0.005);
+    gainNode.gain.setValueAtTime(1, time + duration - 0.005);
+    gainNode.gain.linearRampToValueAtTime(0, time + duration);
+}
+
+function init() {
+    if (!window.layoutTestController)
+        return;
+
+    // Create offline audio context.
+    context = new webkitAudioContext(2, sampleRate * lengthInSeconds, sampleRate);
+
+    // Create a single cycle of a sine wave.
+    // We'll loop this to play notes of a given duration, at a given playback rate.
+    sinWaveBuffer = createOneCycleSinWaveBuffer(440.0, sampleRate);
+
+    // Play 48 notes over a 4 octave range.
+    for (var i = 0; i < numberOfNotes; ++i) {
+        var time = i * noteSpacing;
+
+        var semitone = i - numberOfNotes/2; // start three octaves down
+        
+        // Convert from semitone to rate.
+        var playbackRate = Math.pow(2, semitone / 12);
+
+        playNote(time, noteDuration, playbackRate);
+    }
+
+    context.oncomplete = finishAudioTest;
+    context.startRendering();
+
+    layoutTestController.waitUntilDone();
+}
+
+</script>
+
+</body>
+</html>
diff --git a/LayoutTests/webaudio/audiobuffersource.html b/LayoutTests/webaudio/audiobuffersource.html
new file mode 100644 (file)
index 0000000..2768aed
--- /dev/null
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+
+<!--
+See if we can load an AudioBuffer, create an AudioBufferSourceNode, attach the buffer to it, then play it.
+-->
+
+<html>
+<head>
+<script type="text/javascript" src="resources/audio-testing.js"></script>
+<script type="text/javascript" src="resources/buffer-loader.js"></script>
+
+<script>
+
+window.onload = init;
+
+var sampleRate = 44100.0;
+var lengthInSeconds = 2;
+
+var context = 0;
+var bufferLoader = 0;
+
+function init() {
+    if (!window.layoutTestController)
+        return;
+        
+    // Create offline audio context.
+    context = new webkitAudioContext(2, sampleRate * lengthInSeconds, sampleRate);
+    
+    bufferLoader = new BufferLoader(
+        context,
+        [
+            "resources/hyper-reality/br-jam-loop.wav",
+        ],
+        finishedLoading
+    );
+    
+    bufferLoader.load();
+    layoutTestController.waitUntilDone();
+}
+
+function finishedLoading(bufferList) {
+    var bufferSource = context.createBufferSource();
+    bufferSource.buffer = bufferList[0];
+    
+    bufferSource.connect(context.destination);
+    bufferSource.noteOn(0);
+    
+    context.oncomplete = finishAudioTest;
+    context.startRendering();    
+}
+
+</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/LayoutTests/webaudio/mixing-expected.wav b/LayoutTests/webaudio/mixing-expected.wav
new file mode 100644 (file)
index 0000000..1f1dffd
Binary files /dev/null and b/LayoutTests/webaudio/mixing-expected.wav differ
diff --git a/LayoutTests/webaudio/mixing.html b/LayoutTests/webaudio/mixing.html
new file mode 100644 (file)
index 0000000..d85c036
--- /dev/null
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+
+<!--
+Create two sources and play them simultaneously.  This tests unity-gain summing of AudioNode inputs.
+The result should be some laughing playing at the same time as the drumming.
+-->
+
+<html>
+<head>
+<script type="text/javascript" src="resources/audio-testing.js"></script>
+<script type="text/javascript" src="resources/buffer-loader.js"></script>
+
+</head>
+<body>
+
+<script>
+
+window.onload = init;
+
+var sampleRate = 44100.0;
+var lengthInSeconds = 2;
+
+var context = 0;
+var bufferLoader = 0;
+
+function init() {
+    if (!window.layoutTestController)
+        return;
+        
+    // Create offline audio context.
+    context = new webkitAudioContext(2, sampleRate * lengthInSeconds, sampleRate);
+        
+    bufferLoader = new BufferLoader(
+        context,
+        [
+        "resources/hyper-reality/br-jam-loop.wav",
+        "resources/hyper-reality/laughter.wav",
+        ],
+        finishedLoading
+    );
+
+    bufferLoader.load();
+    layoutTestController.waitUntilDone();
+}
+
+function finishedLoading(bufferList) {
+    // Create two sources and play them at the same time.
+    var source1 = context.createBufferSource();
+    var source2 = context.createBufferSource();
+    source1.buffer = bufferList[0];
+    source2.buffer = bufferList[1];
+    
+    source1.connect(context.destination);
+    source2.connect(context.destination);
+    source1.noteOn(0);
+    source2.noteOn(0);
+    
+    context.oncomplete = finishAudioTest;
+    context.startRendering();    
+}
+
+</script>
+
+</body>
+</html>
diff --git a/LayoutTests/webaudio/resources/hyper-reality/br-jam-loop.wav b/LayoutTests/webaudio/resources/hyper-reality/br-jam-loop.wav
new file mode 100644 (file)
index 0000000..4d25553
Binary files /dev/null and b/LayoutTests/webaudio/resources/hyper-reality/br-jam-loop.wav differ
diff --git a/LayoutTests/webaudio/resources/hyper-reality/laughter.wav b/LayoutTests/webaudio/resources/hyper-reality/laughter.wav
new file mode 100644 (file)
index 0000000..74c1754
Binary files /dev/null and b/LayoutTests/webaudio/resources/hyper-reality/laughter.wav differ
diff --git a/LayoutTests/webaudio/sample-accurate-scheduling-expected.txt b/LayoutTests/webaudio/sample-accurate-scheduling-expected.txt
new file mode 100644 (file)
index 0000000..4819753
--- /dev/null
@@ -0,0 +1,9 @@
+Tests sample-accurate scheduling.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS All events rendered with sample-accuracy.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/webaudio/sample-accurate-scheduling.html b/LayoutTests/webaudio/sample-accurate-scheduling.html
new file mode 100644 (file)
index 0000000..8c282a7
--- /dev/null
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+
+<!--
+Tests that we are able to schedule a series of notes to playback with sample-accuracy.
+We use an impulse so we can tell exactly where the rendering is happening.
+-->
+
+<html>
+<head>
+<link rel="stylesheet" href="../fast/js/resources/js-test-style.css"/>
+<script src="../fast/js/resources/js-test-pre.js"></script>
+<script type="text/javascript" src="resources/audio-testing.js"></script>
+<script type="text/javascript" src="resources/buffer-loader.js"></script>
+</head>
+
+<body>
+
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+description("Tests sample-accurate scheduling.");
+
+var sampleRate = 44100.0;
+var lengthInSeconds = 4;
+
+var context = 0;
+var bufferLoader = 0;
+var impulse;
+
+// See if we can render at exactly these sample offsets.
+var sampleOffsets = [0, 3, 512, 517, 1000, 1005, 20000, 21234, 37590];
+
+function createImpulse() {
+    // An impulse has a value of 1 at time 0, and is otherwise 0.
+    impulse = context.createBuffer(2, 512, sampleRate);
+    var sampleDataL = impulse.getChannelData(0);
+    var sampleDataR = impulse.getChannelData(1);
+    sampleDataL[0] = 1.0;
+    sampleDataR[0] = 1.0;
+}
+
+function playNote(time) {
+    var bufferSource = context.createBufferSource();
+    bufferSource.buffer = impulse;
+    bufferSource.connect(context.destination);
+    bufferSource.noteOn(time);
+}
+
+function checkSampleAccuracy(event) {
+    var buffer = event.renderedBuffer;
+
+    var bufferDataL = buffer.getChannelData(0);
+    var bufferDataR = buffer.getChannelData(1);
+
+    var success = true;
+    
+    // Go through every sample and make sure it's 0, except at positions in sampleOffsets.
+    for (var i = 0; i < buffer.length; ++i) {
+        // Make sure left == right
+        if (bufferDataL[i] != bufferDataR[i]) {
+            testFailed("Rendered buffer left and right channels are not identical.");
+            success = false;
+            break;
+        }
+        
+        if (bufferDataL[i] != 0) {
+            // Make sure this index is  in sampleOffsets
+            var found = false;
+            for (var j = 0; j < sampleOffsets.length; ++j) {
+                if (sampleOffsets[j] == i) {
+                    found = true;
+                    break;
+                }
+            }
+            
+            if (!found) {
+                testFailed("Non-zero sample found at wrong sample offset.");
+                success = false;
+                break;
+            }
+        }
+    }
+
+    if (success) {
+        testPassed("All events rendered with sample-accuracy.");
+    } else {
+        testFailed("Events NOT rendered with sample-accuracy.");
+    }
+
+    finishJSTest();
+}
+
+function runTest() {
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+    
+    window.jsTestIsAsync = true;
+        
+    // Create offline audio context.
+    context = new webkitAudioContext(2, sampleRate * lengthInSeconds, sampleRate);
+    createImpulse();    
+
+    for (var i = 0; i < sampleOffsets.length; ++i) {
+        var timeInSeconds = sampleOffsets[i] * sampleRate;
+        playNote(timeInSeconds);
+    }
+    
+    context.oncomplete = checkSampleAccuracy;
+    context.startRendering();
+}
+
+runTest();
+successfullyParsed = true;
+
+</script>
+
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>