Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
| 2 <html> | 2 <html> |
| 3 | 3 |
| 4 <head> | 4 <head> |
| 5 <script src="../resources/js-test.js"></script> | 5 <script src="../resources/js-test.js"></script> |
| 6 <script src="resources/compatibility.js"></script> | 6 <script src="resources/compatibility.js"></script> |
| 7 <script src="resources/audio-testing.js"></script> | 7 <script src="resources/audio-testing.js"></script> |
| 8 </head> | 8 </head> |
| 9 | 9 |
| 10 <body> | 10 <body> |
| 11 <script> | 11 <script> |
| 12 description('Test disconnect() method on AudioParam destination.'); | 12 description('Test disconnect() method on AudioParam destination.'); |
| 13 window.jsTestIsAsync = true; | 13 window.jsTestIsAsync = true; |
| 14 | 14 |
| 15 var sampleRate = 44100; | |
| 16 var renderLength = 2 * sampleRate; | |
| 17 | |
| 15 var audit = Audit.createTaskRunner(); | 18 var audit = Audit.createTaskRunner(); |
| 16 | 19 |
| 17 // The long render length (20 seconds) test 1 and 2 is to make sure the | |
| 18 // |onstatechange| event gets fired to start the source, which can take | |
| 19 // quite a bit of time. | |
| 20 var testDuration = 20; | |
| 21 | |
| 22 // Task 1: test disconnect(AudioParam) method. | 20 // Task 1: test disconnect(AudioParam) method. |
| 23 audit.defineTask('disconnect(AudioParam)', function (done) { | 21 audit.defineTask('disconnect(AudioParam)', function (done) { |
| 24 | 22 |
| 25 // Creates a buffer source with value [1] and then connect it to two gain | 23 // Creates a buffer source with value [1] and then connect it to two gain |
| 26 // nodes in series. The output of the buffer source is lowered by half | 24 // nodes in series. The output of the buffer source is lowered by half |
| 27 // (* 0.5) and then connected to two |.gain| AudioParams in each gain node . | 25 // (* 0.5) and then connected to two |.gain| AudioParams in each gain node . |
| 26 // | |
| 28 // (1) bufferSource => gain1 => gain2 | 27 // (1) bufferSource => gain1 => gain2 |
| 29 // (2) bufferSource => half => gain1.gain | 28 // (2) bufferSource => half => gain1.gain |
| 30 // (3) half => gain2.gain | 29 // (3) half => gain2.gain |
| 30 // | |
| 31 // This graph should produce the output of 2.25 (= 1 * 1.5 * 1.5). After | 31 // This graph should produce the output of 2.25 (= 1 * 1.5 * 1.5). After |
| 32 // disconnecting (3), it should produce 1.5. | 32 // disconnecting (3), it should produce 1.5. |
| 33 var context = new OfflineAudioContext(1, 44100 * testDuration, 44100); | 33 var context = new OfflineAudioContext(1, renderLength, sampleRate); |
| 34 var source = context.createBufferSource(); | 34 var source = context.createBufferSource(); |
| 35 var buffer1ch = createTestingAudioBuffer(context, 1, 128); | 35 var buffer1ch = createTestingAudioBuffer(context, 1, 1); |
| 36 var half = context.createGain(); | 36 var half = context.createGain(); |
| 37 var gain1 = context.createGain(); | 37 var gain1 = context.createGain(); |
| 38 var gain2 = context.createGain(); | 38 var gain2 = context.createGain(); |
| 39 | 39 |
| 40 source.buffer = buffer1ch; | 40 source.buffer = buffer1ch; |
| 41 source.loop = true; | 41 source.loop = true; |
| 42 half.gain.value = 0.5; | 42 half.gain.value = 0.5; |
| 43 | 43 |
| 44 source.connect(gain1); | 44 source.connect(gain1); |
| 45 gain1.connect(gain2); | 45 gain1.connect(gain2); |
| 46 gain2.connect(context.destination); | 46 gain2.connect(context.destination); |
| 47 source.connect(half); | 47 source.connect(half); |
| 48 | 48 |
| 49 // Connecting |half| to both |gain1.gain| and |gain2.gain| amplifies the | 49 // Connecting |half| to both |gain1.gain| and |gain2.gain| amplifies the |
| 50 // signal by 2.25 (= 1.5 * 1.5) because each gain node amplifies the signa l | 50 // signal by 2.25 (= 1.5 * 1.5) because each gain node amplifies the signa l |
| 51 // by 1.5 (= 1.0 + 0.5). | 51 // by 1.5 (= 1.0 + 0.5). |
| 52 half.connect(gain1.gain); | 52 half.connect(gain1.gain); |
| 53 half.connect(gain2.gain); | 53 half.connect(gain2.gain); |
| 54 | 54 |
| 55 source.start(); | 55 source.start(); |
| 56 | 56 |
| 57 // Disconnects after the rendering starts. | 57 // Schedule the disconnection at 1.0 second. |
|
Raymond Toy
2015/12/01 22:14:37
Can we run the test for a much shorter duration?
hongchan
2015/12/02 18:58:31
Done.
| |
| 58 // | 58 context.suspend(1.0).then(function () { |
| 59 // FIXME: Although this guarantees that the disconnection happens after | 59 half.disconnect(gain2.gain); |
| 60 // the rendering starts, still the actual disconnection might happen after | 60 context.resume(); |
| 61 // oncomplete event fired. | 61 }); |
| 62 // | |
| 63 // The 10ms delay is 1/1000 of the total render length (10,000ms). Because | |
| 64 // OfflineAudioContext runs faster than real time, the disconnection might | |
| 65 // happen after the rendering finishes. Then lower the delay and increase | |
| 66 // the render length to avoid the test failure. | |
| 67 context.onstatechange = function () { | |
| 68 if (context.state === 'running') | |
| 69 half.disconnect(gain2.gain); | |
| 70 }; | |
| 71 | 62 |
| 72 context.startRendering().then(function (buffer) { | 63 context.startRendering().then(function (buffer) { |
| 73 | 64 |
| 74 // Note that this test depends on the disconnection below to happen | |
| 75 // sometime during rendering. | |
| 76 | |
| 77 // Expected values are: 1 * 1.5 * 1.5 -> 1 * 1.5 = [2.25, 1.5] | 65 // Expected values are: 1 * 1.5 * 1.5 -> 1 * 1.5 = [2.25, 1.5] |
|
Raymond Toy
2015/12/01 22:14:37
We should probably check the values change at exac
hongchan
2015/12/02 18:58:32
Done.
| |
| 78 Should('Channel #0', buffer.getChannelData(0)).containValues([2.25, 1.5] ); | 66 Should('Channel #0', buffer.getChannelData(0)).containValues([2.25, 1.5] ); |
| 79 | 67 |
| 80 }).then(done); | 68 }).then(done); |
| 81 }); | 69 }); |
| 82 | 70 |
| 83 // Task 2: test disconnect(AudioParam, output) method. | 71 // Task 2: test disconnect(AudioParam, output) method. |
| 84 audit.defineTask('disconnect(AudioParam, output)', function (done) { | 72 audit.defineTask('disconnect(AudioParam, output)', function (done) { |
| 85 | 73 |
| 86 // Create a 2-channel buffer source with [1, 2] in each channel and | 74 // Create a 2-channel buffer source with [1, 2] in each channel and |
| 87 // make a serial connection through gain1 and gain 2. The make the buffer | 75 // make a serial connection through gain1 and gain 2. The make the buffer |
| 88 // source half with a gain node and connect it to a 2-output splitter. | 76 // source half with a gain node and connect it to a 2-output splitter. |
| 89 // Connect each output to 2 gain AudioParams respectively. | 77 // Connect each output to 2 gain AudioParams respectively. |
| 78 // | |
| 90 // (1) bufferSource => gain1 => gain2 | 79 // (1) bufferSource => gain1 => gain2 |
| 91 // (2) bufferSource => half => splitter(2) | 80 // (2) bufferSource => half => splitter(2) |
| 92 // (3) splitter#0 => gain1.gain | 81 // (3) splitter#0 => gain1.gain |
| 93 // (4) splitter#1 => gain2.gain | 82 // (4) splitter#1 => gain2.gain |
| 83 // | |
| 94 // This graph should produce 3 (= 1 * 1.5 * 2) and 6 (= 2 * 1.5 * 2) for | 84 // This graph should produce 3 (= 1 * 1.5 * 2) and 6 (= 2 * 1.5 * 2) for |
| 95 // each channel. After disconnecting (4), it should output 1.5 and 3. | 85 // each channel. After disconnecting (4), it should output 1.5 and 3. |
| 96 var context = new OfflineAudioContext(2, 44100 * testDuration, 44100); | 86 var context = new OfflineAudioContext(2, renderLength, sampleRate); |
| 97 var source = context.createBufferSource(); | 87 var source = context.createBufferSource(); |
| 98 var buffer2ch = createTestingAudioBuffer(context, 2, 128); | 88 var buffer2ch = createTestingAudioBuffer(context, 2, 128); |
| 99 var splitter = context.createChannelSplitter(2); | 89 var splitter = context.createChannelSplitter(2); |
| 100 var half = context.createGain(); | 90 var half = context.createGain(); |
| 101 var gain1 = context.createGain(); | 91 var gain1 = context.createGain(); |
| 102 var gain2 = context.createGain(); | 92 var gain2 = context.createGain(); |
| 103 | 93 |
| 104 source.buffer = buffer2ch; | 94 source.buffer = buffer2ch; |
| 105 source.loop = true; | 95 source.loop = true; |
| 106 half.gain.value = 0.5; | 96 half.gain.value = 0.5; |
| 107 | 97 |
| 108 source.connect(gain1); | 98 source.connect(gain1); |
| 109 gain1.connect(gain2); | 99 gain1.connect(gain2); |
| 110 gain2.connect(context.destination); | 100 gain2.connect(context.destination); |
| 111 | 101 |
| 112 // |source| originally is [1, 2] but it becomes [0.5, 1] after 0.5 gain. | 102 // |source| originally is [1, 2] but it becomes [0.5, 1] after 0.5 gain. |
| 113 // Each splitter's output will be applied to |gain1.gain| and |gain2.gain| | 103 // Each splitter's output will be applied to |gain1.gain| and |gain2.gain| |
| 114 // respectively in an additive fashion. | 104 // respectively in an additive fashion. |
| 115 source.connect(half); | 105 source.connect(half); |
| 116 half.connect(splitter); | 106 half.connect(splitter); |
| 117 | 107 |
| 118 // This amplifies the signal by 1.5. (= 1.0 + 0.5) | 108 // This amplifies the signal by 1.5. (= 1.0 + 0.5) |
| 119 splitter.connect(gain1.gain, 0); | 109 splitter.connect(gain1.gain, 0); |
| 120 | 110 |
| 121 // This amplifies the signal by 2. (= 1.0 + 1.0) | 111 // This amplifies the signal by 2. (= 1.0 + 1.0) |
| 122 splitter.connect(gain2.gain, 1); | 112 splitter.connect(gain2.gain, 1); |
| 123 | 113 |
| 124 source.start(); | 114 source.start(); |
| 125 | 115 |
| 126 // Disconnect after the rendering starts. See the comment in the previous | 116 // Schedule the disconnect at 1 second. |
| 127 // test task. | 117 context.suspend(1.0).then(function () { |
| 128 context.onstatechange = function () { | 118 splitter.disconnect(gain2.gain, 1); |
| 129 if (context.state === 'running') | 119 context.resume(); |
| 130 splitter.disconnect(gain2.gain, 1); | 120 }); |
| 131 }; | |
| 132 | 121 |
| 133 context.startRendering().then(function (buffer) { | 122 context.startRendering().then(function (buffer) { |
| 134 | 123 |
| 135 // Expected values are: 1 * 1.5 * 2 -> 1 * 1.5 = [3, 1.5] | 124 // Expected values are: 1 * 1.5 * 2 -> 1 * 1.5 = [3, 1.5] |
| 136 Should('Channel #0', buffer.getChannelData(0)).containValues([3, 1.5]); | 125 Should('Channel #0', buffer.getChannelData(0)).containValues([3, 1.5]); |
| 137 | 126 |
| 138 // Expected values are: 2 * 1.5 * 2 -> 2 * 1.5 = [6, 3] | 127 // Expected values are: 2 * 1.5 * 2 -> 2 * 1.5 = [6, 3] |
| 139 Should('Channel #1', buffer.getChannelData(1)).containValues([6, 3]); | 128 Should('Channel #1', buffer.getChannelData(1)).containValues([6, 3]); |
| 140 | 129 |
| 141 }).then(done); | 130 }).then(done); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 186 'disconnect(AudioParam, output)', | 175 'disconnect(AudioParam, output)', |
| 187 'exceptions', | 176 'exceptions', |
| 188 'finish' | 177 'finish' |
| 189 ); | 178 ); |
| 190 | 179 |
| 191 successfullyParsed = true; | 180 successfullyParsed = true; |
| 192 </script> | 181 </script> |
| 193 </body> | 182 </body> |
| 194 | 183 |
| 195 </html> | 184 </html> |
| OLD | NEW |