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-nominal-range.html

Issue 2581463002: Refactor WebAudio test directory (Closed)
Patch Set: Use correct path for wav result files Created 3 years, 12 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
(Empty)
1 <!doctype html>
2 <html>
3 <head>
4 <script src="../resources/js-test.js"></script>
5 <script src="resources/compatibility.js"></script>
6 <script src="resources/audit-util.js"></script>
7 <script src="resources/audio-testing.js"></script>
8 <title>Test AudioParam Nominal Range Values</title>
9 </head>
10
11 <body>
12 <script>
13 description("Test AudioParam Nominal Range Values.");
14 window.jsTestIsAsync = true;
15
16 // Some arbitrary sample rate for the offline context.
17 var sampleRate = 48000;
18
19 // The actual offline context
20 var context;
21
22 // The set of all methods that we've tested for verifying that we tested a ll of the necessary
23 // objects.
24 var testedMethods = new Set();
25
26 // The most positive single float value (the value just before infinity). Be careful when
27 // changing this value! Javascript only uses double floats, so the value here should be the
28 // max single-float value, converted directly to a double-float value. Th is also depends on
29 // Javascript reading this value and producing the desired double-float va lue correctly.
30 var mostPositiveFloat = 3.4028234663852886e38;
31
32 var audit = Audit.createTaskRunner();
33
34 // Array describing the tests that should be run.
35 var testConfigs = [{
36 // The name of the method to create the particular node to be tested.
37 creator: "createGain",
38
39 // Any args to pass to the creator function.
40 args: [],
41
42 // The min/max limits for each AudioParam of the node. This is a dictio nary whose keys are
43 // the names of each AudioParam in the node. Don't define this if the n ode doesn't have any
44 // AudioParam attributes.
45 limits: {
46 gain: {
47 // The expected min and max values for this AudioParam.
48 minValue: -mostPositiveFloat,
49 maxValue: mostPositiveFloat
50 }
51 }
52 }, {
53 creator: "createDelay",
54 // Just specify a non-default value for the maximum delay so we can make sure the limits are
55 // set correctly.
56 args: [1.5],
57 limits: {
58 delayTime: {
59 minValue: 0,
60 maxValue: 1.5
61 }
62 }
63 }, {
64 creator: "createBufferSource",
65 args: [],
66 limits: {
67 playbackRate: {
68 minValue: -mostPositiveFloat,
69 maxValue: mostPositiveFloat
70 },
71 detune: {
72 minValue: -mostPositiveFloat,
73 maxValue: mostPositiveFloat
74 }
75 }
76 }, {
77 creator: "createStereoPanner",
78 args: [],
79 limits: {
80 pan: {
81 minValue: -1,
82 maxValue: 1
83 }
84 }
85 }, {
86 creator: "createDynamicsCompressor",
87 args: [],
88 // Do not set limits for reduction; it's currently an AudioParam but sh ould be a float.
89 // So let the test fail for reduction. When reduction is changed, this test will then
90 // correctly pass.
91 limits: {
92 threshold: {
93 minValue: -100,
94 maxValue: 0
95 },
96 knee: {
97 minValue: 0,
98 maxValue: 40
99 },
100 ratio: {
101 minValue: 1,
102 maxValue: 20
103 },
104 attack: {
105 minValue: 0,
106 maxValue: 1
107 },
108 release: {
109 minValue: 0,
110 maxValue: 1
111 }
112 }
113 },
114 {
115 creator: "createBiquadFilter",
116 args: [],
117 limits: {
118 gain: {
119 minValue: -mostPositiveFloat,
120 maxValue: mostPositiveFloat
121 },
122 Q: {
123 minValue: -mostPositiveFloat,
124 maxValue: mostPositiveFloat
125 },
126 frequency: {
127 minValue: 0,
128 maxValue: sampleRate / 2
129 },
130 detune: {
131 minValue: -mostPositiveFloat,
132 maxValue: mostPositiveFloat
133 }
134 }
135 }, {
136 creator: "createOscillator",
137 args: [],
138 limits: {
139 frequency: {
140 minValue: -sampleRate / 2,
141 maxValue: sampleRate / 2
142 },
143 detune: {
144 minValue: -mostPositiveFloat,
145 maxValue: mostPositiveFloat
146 }
147 }
148 }, {
149 creator: "createPanner",
150 args: [],
151 limits : {
152 positionX: {
153 minValue: -mostPositiveFloat,
154 maxValue: mostPositiveFloat,
155 },
156 positionY: {
157 minValue: -mostPositiveFloat,
158 maxValue: mostPositiveFloat,
159 },
160 positionZ: {
161 minValue: -mostPositiveFloat,
162 maxValue: mostPositiveFloat,
163 },
164 orientationX: {
165 minValue: -mostPositiveFloat,
166 maxValue: mostPositiveFloat,
167 },
168 orientationY: {
169 minValue: -mostPositiveFloat,
170 maxValue: mostPositiveFloat,
171 },
172 orientationZ: {
173 minValue: -mostPositiveFloat,
174 maxValue: mostPositiveFloat,
175 }
176 },
177 }, {
178 creator: "createConstantSource",
179 args: [],
180 limits: {
181 offset: {
182 minValue: -mostPositiveFloat,
183 maxValue: mostPositiveFloat
184 }
185 }
186 },
187 // These nodes don't have AudioParams, but we want to test them anyway. A ny arguments for the
188 // constructor are pretty much arbitrary; they just need to be valid.
189 {
190 creator: "createBuffer",
191 args: [1, 1, sampleRate],
192 }, {
193 creator: "createIIRFilter",
194 args: [[1,2],[3,4]]
195 }, {
196 creator: "createWaveShaper",
197 args: [],
198 }, {
199 creator: "createConvolver",
200 args: [],
201 }, {
202 creator: "createAnalyser",
203 args: [],
204 }, {
205 creator: "createScriptProcessor",
206 args: [0],
207 }, {
208 creator: "createPeriodicWave",
209 args: [Float32Array.from([0, 0]), Float32Array.from([1, 0])],
210 }, {
211 creator: "createChannelSplitter",
212 args: [],
213 }, {
214 creator: "createChannelMerger",
215 args: [],
216 }, {
217 creator: "createMediaElementSource",
218 args: [new Audio()]
219 },{
220 creator: "createMediaStreamDestination",
221 args: []
222 }
223 // Can't currently test MediaStreamSource because we're using an offline
224 // context.
225 ];
226
227 // Create the context so we can use it in the following test.
228 audit.defineTask("initialize", function (done) {
229 // Just any context so that we can create the nodes.
230 context = new OfflineAudioContext(1, 1, sampleRate);
231 done();
232 });
233
234 // Create a task for each entry in testConfigs
235 for (var test in testConfigs) {
236 var config = testConfigs[test]
237 audit.defineTask(config.creator, (function (c) {
238 return function (done) {
239 var node = context[c.creator](...c.args);
240 testLimits(c.creator, node, c.limits);
241 done();
242 };
243 })(config));
244 }
245
246 // Test the AudioListener params that were added for the automated Panner
247 audit.defineTask("AudioListener", function (done) {
248 testLimits("", context.listener, {
249 positionX: {
250 minValue: -mostPositiveFloat,
251 maxValue: mostPositiveFloat,
252 },
253 positionY: {
254 minValue: -mostPositiveFloat,
255 maxValue: mostPositiveFloat,
256 },
257 positionZ: {
258 minValue: -mostPositiveFloat,
259 maxValue: mostPositiveFloat,
260 },
261 forwardX: {
262 minValue: -mostPositiveFloat,
263 maxValue: mostPositiveFloat,
264 },
265 forwardY: {
266 minValue: -mostPositiveFloat,
267 maxValue: mostPositiveFloat,
268 },
269 forwardZ: {
270 minValue: -mostPositiveFloat,
271 maxValue: mostPositiveFloat,
272 },
273 upX: {
274 minValue: -mostPositiveFloat,
275 maxValue: mostPositiveFloat,
276 },
277 upY: {
278 minValue: -mostPositiveFloat,
279 maxValue: mostPositiveFloat,
280 },
281 upZ: {
282 minValue: -mostPositiveFloat,
283 maxValue: mostPositiveFloat,
284 }
285 });
286 done();
287 });
288
289 // Verify that we have tested all the create methods available on the cont ext.
290 audit.defineTask("verifyTests", function (done) {
291 var allNodes = new Set();
292 // Create the set of all "create" methods from the context.
293 for (var method in context) {
294 if (typeof context[method] === "function" && method.substring(0, 6) == = "create") {
295 allNodes.add(method);
296 }
297 }
298
299 // Compute the difference between the set of all create methods on the c ontext and the set
300 // of tests that we've run.
301 var diff = new Set([...allNodes].filter(x => !testedMethods.has(x)));
302
303 // Can't currently test a MediaStreamSourceNode, so remove it from the d iff set.
304 diff.delete("createMediaStreamSource");
305
306 // It's a test failure if we didn't test all of the create methods in th e context (except
307 // createMediaStreamSource, of course).
308 if (diff.size) {
309 var output = [];
310 for (let item of diff)
311 output.push(" " + item.substring(6));
312 testFailed("These nodes were not tested:" + output + "\n");
313 } else {
314 testPassed("All nodes were tested.\n");
315 }
316
317 done();
318 });
319
320 // Simple test of a few automation methods to verify we get warnings.
321 audit.defineTask("automation", function (done) {
322 // Just use a DelayNode for testing because the audio param has finite l imits.
323 var d = context.createDelay();
324
325 // The console output should have the warnings that we're interested in.
326 d.delayTime.setValueAtTime(-1, 0);
327 d.delayTime.linearRampToValueAtTime(2, 1);
328 d.delayTime.exponentialRampToValueAtTime(3, 2);
329 d.delayTime.setTargetAtTime(-1, 3, .1);
330 d.delayTime.setValueCurveAtTime(Float32Array.from([.1, .2, 1.5, -1]), 4, .1);
331 done();
332 });
333
334 // All done!
335 audit.defineTask("finish", function (done) {
336 finishJSTest();
337 done();
338 });
339
340 audit.runTasks();
341
342 // Is |object| an AudioParam? We determine this by checking the construct or name.
343 function isAudioParam(object) {
344 return object && object.constructor.name === "AudioParam";
345 }
346
347 // Does |limitOptions| exist and does it have valid values for the expecte d min and max
348 // values?
349 function hasValidLimits(limitOptions) {
350 return limitOptions && (typeof limitOptions.minValue === "number") && (t ypeof limitOptions.maxValue === "number");
351 }
352
353 // Check the min and max values for the AudioParam attribute named |paramN ame| for the |node|.
354 // The expected limits is given by the dictionary |limits|. If some test fails, add the name
355 // of the failed
356 function validateAudioParamLimits(node, paramName, limits) {
357 var nodeName = node.constructor.name;
358 var parameter = node[paramName];
359 var prefix = nodeName + "." + paramName;
360
361 var success = true;
362 if (hasValidLimits(limits[paramName])) {
363 // Verify that the min and max values for the parameter are correct.
364 var isCorrect = Should(prefix + ".minValue", parameter.minValue)
365 .beEqualTo(limits[paramName].minValue);
366 isCorrect = Should(prefix + ".maxValue", parameter.maxValue)
367 .beEqualTo(limits[paramName].maxValue) && isCorrect;
368
369 // Verify that the min and max attributes are read-only
370 parameter.minValue = Math.PI;
371 var isReadOnly;
372 isReadOnly = Should(prefix + ".minValue = Math.PI", parameter.minValue )
373 .notBeEqualTo(Math.PI);
374 if (isReadOnly)
375 testPassed(prefix + ".minValue is read-only.");
376 else
377 testFailed(prefix + ".minValue should be read-only but was changed." );
378 isCorrect = isReadOnly && isCorrect;
379
380 parameter.maxValue = Math.PI;
381 isReadOnly = Should(prefix + ".maxValue = Math.PI", parameter.maxValue )
382 .notBeEqualTo(Math.PI);
383 if (isReadOnly)
384 testPassed(prefix + ".maxValue is read-only.");
385 else
386 testFailed(prefix + ".maxValue should be read-only but was changed." );
387 isCorrect = isReadOnly && isCorrect;
388
389 // Now try to set the parameter outside the nominal range.
390 var newValue = 2 * limits[paramName].minValue - 1;
391
392 var isClipped = true;
393 var clippingTested = false;
394 // If the new value is beyond float the largest single-precision float , skip the test
395 // because Chrome throws an error.
396 if (newValue >= -mostPositiveFloat) {
397 parameter.value = newValue;
398 clippingTested = true;
399 isClipped = Should("Set " + prefix + ".value = " + newValue, paramet er.value)
400 .beEqualTo(parameter.minValue) && isClipped;
401 }
402
403 newValue = 2 * limits[paramName].maxValue + 1;
404
405 if (newValue <= mostPositiveFloat) {
406 parameter.value = newValue;
407 clippingTested = true;
408 isClipped = Should("Set " + prefix + ".value = " + newValue, paramet er.value)
409 .beEqualTo(parameter.maxValue) && isClipped;
410
411 }
412
413 if (clippingTested) {
414 if (isClipped)
415 testPassed(prefix + " was correctly clipped to lie within the nomi nal range.")
416 else
417 testPassed(prefix + " was not correctly clipped to lie within the nominal range.")
418 }
419
420 isCorrect = isCorrect && isClipped;
421
422 success = isCorrect && success;
423 } else {
424 // Test config didn't specify valid limits. Fail this test!
425 testFailed("Limits for " + nodeName + "." + paramName + " were not cor rectly defined.");
426 success = false;
427 }
428
429 return success;
430 }
431
432 // Test all of the AudioParams for |node| using the expected values in |li mits|.
433 // |creatorName| is the name of the method to create the node, and is used to keep trakc of
434 // which tests we've run.
435 function testLimits(creatorName, node, limits) {
436 var nodeName = node.constructor.name;
437 testedMethods.add(creatorName);
438
439 var success = true;
440
441 // List of all of the AudioParams that were tested.
442 var audioParams = [];
443
444 // List of AudioParams that failed the test.
445 var incorrectParams = [];
446
447 // Look through all of the keys for the node and extract just the AudioP arams
448 Object.keys(node.__proto__).forEach(function (paramName) {
449 if (isAudioParam(node[paramName])) {
450 audioParams.push(paramName);
451 var isValid = validateAudioParamLimits(node, paramName, limits, inco rrectParams);
452 if (!isValid)
453 incorrectParams.push(paramName);
454
455 success = isValid && success;
456 }
457 });
458
459 // Print an appropriate message depending on whether there were AudioPar ams defined or not.
460 if (audioParams.length) {
461 var message = "Nominal ranges for AudioParam(s) of " + node.constructo r.name;
462 if (success)
463 testPassed(message + " are correct.\n");
464 else
465 testFailed(message + " are incorrect for: " + incorrectParams + ".\n ");
466 return success;
467 } else {
468 if (limits)
469 testFailed(nodeName + " has no AudioParams but test expected " + lim its + ".\n");
470 else
471 testPassed(nodeName + " has no AudioParams as expected.\n");
472 }
473 }
474 </script>
475 </body>
476 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698