Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Unified Diff: LayoutTests/webaudio/audionode-disconnect-audioparam.html

Issue 886173004: Fix AudioNode.disconnect() to support selective disconnection. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Conflict solved. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: LayoutTests/webaudio/audionode-disconnect-audioparam.html
diff --git a/LayoutTests/webaudio/audionode-disconnect-audioparam.html b/LayoutTests/webaudio/audionode-disconnect-audioparam.html
new file mode 100644
index 0000000000000000000000000000000000000000..b9a31aec4fc61fff4fb0d03b37b89dae9e13d707
--- /dev/null
+++ b/LayoutTests/webaudio/audionode-disconnect-audioparam.html
@@ -0,0 +1,237 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <script src="../resources/js-test.js"></script>
+ <script src="resources/compatibility.js"></script>
+ <script src="resources/audio-testing.js"></script>
+</head>
+
+<body>
+ <script>
+ description('Test disconnect() method on AudioParam destination.');
+ window.jsTestIsAsync = true;
+
+ var audit = Audit.createTaskRunner();
+
+ // Task 1: test disconnect(AudioParam) method.
+ audit.defineTask('disconnect(AudioParam)', function (done) {
+
+ // Creates a buffer source with value [1] and then connect it to two gain
+ // nodes in series. The output of the buffer source is lowered by half
+ // (* 0.5) and then connected to two |.gain| AudioParams in each gain node.
+ // (1) bufferSource => gain1 => gain2
+ // (2) bufferSource => half => gain1.gain
+ // (3) half => gain2.gain
+ // This graph should produce the output of 2.25 (= 1 * 1.5 * 1.5). After
+ // disconnecting (3), it should produce 1.5.
+ var context = new OfflineAudioContext(1, 44100 * 10, 44100);
+ var source = context.createBufferSource();
+ var buffer1ch = createTestingAudioBuffer(context, 1, 128);
+ var half = context.createGain();
+ var gain1 = context.createGain();
+ var gain2 = context.createGain();
+
+ source.buffer = buffer1ch;
+ source.loop = true;
+ half.gain.value = 0.5;
+
+ source.connect(gain1);
+ gain1.connect(gain2);
+ gain2.connect(context.destination);
+ source.connect(half);
+
+ // Connecting |half| to both |gain1.gain| and |gain2.gain| amplifies the
+ // signal by 2.25 (= 1.5 * 1.5) because each gain node amplifies the signal
+ // by 1.5 (= 1.0 + 0.5).
+ half.connect(gain1.gain);
+ half.connect(gain2.gain);
+
+ source.start();
+
+ // Disconnects after the rendering starts.
+ //
+ // FIXME: Although this guarantees that the disconnection happens after
+ // the rendering starts, still the actual disconnection might happen after
+ // oncomplete event fired.
+ //
+ // The 10ms delay is 1/1000 of the total render length (10,000ms). Because
+ // OfflineAudioContext runs faster than real time, the disconnection might
+ // happen after the rendering finishes. Then lower the delay and increase
+ // the render length to avoid the test failure.
+ var stateAlreadyChanged = false;
+ context.onstatechange = function () {
+ if (!stateAlreadyChanged) {
+ half.disconnect(gain2.gain);
+ stateAlreadyChanged = true;
+ }
+ };
+
+ context.startRendering().then(function (buffer) {
+
+ // Note that this test depends on the disconnection below to happen
+ // sometime during rendering.
+ var channelData = buffer.getChannelData(0);
+ var expectedValues = [2.25, 1.5]; // 1 * 1.5 * 1.5 -> 1 * 1.5
+ var passed = compareElements(expectedValues, channelData);
+
+ if (passed) {
+ testPassed('The rendered buffer matches expected values: [' +
+ expectedValues.toString() + ']'
+ );
+ } else {
+ testFailed('The rendered buffer does not match expected values.');
+ }
+ }).then(done);
+ });
+
+ // Task 2: test disconnect(AudioParam, output) method.
+ audit.defineTask('disconnect(AudioParam, output)', function (done) {
+
+ // Create a 2-channel buffer source with [1, 2] in each channel and
+ // make a serial connection through gain1 and gain 2. The make the buffer
+ // source half with a gain node and connect it to a 2-output splitter.
+ // Connect each output to 2 gain AudioParams respectively.
+ // (1) bufferSource => gain1 => gain2
+ // (2) bufferSource => half => splitter(2)
+ // (3) splitter#0 => gain1.gain
+ // (4) splitter#1 => gain2.gain
+ // This graph should produce 3 (= 1 * 1.5 * 2) and 6 (= 2 * 1.5 * 2) for
+ // each channel. After disconnecting (4), it should output 1.5 and 3.
+ var context = new OfflineAudioContext(2, 44100 * 10, 44100);
+ var source = context.createBufferSource();
+ var buffer2ch = createTestingAudioBuffer(context, 2, 128);
+ var splitter = context.createChannelSplitter(2);
+ var half = context.createGain();
+ var gain1 = context.createGain();
+ var gain2 = context.createGain();
+
+ source.buffer = buffer2ch;
+ source.loop = true;
+ half.gain.value = 0.5;
+
+ source.connect(gain1);
+ gain1.connect(gain2);
+ gain2.connect(context.destination);
+
+ // |source| originally is [1, 2] but it becomes [0.5, 1] after 0.5 gain.
+ // Each splitter's output will be applied to |gain1.gain| and |gain2.gain|
+ // respectively in an additive fashion.
+ source.connect(half);
+ half.connect(splitter);
+
+ // This amplifies the signal by 1.5. (= 1.0 + 0.5)
+ splitter.connect(gain1.gain, 0);
+
+ // This amplifies the signal by 2. (= 1.0 + 1.0)
+ splitter.connect(gain2.gain, 1);
+
+ source.start();
+
+ // Disconnect after the rendering starts. See the comment in the previous
+ // test task.
+ var stateAlreadyChanged = false;
+ context.onstatechange = function () {
+ if (!stateAlreadyChanged) {
+ splitter.disconnect(gain2.gain, 1);
+ stateAlreadyChanged = true;
+ }
+ };
+
+ context.startRendering().then(function (buffer) {
+ var channelData0 = buffer.getChannelData(0);
+ var channelData1 = buffer.getChannelData(1);
+ var expectedValuesCh0 = [3, 1.5]; // 1 * 1.5 * 2 -> 1 * 1.5
+ var expectedValuesCh1 = [6, 3]; // 2 * 1.5 * 2 -> 2 * 1.5
+ var passedCh0 = compareElements(expectedValuesCh0, channelData0);
+ var passedCh1 = compareElements(expectedValuesCh1, channelData1);
+
+ if (passedCh0 && passedCh1) {
+ testPassed('The rendered buffer matches expected values: Ch0 = [' +
+ expectedValuesCh0.toString() + '] Ch1 = [' + expectedValuesCh1.toString() +
+ ']'
+ );
+ } else {
+ testFailed('Expected values do not match.');
+ }
+ }).then(done);
+ });
+
+ // Task 3: exception checks.
+ audit.defineTask('exceptions', function (done) {
+ var context = new AudioContext();
+ var gain1 = context.createGain();
+ var splitter = context.createChannelSplitter(2);
+ var gain2 = context.createGain();
+ var gain3 = context.createGain();
+
+ // Connect a splitter to gain nodes and merger so we can test the possible
+ // ways of disconnecting the nodes to verify that appropriate exceptions
+ // are thrown.
+ gain1.connect(splitter);
+ splitter.connect(gain2.gain, 0);
+ splitter.connect(gain3.gain, 1);
+ gain2.connect(gain3);
+ gain3.connect(context.destination);
+
+ // gain1 is not connected to gain3.gain. Exception should be thrown.
+ Should.throwWithType('InvalidAccessError', function () {
+ gain1.disconnect(gain3.gain);
+ });
+
+ // When the output index is good but the destination is invalid.
+ Should.throwWithType('InvalidAccessError', function () {
+ splitter.disconnect(gain1.gain, 1);
+ });
+
+ // When both arguments are wrong, throw IndexSizeError first.
+ Should.throwWithType('IndexSizeError', function () {
+ splitter.disconnect(gain1.gain, 2);
+ });
+
+ done();
+ });
+
+ audit.defineTask('finish', function (done) {
+ finishJSTest();
+ done();
+ });
+
+ audit.runTasks(
+ 'disconnect(AudioParam)',
+ 'disconnect(AudioParam, output)',
+ 'exceptions',
+ 'finish'
+ );
+
+ // The value-wise comparison of two arrays with different length. It
+ // checks the value of element regardless of its occurrence. For example,
+ // (1) [2.25, 2.25, 2.25, 1.5, 1.5, 1.5] === [2.25, 1.5]
+ // (2) [2.25, 2.25, 1.5, 1.5, 0, 7, 7, 7, 9, 1] !== [2.25, 1.5]
+ // (3) [-1, 2, 3, 2.25, 2.25, 1.5, 1.5] !== [2.25, 1.5]
+ // (4) [3, 3, 3, 7, 7, 7] !== [2.25, 1.5]
+ function compareElements(expected, actual) {
+ var indexExpected = 0, indexActual = 0;
+ while (indexExpected < expected.length && indexActual < actual.length) {
+ if (expected[indexExpected] === actual[indexActual]) {
+ indexActual++;
+ } else {
+ indexExpected++;
+ }
+ }
+
+ if (indexExpected < expected.length - 1 || indexActual < actual.length - 1) {
+ // This is for the debugging purpose. Printed out only when failed.
+ console.log('The value ' + actual[indexActual] + ' at index ' +
+ indexActual + ' was not found in expected values');
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ successfullyParsed = true;
+ </script>
+</body>
+
+</html>
« no previous file with comments | « LayoutTests/webaudio/audionode-disconnect.html ('k') | LayoutTests/webaudio/audionode-disconnect-audioparam-expected.txt » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698