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

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/audionode-disconnect-audioparam.html

Issue 1488693006: Fix flaky WebAudio layout tests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Feedback (2) Created 5 years 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 unified diff | Download patch
OLDNEW
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 renderQuantum = 128;
16
17 var sampleRate = 44100;
18 var renderDuration = 0.5;
19 var disconnectTime = 0.5 * renderDuration;
20
15 var audit = Audit.createTaskRunner(); 21 var audit = Audit.createTaskRunner();
16 22
17 // The long render length (20 seconds) test 1 and 2 is to make sure the 23 // Calculate the index for disconnection.
18 // |onstatechange| event gets fired to start the source, which can take 24 function getDisconnectIndex(disconnectTime) {
19 // quite a bit of time. 25 var disconnectIndex = disconnectTime * sampleRate;
20 var testDuration = 20; 26 return disconnectIndex -= (disconnectIndex) % renderQuantum;
27 }
28
29 // Get the index of value change.
30 function getValueChangeIndex(array, targetValue) {
31 return array.findIndex(function (element, index) {
32 if (element === targetValue)
33 return true;
34 });
35 }
21 36
22 // Task 1: test disconnect(AudioParam) method. 37 // Task 1: test disconnect(AudioParam) method.
23 audit.defineTask('disconnect(AudioParam)', function (done) { 38 audit.defineTask('disconnect(AudioParam)', function (done) {
24 39
25 // Creates a buffer source with value [1] and then connect it to two gain 40 // 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 41 // 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 . 42 // (* 0.5) and then connected to two |.gain| AudioParams in each gain node .
43 //
28 // (1) bufferSource => gain1 => gain2 44 // (1) bufferSource => gain1 => gain2
29 // (2) bufferSource => half => gain1.gain 45 // (2) bufferSource => half => gain1.gain
30 // (3) half => gain2.gain 46 // (3) half => gain2.gain
47 //
31 // This graph should produce the output of 2.25 (= 1 * 1.5 * 1.5). After 48 // This graph should produce the output of 2.25 (= 1 * 1.5 * 1.5). After
32 // disconnecting (3), it should produce 1.5. 49 // disconnecting (3), it should produce 1.5.
33 var context = new OfflineAudioContext(1, 44100 * testDuration, 44100); 50 var context = new OfflineAudioContext(1, renderDuration * sampleRate, samp leRate);
34 var source = context.createBufferSource(); 51 var source = context.createBufferSource();
35 var buffer1ch = createTestingAudioBuffer(context, 1, 128); 52 var buffer1ch = createConstantBuffer(context, 1, 1);
36 var half = context.createGain(); 53 var half = context.createGain();
37 var gain1 = context.createGain(); 54 var gain1 = context.createGain();
38 var gain2 = context.createGain(); 55 var gain2 = context.createGain();
39 56
40 source.buffer = buffer1ch; 57 source.buffer = buffer1ch;
41 source.loop = true; 58 source.loop = true;
42 half.gain.value = 0.5; 59 half.gain.value = 0.5;
43 60
44 source.connect(gain1); 61 source.connect(gain1);
45 gain1.connect(gain2); 62 gain1.connect(gain2);
46 gain2.connect(context.destination); 63 gain2.connect(context.destination);
47 source.connect(half); 64 source.connect(half);
48 65
49 // Connecting |half| to both |gain1.gain| and |gain2.gain| amplifies the 66 // 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 67 // signal by 2.25 (= 1.5 * 1.5) because each gain node amplifies the signa l
51 // by 1.5 (= 1.0 + 0.5). 68 // by 1.5 (= 1.0 + 0.5).
52 half.connect(gain1.gain); 69 half.connect(gain1.gain);
53 half.connect(gain2.gain); 70 half.connect(gain2.gain);
54 71
55 source.start(); 72 source.start();
56 73
57 // Disconnects after the rendering starts. 74 // Schedule the disconnection at the half of render duration.
58 // 75 context.suspend(disconnectTime).then(function () {
59 // FIXME: Although this guarantees that the disconnection happens after 76 half.disconnect(gain2.gain);
60 // the rendering starts, still the actual disconnection might happen after 77 context.resume();
61 // oncomplete event fired. 78 });
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 79
72 context.startRendering().then(function (buffer) { 80 context.startRendering().then(function (buffer) {
73 81 var channelData = buffer.getChannelData(0);
74 // Note that this test depends on the disconnection below to happen 82 var disconnectIndex = getDisconnectIndex(disconnectTime);
75 // sometime during rendering. 83 var valueChangeIndex = getValueChangeIndex(channelData, 1.5);
76 84
77 // Expected values are: 1 * 1.5 * 1.5 -> 1 * 1.5 = [2.25, 1.5] 85 // Expected values are: 1 * 1.5 * 1.5 -> 1 * 1.5 = [2.25, 1.5]
78 Should('Channel #0', buffer.getChannelData(0)).containValues([2.25, 1.5] ); 86 Should('Channel #0', channelData).containValues([2.25, 1.5]);
79 87 Should('The index of value change', valueChangeIndex)
88 .beEqualTo(disconnectIndex);
89
80 }).then(done); 90 }).then(done);
81 }); 91 });
82 92
83 // Task 2: test disconnect(AudioParam, output) method. 93 // Task 2: test disconnect(AudioParam, output) method.
84 audit.defineTask('disconnect(AudioParam, output)', function (done) { 94 audit.defineTask('disconnect(AudioParam, output)', function (done) {
85 95
86 // Create a 2-channel buffer source with [1, 2] in each channel and 96 // 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 97 // 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. 98 // source half with a gain node and connect it to a 2-output splitter.
89 // Connect each output to 2 gain AudioParams respectively. 99 // Connect each output to 2 gain AudioParams respectively.
100 //
90 // (1) bufferSource => gain1 => gain2 101 // (1) bufferSource => gain1 => gain2
91 // (2) bufferSource => half => splitter(2) 102 // (2) bufferSource => half => splitter(2)
92 // (3) splitter#0 => gain1.gain 103 // (3) splitter#0 => gain1.gain
93 // (4) splitter#1 => gain2.gain 104 // (4) splitter#1 => gain2.gain
94 // This graph should produce 3 (= 1 * 1.5 * 2) and 6 (= 2 * 1.5 * 2) for 105 //
106 // 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. 107 // each channel. After disconnecting (4), it should output 1.5 and 3.
96 var context = new OfflineAudioContext(2, 44100 * testDuration, 44100); 108 var context = new OfflineAudioContext(2, renderDuration * sampleRate, samp leRate);
97 var source = context.createBufferSource(); 109 var source = context.createBufferSource();
98 var buffer2ch = createTestingAudioBuffer(context, 2, 128); 110 var buffer2ch = createConstantBuffer(context, 1, [1, 2]);
99 var splitter = context.createChannelSplitter(2); 111 var splitter = context.createChannelSplitter(2);
100 var half = context.createGain(); 112 var half = context.createGain();
101 var gain1 = context.createGain(); 113 var gain1 = context.createGain();
102 var gain2 = context.createGain(); 114 var gain2 = context.createGain();
103 115
104 source.buffer = buffer2ch; 116 source.buffer = buffer2ch;
105 source.loop = true; 117 source.loop = true;
106 half.gain.value = 0.5; 118 half.gain.value = 0.5;
107 119
108 source.connect(gain1); 120 source.connect(gain1);
109 gain1.connect(gain2); 121 gain1.connect(gain2);
110 gain2.connect(context.destination); 122 gain2.connect(context.destination);
111 123
112 // |source| originally is [1, 2] but it becomes [0.5, 1] after 0.5 gain. 124 // |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| 125 // Each splitter's output will be applied to |gain1.gain| and |gain2.gain|
114 // respectively in an additive fashion. 126 // respectively in an additive fashion.
115 source.connect(half); 127 source.connect(half);
116 half.connect(splitter); 128 half.connect(splitter);
117 129
118 // This amplifies the signal by 1.5. (= 1.0 + 0.5) 130 // This amplifies the signal by 1.5. (= 1.0 + 0.5)
119 splitter.connect(gain1.gain, 0); 131 splitter.connect(gain1.gain, 0);
120 132
121 // This amplifies the signal by 2. (= 1.0 + 1.0) 133 // This amplifies the signal by 2. (= 1.0 + 1.0)
122 splitter.connect(gain2.gain, 1); 134 splitter.connect(gain2.gain, 1);
123 135
124 source.start(); 136 source.start();
125 137
126 // Disconnect after the rendering starts. See the comment in the previous 138 // Schedule the disconnection at the half of render duration.
127 // test task. 139 context.suspend(disconnectTime).then(function () {
128 context.onstatechange = function () { 140 splitter.disconnect(gain2.gain, 1);
129 if (context.state === 'running') 141 context.resume();
130 splitter.disconnect(gain2.gain, 1); 142 });
131 };
132 143
133 context.startRendering().then(function (buffer) { 144 context.startRendering().then(function (buffer) {
145 var channelData0 = buffer.getChannelData(0);
146 var channelData1 = buffer.getChannelData(1);
134 147
148 var disconnectIndex = getDisconnectIndex(disconnectTime);
149 var valueChangeIndexCh0 = getValueChangeIndex(channelData0, 1.5);
150 var valueChangeIndexCh1 = getValueChangeIndex(channelData1, 3);
151
135 // Expected values are: 1 * 1.5 * 2 -> 1 * 1.5 = [3, 1.5] 152 // Expected values are: 1 * 1.5 * 2 -> 1 * 1.5 = [3, 1.5]
136 Should('Channel #0', buffer.getChannelData(0)).containValues([3, 1.5]); 153 Should('Channel #0', channelData0).containValues([3, 1.5]);
154 Should('The index of value change in channel #0', valueChangeIndexCh0)
155 .beEqualTo(disconnectIndex);
137 156
138 // Expected values are: 2 * 1.5 * 2 -> 2 * 1.5 = [6, 3] 157 // Expected values are: 2 * 1.5 * 2 -> 2 * 1.5 = [6, 3]
139 Should('Channel #1', buffer.getChannelData(1)).containValues([6, 3]); 158 Should('Channel #1', channelData1).containValues([6, 3]);
159 Should('The index of value change in channel #1', valueChangeIndexCh1)
160 .beEqualTo(disconnectIndex);
140 161
141 }).then(done); 162 }).then(done);
142 }); 163 });
143 164
144 // Task 3: exception checks. 165 // Task 3: exception checks.
145 audit.defineTask('exceptions', function (done) { 166 audit.defineTask('exceptions', function (done) {
146 var context = new AudioContext(); 167 var context = new AudioContext();
147 var gain1 = context.createGain(); 168 var gain1 = context.createGain();
148 var splitter = context.createChannelSplitter(2); 169 var splitter = context.createChannelSplitter(2);
149 var gain2 = context.createGain(); 170 var gain2 = context.createGain();
150 var gain3 = context.createGain(); 171 var gain3 = context.createGain();
151 172
152 // Connect a splitter to gain nodes and merger so we can test the possible 173 // Connect a splitter to gain nodes and merger so we can test the possible
153 // ways of disconnecting the nodes to verify that appropriate exceptions 174 // ways of disconnecting the nodes to verify that appropriate exceptions
154 // are thrown. 175 // are thrown.
155 gain1.connect(splitter); 176 gain1.connect(splitter);
156 splitter.connect(gain2.gain, 0); 177 splitter.connect(gain2.gain, 0);
157 splitter.connect(gain3.gain, 1); 178 splitter.connect(gain3.gain, 1);
158 gain2.connect(gain3); 179 gain2.connect(gain3);
159 gain3.connect(context.destination); 180 gain3.connect(context.destination);
160 181
161 // gain1 is not connected to gain3.gain. Exception should be thrown. 182 // gain1 is not connected to gain3.gain. Exception should be thrown.
162 Should('gain1.disconnect(gain3.gain)', function () { 183 Should('gain1.disconnect(gain3.gain)', function () {
163 gain1.disconnect(gain3.gain); 184 gain1.disconnect(gain3.gain);
(...skipping 22 matching lines...) Expand all
186 'disconnect(AudioParam, output)', 207 'disconnect(AudioParam, output)',
187 'exceptions', 208 'exceptions',
188 'finish' 209 'finish'
189 ); 210 );
190 211
191 successfullyParsed = true; 212 successfullyParsed = true;
192 </script> 213 </script>
193 </body> 214 </body>
194 215
195 </html> 216 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698