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

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/audioparam-nominal-range.html

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

Powered by Google App Engine
This is Rietveld 408576698