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

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurveAtTime-interpolation.html

Issue 2895963003: Apply layout-test-tidy to LayoutTests/webaudio (Closed)
Patch Set: Created 3 years, 7 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 unified diff | Download patch
OLDNEW
1 <!doctype html> 1 <!DOCTYPE html>
2 <html> 2 <html>
3 <head> 3 <head>
4 <title>Test Interpolation for AudioParam.setValueCurveAtTime</title> 4 <title>
5 Test Interpolation for AudioParam.setValueCurveAtTime
6 </title>
5 <script src="../../resources/testharness.js"></script> 7 <script src="../../resources/testharness.js"></script>
6 <script src="../../resources/testharnessreport.js"></script> 8 <script src="../../resources/testharnessreport.js"></script>
7 <script src="../resources/audit-util.js"></script> 9 <script src="../resources/audit-util.js"></script>
8 <script src="../resources/audit.js"></script> 10 <script src="../resources/audit.js"></script>
9 <title>Test Interpolation for AudioParam.setValueCurveAtTime</title> 11 <title>
12 Test Interpolation for AudioParam.setValueCurveAtTime
13 </title>
10 </head> 14 </head>
15 <body>
16 <script id="layout-test-code">
17 // Play a constant signal through a gain node that is automated using
18 // setValueCurveAtTime with a 2-element curve. The output should be a
19 // linear change.
11 20
12 <body> 21 // Choose a sample rate that is a multiple of 128, the rendering quantum
13 <script> 22 // size. This makes the math work out to be nice numbers.
23 let sampleRate = 25600;
24 let testDurationSec = 1;
25 let testDurationFrames = testDurationSec * sampleRate;
14 26
15 // Play a constant signal through a gain node that is automated using setV alueCurveAtTime with 27 // Where the curve starts and its duration. This MUST be less than the
16 // a 2-element curve. The output should be a linear change. 28 // total rendering time.
29 let curveStartTime = 256 / sampleRate;
30 let curveDuration = 300 / sampleRate;
31 ;
32 let curveValue = 0.75;
17 33
18 // Choose a sample rate that is a multiple of 128, the rendering quantum s ize. This makes the 34 // At this time, the gain node goes to gain 1. This is used to make sure
19 // math work out to be nice numbers. 35 // the value curve is propagated correctly until the next event.
20 var sampleRate = 25600; 36 let fullGainTime = 0.75;
21 var testDurationSec = 1;
22 var testDurationFrames = testDurationSec * sampleRate;
23 37
24 // Where the curve starts and its duration. This MUST be less than the to tal rendering time. 38 // Thresholds use to determine if the test passes; these are
25 var curveStartTime = 256 / sampleRate; 39 // experimentally determined. The SNR between the actual and expected
26 var curveDuration = 300 / sampleRate;; 40 // result should be at least |snrThreshold|. The maximum difference
27 var curveValue = 0.75; 41 // betwen them should not exceed |maxErrorThreshold|.
42 let snrThreshold = 10000;
43 let maxErrorThreshold = 0;
28 44
29 // At this time, the gain node goes to gain 1. This is used to make sure the value curve is 45 let context;
30 // propagated correctly until the next event. 46 let actualResult;
31 var fullGainTime = 0.75; 47 let expectedResult;
32
33 // Thresholds use to determine if the test passes; these are experimentall y determined. The
34 // SNR between the actual and expected result should be at least |snrThres hold|. The maximum
35 // difference betwen them should not exceed |maxErrorThreshold|.
36 var snrThreshold = 10000;
37 var maxErrorThreshold = 0;
38 48
39 var context; 49 let audit = Audit.createTaskRunner();
40 var actualResult;
41 var expectedResult;
42 50
43 var audit = Audit.createTaskRunner(); 51 // Array of test configs. Each config must specify curveStartTime,
52 // curveDuration, curveLength, fullGainTime, maxErrorThreshold, and
53 // snrThreshold.
54 let testConfigs = [
55 {
56 // The main test
57 curveStartTime: 256 / sampleRate,
58 curveDuration: 300 / sampleRate,
59 curveLength: 2,
60 fullGainTime: 0.75,
61 maxErrorThreshold: 5.9605e-8,
62 snrThreshold: 171.206
63 },
64 {
65 // Increase the curve length
66 curveStartTime: 256 / sampleRate,
67 curveDuration: 300 / sampleRate,
68 curveLength: 3,
69 fullGainTime: 0.75,
70 maxErrorThreshold: 5.9605e-8,
71 snrThreshold: 171.206
72 },
73 {
74 // Increase the curve length
75 curveStartTime: 256 / sampleRate,
76 curveDuration: 300 / sampleRate,
77 curveLength: 16,
78 fullGainTime: 0.75,
79 maxErrorThreshold: 5.9605e-8,
80 snrThreshold: 170.892
81 },
82 {
83 // Increase the curve length
84 curveStartTime: 256 / sampleRate,
85 curveDuration: 300 / sampleRate,
86 curveLength: 100,
87 fullGainTime: 0.75,
88 maxErrorThreshold: 1.1921e-7,
89 snrThreshold: 168.712
90 },
91 {
92 // Corner case with duration less than a frame!
93 curveStartTime: 256 / sampleRate,
94 curveDuration: 0.25 / sampleRate,
95 curveLength: 2,
96 fullGainTime: 0.75,
97 maxErrorThreshold: 0,
98 snrThreshold: 10000
99 },
100 {
101 // Short duration test
102 curveStartTime: 256 / sampleRate,
103 curveDuration: 2 / sampleRate,
104 curveLength: 2,
105 fullGainTime: 0.75,
106 maxErrorThreshold: 0,
107 snrThreshold: 10000
108 },
109 {
110 // Short duration test with many points.
111 curveStartTime: 256 / sampleRate,
112 curveDuration: 2 / sampleRate,
113 curveLength: 8,
114 fullGainTime: 0.75,
115 maxErrorThreshold: 0,
116 snrThreshold: 10000
117 },
118 {
119 // Long duration, big curve
120 curveStartTime: 256 / sampleRate,
121 curveDuration: .5,
122 curveLength: 1000,
123 fullGainTime: 0.75,
124 maxErrorThreshold: 5.9605e-8,
125 snrThreshold: 152.784
126 }
127 ];
44 128
45 // Array of test configs. Each config must specify curveStartTime, curveD uration, 129 // Creates a function based on the test config that is suitable for use by
46 // curveLength, fullGainTime, maxErrorThreshold, and snrThreshold. 130 // defineTask().
47 var testConfigs = [{
48 // The main test
49 curveStartTime: 256 / sampleRate,
50 curveDuration: 300 / sampleRate,
51 curveLength: 2,
52 fullGainTime: 0.75,
53 maxErrorThreshold: 5.9605e-8,
54 snrThreshold: 171.206
55 }, {
56 // Increase the curve length
57 curveStartTime: 256 / sampleRate,
58 curveDuration: 300 / sampleRate,
59 curveLength: 3,
60 fullGainTime: 0.75,
61 maxErrorThreshold: 5.9605e-8,
62 snrThreshold: 171.206
63 }, {
64 // Increase the curve length
65 curveStartTime: 256 / sampleRate,
66 curveDuration: 300 / sampleRate,
67 curveLength: 16,
68 fullGainTime: 0.75,
69 maxErrorThreshold: 5.9605e-8,
70 snrThreshold: 170.892
71 }, {
72 // Increase the curve length
73 curveStartTime: 256 / sampleRate,
74 curveDuration: 300 / sampleRate,
75 curveLength: 100,
76 fullGainTime: 0.75,
77 maxErrorThreshold: 1.1921e-7,
78 snrThreshold: 168.712
79 }, {
80 // Corner case with duration less than a frame!
81 curveStartTime: 256 / sampleRate,
82 curveDuration: 0.25 / sampleRate,
83 curveLength: 2,
84 fullGainTime: 0.75,
85 maxErrorThreshold: 0,
86 snrThreshold: 10000
87 }, {
88 // Short duration test
89 curveStartTime: 256 / sampleRate,
90 curveDuration: 2 / sampleRate,
91 curveLength: 2,
92 fullGainTime: 0.75,
93 maxErrorThreshold: 0,
94 snrThreshold: 10000
95 }, {
96 // Short duration test with many points.
97 curveStartTime: 256 / sampleRate,
98 curveDuration: 2 / sampleRate,
99 curveLength: 8,
100 fullGainTime: 0.75,
101 maxErrorThreshold: 0,
102 snrThreshold: 10000
103 }, {
104 // Long duration, big curve
105 curveStartTime: 256 / sampleRate,
106 curveDuration: .5,
107 curveLength: 1000,
108 fullGainTime: 0.75,
109 maxErrorThreshold: 5.9605e-8,
110 snrThreshold: 152.784
111 }];
112
113 // Creates a function based on the test config that is suitable for use by defineTask().
114 function createTaskFunction(config) { 131 function createTaskFunction(config) {
115 return function (task, should) { 132 return function(task, should) {
116 runTest(should, config).then(() => task.done()); 133 runTest(should, config).then(() => task.done());
117 }; 134 };
118 } 135 }
119 136
120 // Define a task for each config, in the order listed in testConfigs. 137 // Define a task for each config, in the order listed in testConfigs.
121 for (var k = 0; k < testConfigs.length; ++k) { 138 for (let k = 0; k < testConfigs.length; ++k) {
122 var config = testConfigs[k]; 139 let config = testConfigs[k];
123 var name = k + ":curve=" + config.curveLength + ",duration=" + (config.c urveDuration * sampleRate); 140 let name = k + ':curve=' + config.curveLength +
141 ',duration=' + (config.curveDuration * sampleRate);
124 audit.define(name, createTaskFunction(config)); 142 audit.define(name, createTaskFunction(config));
125 } 143 }
126 144
127 // Simple test from crbug.com/441471. Makes sure the end points and the m iddle point are 145 // Simple test from crbug.com/441471. Makes sure the end points and the
128 // interpolated correctly. 146 // middle point are interpolated correctly.
129 audit.define("crbug-441471", (task, should) => { 147 audit.define('crbug-441471', (task, should) => {
130 // Any sample rate should work; we pick something small such that the ti me end points are on 148 // Any sample rate should work; we pick something small such that the
131 // a sampling point. 149 // time end points are on a sampling point.
132 var context = new OfflineAudioContext(1, 5000, 5000) 150 let context = new OfflineAudioContext(1, 5000, 5000)
133 151
134 // A constant source 152 // A constant source
135 var source = context.createBufferSource(); 153 let source = context.createBufferSource();
136 source.buffer = createConstantBuffer(context, 1, 1); 154 source.buffer = createConstantBuffer(context, 1, 1);
137 source.loop = true; 155 source.loop = true;
138 156
139 var gain = context.createGain(); 157 let gain = context.createGain();
140 158
141 var startTime = 0.7; 159 let startTime = 0.7;
142 var duration = 0.2; 160 let duration = 0.2;
143
144 // Create the curve. The interpolated result should be just a straight line from -1 to 1
145 // from time startTime to startTime + duration.
146 161
147 var c = new Float32Array(3); 162 // Create the curve. The interpolated result should be just a straight
163 // line from -1 to 1 from time startTime to startTime + duration.
164
165 let c = new Float32Array(3);
148 c[0] = -1; 166 c[0] = -1;
149 c[1] = 0; 167 c[1] = 0;
150 c[2] = 1; 168 c[2] = 1;
151 gain.gain.setValueCurveAtTime(c, startTime, duration); 169 gain.gain.setValueCurveAtTime(c, startTime, duration);
152 source.connect(gain); 170 source.connect(gain);
153 gain.connect(context.destination); 171 gain.connect(context.destination);
154 source.start(); 172 source.start();
155 173
156 context.startRendering().then(function (renderedBuffer) { 174 context.startRendering()
157 var data = renderedBuffer.getChannelData(0); 175 .then(function(renderedBuffer) {
158 var endTime = startTime + duration; 176 let data = renderedBuffer.getChannelData(0);
159 var midPoint = (startTime + endTime) / 2; 177 let endTime = startTime + duration;
178 let midPoint = (startTime + endTime) / 2;
160 179
161 should(data[timeToSampleFrame(startTime, context.sampleRate)], 180 should(
162 "Curve value at time " + startTime) 181 data[timeToSampleFrame(startTime, context.sampleRate)],
163 .beEqualTo(c[0]); 182 'Curve value at time ' + startTime)
164 // Due to round-off, the value at the midpoint is not exactly zero on arm64. See 183 .beEqualTo(c[0]);
165 // crbug.com/558563. The current value is experimentally determined. 184 // Due to round-off, the value at the midpoint is not exactly zero
166 should(data[timeToSampleFrame(midPoint, context.sampleRate)], 185 // on arm64. See crbug.com/558563. The current value is
167 "Curve value at time " + midPoint) 186 // experimentally determined.
168 .beCloseTo(0, {threshold: Math.pow(2, -51)}); 187 should(
169 should(data[timeToSampleFrame(endTime, context.sampleRate)], 188 data[timeToSampleFrame(midPoint, context.sampleRate)],
170 "Curve value at time " + endTime) 189 'Curve value at time ' + midPoint)
171 .beEqualTo(c[2]); 190 .beCloseTo(0, {threshold: Math.pow(2, -51)});
172 }).then(() => task.done()); 191 should(
192 data[timeToSampleFrame(endTime, context.sampleRate)],
193 'Curve value at time ' + endTime)
194 .beEqualTo(c[2]);
195 })
196 .then(() => task.done());
173 }); 197 });
174 198
175 function runTest(should, config) { 199 function runTest(should, config) {
176 context = new OfflineAudioContext(1, testDurationFrames, sampleRate); 200 context = new OfflineAudioContext(1, testDurationFrames, sampleRate);
177 201
178 // A constant audio source of value 1. 202 // A constant audio source of value 1.
179 var source = context.createBufferSource(); 203 let source = context.createBufferSource();
180 source.buffer = createConstantBuffer(context, 1, 1); 204 source.buffer = createConstantBuffer(context, 1, 1);
181 source.loop = true; 205 source.loop = true;
182 206
183 // The value curve for testing. Just to make things easy for testing, m ake the curve a 207 // The value curve for testing. Just to make things easy for testing,
184 // simple ramp up to curveValue. 208 // make the curve a simple ramp up to curveValue.
185 // TODO(rtoy): Maybe allow more complicated curves? 209 // TODO(rtoy): Maybe allow more complicated curves?
186 var curve = new Float32Array(config.curveLength); 210 let curve = new Float32Array(config.curveLength);
187 for (var k = 0; k < config.curveLength; ++k) { 211 for (let k = 0; k < config.curveLength; ++k) {
188 curve[k] = curveValue / (config.curveLength - 1) * k; 212 curve[k] = curveValue / (config.curveLength - 1) * k;
189 } 213 }
190 214
191 // A gain node that is to be automated using setValueCurveAtTime. 215 // A gain node that is to be automated using setValueCurveAtTime.
192 var gain = context.createGain(); 216 let gain = context.createGain();
193 gain.gain.value = 0; 217 gain.gain.value = 0;
194 gain.gain.setValueCurveAtTime(curve, config.curveStartTime, config.curve Duration); 218 gain.gain.setValueCurveAtTime(
219 curve, config.curveStartTime, config.curveDuration);
195 // This is to verify that setValueCurveAtTime ends appropriately. 220 // This is to verify that setValueCurveAtTime ends appropriately.
196 gain.gain.setValueAtTime(1, config.fullGainTime); 221 gain.gain.setValueAtTime(1, config.fullGainTime);
197 222
198 source.connect(gain); 223 source.connect(gain);
199 gain.connect(context.destination); 224 gain.connect(context.destination);
200 source.start(); 225 source.start();
201 226
202 // Some consistency checks on the test parameters 227 // Some consistency checks on the test parameters
203 let prefix = "Length " + config.curveLength + ", duration " + config.cur veDuration; 228 let prefix = 'Length ' + config.curveLength + ', duration ' +
204 should(config.curveStartTime + config.curveDuration, 229 config.curveDuration;
205 prefix + ": Check: Curve end time") 230 should(
206 .beLessThanOrEqualTo(testDurationSec); 231 config.curveStartTime + config.curveDuration,
207 should(config.fullGainTime, prefix + ": Check: Full gain start time") 232 prefix + ': Check: Curve end time')
208 .beLessThanOrEqualTo(testDurationSec); 233 .beLessThanOrEqualTo(testDurationSec);
209 should(config.fullGainTime, 234 should(config.fullGainTime, prefix + ': Check: Full gain start time')
210 prefix + ": Check: Full gain start time") 235 .beLessThanOrEqualTo(testDurationSec);
211 .beGreaterThanOrEqualTo(config.curveStartTime + config.curveDuration); 236 should(config.fullGainTime, prefix + ': Check: Full gain start time')
237 .beGreaterThanOrEqualTo(
238 config.curveStartTime + config.curveDuration);
212 239
213 // Rock and roll! 240 // Rock and roll!
214 return context.startRendering().then(checkResult(should, config)); 241 return context.startRendering().then(checkResult(should, config));
215 } 242 }
216 243
217 // Return a function to check that the rendered result matches the expecte d result. 244 // Return a function to check that the rendered result matches the
245 // expected result.
218 function checkResult(should, config) { 246 function checkResult(should, config) {
219 return function (renderedBuffer) { 247 return function(renderedBuffer) {
220 var success = true; 248 let success = true;
221 249
222 actualResult = renderedBuffer.getChannelData(0); 250 actualResult = renderedBuffer.getChannelData(0);
223 expectedResult = computeExpectedResult(config); 251 expectedResult = computeExpectedResult(config);
224 252
225 // Compute the SNR and max absolute difference between the actual and expected result. 253 // Compute the SNR and max absolute difference between the actual and
226 var SNR = 10*Math.log10(computeSNR(actualResult, expectedResult)); 254 // expected result.
227 var maxDiff = -1; 255 let SNR = 10 * Math.log10(computeSNR(actualResult, expectedResult));
228 var posn = -1; 256 let maxDiff = -1;
257 let posn = -1;
229 258
230 for (var k = 0; k < actualResult.length; ++k) { 259 for (let k = 0; k < actualResult.length; ++k) {
231 var diff = Math.abs(actualResult[k] - expectedResult[k]); 260 let diff = Math.abs(actualResult[k] - expectedResult[k]);
232 if (maxDiff < diff) { 261 if (maxDiff < diff) {
233 maxDiff = diff; 262 maxDiff = diff;
234 posn = k; 263 posn = k;
235 } 264 }
236 } 265 }
237 266
238 let prefix = "Curve length " + config.curveLength + ", duration " + co nfig.curveDuration; 267 let prefix = 'Curve length ' + config.curveLength + ', duration ' +
239 should(SNR, prefix + ": SNR") 268 config.curveDuration;
240 .beGreaterThanOrEqualTo(config.snrThreshold); 269 should(SNR, prefix + ': SNR')
270 .beGreaterThanOrEqualTo(config.snrThreshold);
241 271
242 should(maxDiff, prefix + ": Max difference") 272 should(maxDiff, prefix + ': Max difference')
243 .beLessThanOrEqualTo(config.maxErrorThreshold); 273 .beLessThanOrEqualTo(config.maxErrorThreshold);
244 } 274 }
245 } 275 }
246 276
247 // Compute the expected result based on the config settings. 277 // Compute the expected result based on the config settings.
248 function computeExpectedResult(config) { 278 function computeExpectedResult(config) {
249 // The automation curve starts at |curveStartTime| and has duration |cu rveDuration|. So, 279 // The automation curve starts at |curveStartTime| and has duration
250 // the output should be zero until curveStartTime, linearly ramp up fro m there to 280 // |curveDuration|. So, the output should be zero until curveStartTime,
251 // |curveValue|, and then be constant 1 from then to the end of the buf fer. 281 // linearly ramp up from there to |curveValue|, and then be constant 1
282 // from then to the end of the buffer.
252 283
253 var expected = new Float32Array(testDurationFrames); 284 let expected = new Float32Array(testDurationFrames);
254 285
255 var curveStartFrame = config.curveStartTime * sampleRate; 286 let curveStartFrame = config.curveStartTime * sampleRate;
256 var curveEndFrame = (config.curveStartTime + config.curveDuration) * sa mpleRate; 287 let curveEndFrame =
257 var fullGainFrame = config.fullGainTime * sampleRate; 288 (config.curveStartTime + config.curveDuration) * sampleRate;
289 let fullGainFrame = config.fullGainTime * sampleRate;
258 290
259 var k; 291 let k;
260 292
261 // Zero out the start. 293 // Zero out the start.
262 for (k = 0; k < curveStartFrame; ++k) 294 for (k = 0; k < curveStartFrame; ++k)
263 expected[k] = 0; 295 expected[k] = 0;
264 296
265 // Linearly ramp now. This assumes that the actual curve used is a lin ear ramp, even if 297 // Linearly ramp now. This assumes that the actual curve used is a
266 // there are many curve points. 298 // linear ramp, even if there are many curve points.
267 var stepSize = curveValue / (config.curveDuration * sampleRate); 299 let stepSize = curveValue / (config.curveDuration * sampleRate);
268 for (; k < curveEndFrame; ++k) 300 for (; k < curveEndFrame; ++k)
269 expected[k] = stepSize * (k - curveStartFrame); 301 expected[k] = stepSize * (k - curveStartFrame);
270 302
271 // Hold it constant until the next event 303 // Hold it constant until the next event
272 for (; k < fullGainFrame; ++k) 304 for (; k < fullGainFrame; ++k)
273 expected[k] = curveValue; 305 expected[k] = curveValue;
274 306
275 // Amplitude is one for the rest of the test. 307 // Amplitude is one for the rest of the test.
276 for (; k < testDurationFrames; ++k) 308 for (; k < testDurationFrames; ++k)
277 expected[k] = 1; 309 expected[k] = 1;
278 310
279 return expected; 311 return expected;
280 } 312 }
281 313
282 audit.run(); 314 audit.run();
283 </script> 315 </script>
284 </body> 316 </body>
285 </html> 317 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698