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

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

Powered by Google App Engine
This is Rietveld 408576698