OLD | NEW |
---|---|
1 var sampleRate = 44100; | 1 var sampleRate = 44100; |
2 | 2 |
3 // Information about the starting/ending times and starting/ending values for ea ch time interval. | 3 // Information about the starting/ending times and starting/ending values for ea ch time interval. |
4 var timeValueInfo; | 4 var timeValueInfo; |
5 | 5 |
6 // The difference between starting values between each time interval. | 6 // The difference between starting values between each time interval. |
7 var startingValueDelta; | 7 var startingValueDelta; |
8 | 8 |
9 // For any automation function that has an end or target value, the end value is based the starting | 9 // For any automation function that has an end or target value, the end value is based the starting |
10 // value of the time interval. The starting value will be increased or decrease d by | 10 // value of the time interval. The starting value will be increased or decrease d by |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
212 | 212 |
213 // Return the difference between the starting value at |timeIntervalIndex| and t he starting value at | 213 // Return the difference between the starting value at |timeIntervalIndex| and t he starting value at |
214 // the next time interval. Since we started at a large initial value, we decrea se the value at each | 214 // the next time interval. Since we started at a large initial value, we decrea se the value at each |
215 // time interval. | 215 // time interval. |
216 function valueUpdate(timeIntervalIndex) | 216 function valueUpdate(timeIntervalIndex) |
217 { | 217 { |
218 return -startingValueDelta; | 218 return -startingValueDelta; |
219 } | 219 } |
220 | 220 |
221 // Compare a section of the rendered data against our expected signal. | 221 // Compare a section of the rendered data against our expected signal. |
222 function comparePartialSignals(rendered, expectedFunction, startTime, endTime, v alueInfo, sampleRate, errorMetric) | 222 function comparePartialSignals(should, rendered, expectedFunction, startTime, en dTime, valueInfo, sampleRate, errorMetric) |
223 { | 223 { |
224 var startSample = timeToSampleFrame(startTime, sampleRate); | 224 var startSample = timeToSampleFrame(startTime, sampleRate); |
225 var expected = expectedFunction(startTime, endTime, valueInfo.startValue, va lueInfo.endValue, sampleRate, timeConstant); | 225 var expected = expectedFunction(startTime, endTime, valueInfo.startValue, va lueInfo.endValue, sampleRate, timeConstant); |
226 | 226 |
227 var n = expected.length; | 227 var n = expected.length; |
228 var maxError = -1; | 228 var maxError = -1; |
229 var maxErrorIndex = -1; | 229 var maxErrorIndex = -1; |
230 | 230 |
231 for (var k = 0; k < n; ++k) { | 231 for (var k = 0; k < n; ++k) { |
232 // Make sure we don't pass these tests because a NaN has been generated in either the | 232 // Make sure we don't pass these tests because a NaN has been generated in either the |
233 // rendered data or the reference data. | 233 // rendered data or the reference data. |
234 if (!isValidNumber(rendered[startSample + k])) { | 234 if (!isValidNumber(rendered[startSample + k])) { |
235 maxError = Infinity; | 235 maxError = Infinity; |
236 maxErrorIndex = startSample + k; | 236 maxErrorIndex = startSample + k; |
237 testFailed("NaN or infinity for rendered data at " + maxErrorIndex); | 237 //testFailed("NaN or infinity for rendered data at " + maxErrorIndex ); |
hongchan
2017/01/30 17:38:04
Remove this line.
| |
238 should(!isValidNumber(rendered[startSample + k]), | |
hongchan
2017/01/30 17:38:04
Can this be |isValidNumber()| then |beTrue()|?
Sa
Raymond Toy
2017/01/30 18:07:02
I thought it would be better to keep the test cond
| |
239 "NaN or infinity for rendered data at " + maxErrorIndex) | |
240 .beFalse(); | |
238 break; | 241 break; |
239 } | 242 } |
240 if (!isValidNumber(expected[k])) { | 243 if (!isValidNumber(expected[k])) { |
241 maxError = Infinity; | 244 maxError = Infinity; |
242 maxErrorIndex = startSample + k; | 245 maxErrorIndex = startSample + k; |
243 testFailed("Nan or infinity for reference data at " + maxErrorIndex) ; | 246 //testFailed("Nan or infinity for reference data at " + maxErrorInde x); |
hongchan
2017/01/30 17:38:04
Ditto.
| |
247 should(!isValidNumber(expected[k]), | |
248 "NaN or infinity for rendered data at " + maxErrorIndex) | |
249 .beFalse(); | |
244 break; | 250 break; |
245 } | 251 } |
246 var error = Math.abs(errorMetric(rendered[startSample + k], expected[k]) ); | 252 var error = Math.abs(errorMetric(rendered[startSample + k], expected[k]) ); |
247 if (error > maxError) { | 253 if (error > maxError) { |
248 maxError = error; | 254 maxError = error; |
249 maxErrorIndex = k; | 255 maxErrorIndex = k; |
250 } | 256 } |
251 } | 257 } |
252 | 258 |
253 return {maxError : maxError, index : maxErrorIndex, expected: expected}; | 259 return {maxError : maxError, index : maxErrorIndex, expected: expected}; |
254 } | 260 } |
255 | 261 |
256 // Find the discontinuities in the data and compare the locations of the discont inuities with the | 262 // Find the discontinuities in the data and compare the locations of the discont inuities with the |
257 // times that define the time intervals. There is a discontinuity if the differe nce between | 263 // times that define the time intervals. There is a discontinuity if the differe nce between |
258 // successive samples exceeds the threshold. | 264 // successive samples exceeds the threshold. |
259 function verifyDiscontinuities(values, times, threshold) | 265 function verifyDiscontinuities(should, values, times, threshold) |
260 { | 266 { |
261 var n = values.length; | 267 var n = values.length; |
262 var success = true; | 268 var success = true; |
263 var badLocations = 0; | 269 var badLocations = 0; |
264 var breaks = []; | 270 var breaks = []; |
265 | 271 |
266 // Find discontinuities. | 272 // Find discontinuities. |
267 for (var k = 1; k < n; ++k) { | 273 for (var k = 1; k < n; ++k) { |
268 if (Math.abs(values[k] - values[k - 1]) > threshold) { | 274 if (Math.abs(values[k] - values[k - 1]) > threshold) { |
269 breaks.push(k); | 275 breaks.push(k); |
270 } | 276 } |
271 } | 277 } |
272 | 278 |
273 var testCount; | 279 var testCount; |
274 | 280 |
275 // If there are numberOfTests intervals, there are only numberOfTests - 1 in ternal interval | 281 // If there are numberOfTests intervals, there are only numberOfTests - 1 in ternal interval |
276 // boundaries. Hence the maximum number of discontinuties we expect to find is numberOfTests - | 282 // boundaries. Hence the maximum number of discontinuties we expect to find is numberOfTests - |
277 // 1. If we find more than that, we have no reference to compare against. We also assume that | 283 // 1. If we find more than that, we have no reference to compare against. We also assume that |
278 // the actual discontinuities are close to the expected ones. | 284 // the actual discontinuities are close to the expected ones. |
279 // | 285 // |
280 // This is just a sanity check when something goes really wrong. For exampl e, if the threshold | 286 // This is just a sanity check when something goes really wrong. For exampl e, if the threshold |
281 // is too low, every sample frame looks like a discontinuity. | 287 // is too low, every sample frame looks like a discontinuity. |
282 if (breaks.length >= numberOfTests) { | 288 if (breaks.length >= numberOfTests) { |
283 testCount = numberOfTests - 1; | 289 testCount = numberOfTests - 1; |
284 testFailed("Found more discontinuities (" + breaks.length + ") than expe cted. Only comparing first " + testCount + "discontinuities."); | 290 //testFailed("Found more discontinuities (" + breaks.length + ") than ex pected. Only comparing first " + testCount + "discontinuities."); |
291 should(breaks.length, | |
292 "Number of discontinuities") | |
293 .beLessThan(numberOfTests); | |
285 success = false; | 294 success = false; |
286 } else { | 295 } else { |
287 testCount = breaks.length; | 296 testCount = breaks.length; |
288 } | 297 } |
289 | 298 |
290 // Compare the location of each discontinuity with the end time of each inte rval. (There is no | 299 // Compare the location of each discontinuity with the end time of each inte rval. (There is no |
291 // discontinuity at the start of the signal.) | 300 // discontinuity at the start of the signal.) |
292 for (var k = 0; k < testCount; ++k) { | 301 for (var k = 0; k < testCount; ++k) { |
293 var expectedSampleFrame = timeToSampleFrame(times[k + 1], sampleRate); | 302 var expectedSampleFrame = timeToSampleFrame(times[k + 1], sampleRate); |
294 if (breaks[k] != expectedSampleFrame) { | 303 if (breaks[k] != expectedSampleFrame) { |
295 success = false; | 304 success = false; |
296 ++badLocations; | 305 ++badLocations; |
297 testFailed("Expected discontinuity at " + expectedSampleFrame + " bu t got " + breaks[k]); | 306 //testFailed("Expected discontinuity at " + expectedSampleFrame + " but got " + breaks[k]); |
307 should(breaks[k], | |
308 "Discontinuity at index") | |
309 .beEqualTo(expectedSampleFrame); | |
298 } | 310 } |
299 } | 311 } |
300 | 312 |
301 if (badLocations) { | 313 if (badLocations) { |
302 testFailed(badLocations + " discontinuities at incorrect locations"); | 314 //testFailed(badLocations + " discontinuities at incorrect locations"); |
315 should(badLocations, "Number of discontinuites at incorrect locations") | |
316 .beEqualTo(0); | |
303 success = false; | 317 success = false; |
304 } else { | 318 } else { |
319 /* | |
305 if (breaks.length == numberOfTests - 1) { | 320 if (breaks.length == numberOfTests - 1) { |
306 testPassed("All " + numberOfTests + " tests started and ended at the correct time."); | 321 testPassed("All " + numberOfTests + " tests started and ended at the correct time."); |
307 } else { | 322 } else { |
308 testFailed("Found " + breaks.length + " discontinuities but expected " + (numberOfTests - 1)); | 323 testFailed("Found " + breaks.length + " discontinuities but expected " + (numberOfTests - 1)); |
309 success = false; | 324 success = false; |
310 } | 325 } |
326 */ | |
327 should(breaks.length + 1, | |
328 "Number of tests started and ended at the correct time") | |
329 .beEqualTo(numberOfTests); | |
311 } | 330 } |
312 | 331 |
313 return success; | 332 return success; |
314 } | 333 } |
315 | 334 |
316 // Compare the rendered data with the expected data. | 335 // Compare the rendered data with the expected data. |
317 // | 336 // |
318 // testName - string describing the test | 337 // testName - string describing the test |
319 // | 338 // |
320 // maxError - maximum allowed difference between the rendered data and the expec ted data | 339 // maxError - maximum allowed difference between the rendered data and the expec ted data |
321 // | 340 // |
322 // rendererdData - array containing the rendered (actual) data | 341 // rendererdData - array containing the rendered (actual) data |
323 // | 342 // |
324 // expectedFunction - function to compute the expected data | 343 // expectedFunction - function to compute the expected data |
325 // | 344 // |
326 // timeValueInfo - array containing information about the start and end times an d the start and end | 345 // timeValueInfo - array containing information about the start and end times an d the start and end |
327 // values of each interval. | 346 // values of each interval. |
328 // | 347 // |
329 // breakThreshold - threshold to use for determining discontinuities. | 348 // breakThreshold - threshold to use for determining discontinuities. |
330 function compareSignals(testName, maxError, renderedData, expectedFunction, time ValueInfo, breakThreshold, errorMetric) | 349 function compareSignals(should, testName, maxError, renderedData, expectedFuncti on, timeValueInfo, breakThreshold, errorMetric) |
331 { | 350 { |
332 var success = true; | 351 var success = true; |
333 var failedTestCount = 0; | 352 var failedTestCount = 0; |
334 var times = timeValueInfo.times; | 353 var times = timeValueInfo.times; |
335 var values = timeValueInfo.values; | 354 var values = timeValueInfo.values; |
336 var n = values.length; | 355 var n = values.length; |
337 var expectedSignal = []; | 356 var expectedSignal = []; |
338 | 357 |
339 success = verifyDiscontinuities(renderedData, times, breakThreshold); | 358 success = verifyDiscontinuities(should, renderedData, times, breakThreshold) ; |
340 | 359 |
341 for (var k = 0; k < n; ++k) { | 360 for (var k = 0; k < n; ++k) { |
342 var result = comparePartialSignals(renderedData, expectedFunction, times [k], times[k + 1], values[k], sampleRate, errorMetric); | 361 var result = comparePartialSignals(should, renderedData, expectedFunction, times[k], times[k + 1], values[k], sampleRate, errorMetric); |
343 | 362 |
344 expectedSignal = expectedSignal.concat(Array.prototype.slice.call(result .expected)); | 363 expectedSignal = expectedSignal.concat(Array.prototype.slice.call(result .expected)); |
345 | 364 |
365 /* | |
hongchan
2017/01/30 17:38:04
Remove commented line.
| |
346 if (result.maxError > maxError) { | 366 if (result.maxError > maxError) { |
347 var offset = result.index + timeToSampleFrame(times[k], sampleRate); | 367 var offset = result.index + timeToSampleFrame(times[k], sampleRate); |
348 testFailed("Incorrect value for test " + k + ". Max error = " + resu lt.maxError | 368 testFailed("Incorrect value for test " + k + ". Max error = " + resu lt.maxError |
349 + " at offset " + offset | 369 + " at offset " + offset |
350 + ": actual = " + renderedData[offset] | 370 + ": actual = " + renderedData[offset] |
351 + ", expected = " + expectedSignal[offset] + "."); | 371 + ", expected = " + expectedSignal[offset] + "."); |
352 ++failedTestCount; | 372 ++failedTestCount; |
353 } | 373 } |
374 */ | |
375 should(result.maxError, | |
376 "Max error for test " + k + " at offset " + (result.index + timeT oSampleFrame(times[k], sampleRate))) | |
377 .beLessThanOrEqualTo(maxError); | |
354 } | 378 } |
355 | 379 |
380 /* | |
hongchan
2017/01/30 17:38:04
Ditto.
| |
356 if (failedTestCount) { | 381 if (failedTestCount) { |
357 testFailed(failedTestCount + " tests failed out of " + n); | 382 testFailed(failedTestCount + " tests failed out of " + n); |
358 success = false; | 383 success = false; |
359 } else { | 384 } else { |
360 testPassed("All " + n + " tests passed within an acceptable relative tol erance of " + maxError + "."); | 385 testPassed("All " + n + " tests passed within an acceptable relative tol erance of " + maxError + "."); |
361 } | 386 } |
387 */ | |
388 should(failedTestCount, | |
389 "Number of failed tests with an acceptable relative tolerance of " + maxError) | |
390 .beEqualTo(0); | |
362 | 391 |
392 /* | |
hongchan
2017/01/30 17:38:04
Ditto.
| |
363 if (success) { | 393 if (success) { |
364 testPassed("AudioParam " + testName + " test passed."); | 394 testPassed("AudioParam " + testName + " test passed."); |
365 } else { | 395 } else { |
366 testFailed("AudioParam " + testName + " test failed."); | 396 testFailed("AudioParam " + testName + " test failed."); |
367 } | 397 } |
398 */ | |
368 } | 399 } |
369 | 400 |
370 // Create a function to test the rendered data with the reference data. | 401 // Create a function to test the rendered data with the reference data. |
371 // | 402 // |
372 // testName - string describing the test | 403 // testName - string describing the test |
373 // | 404 // |
374 // error - max allowed error between rendered data and the reference data. | 405 // error - max allowed error between rendered data and the reference data. |
375 // | 406 // |
376 // referenceFunction - function that generates the reference data to be compared with the rendered | 407 // referenceFunction - function that generates the reference data to be compared with the rendered |
377 // data. | 408 // data. |
378 // | 409 // |
379 // jumpThreshold - optional parameter that specifies the threshold to use for de tecting | 410 // jumpThreshold - optional parameter that specifies the threshold to use for de tecting |
380 // discontinuities. If not specified, defaults to discontinuityThreshold. | 411 // discontinuities. If not specified, defaults to discontinuityThreshold. |
381 // | 412 // |
382 function checkResultFunction(testName, error, referenceFunction, jumpThreshold, errorMetric) | 413 function checkResultFunction(task, should, testName, error, referenceFunction, j umpThreshold, errorMetric) |
383 { | 414 { |
384 return function(event) { | 415 return function(event) { |
385 var buffer = event.renderedBuffer; | 416 var buffer = event.renderedBuffer; |
386 renderedData = buffer.getChannelData(0); | 417 renderedData = buffer.getChannelData(0); |
387 | 418 |
388 var threshold; | 419 var threshold; |
389 | 420 |
390 if (!jumpThreshold) { | 421 if (!jumpThreshold) { |
391 threshold = discontinuityThreshold; | 422 threshold = discontinuityThreshold; |
392 } else { | 423 } else { |
393 threshold = jumpThreshold; | 424 threshold = jumpThreshold; |
394 } | 425 } |
395 | 426 |
396 compareSignals(testName, error, renderedData, referenceFunction, timeVal ueInfo, threshold, errorMetric); | 427 compareSignals(should, testName, error, renderedData, referenceFunction, timeValueInfo, threshold, errorMetric); |
397 | 428 task.done(); |
398 finishJSTest(); | |
399 } | 429 } |
400 } | 430 } |
401 | 431 |
402 // Run all the automation tests. | 432 // Run all the automation tests. |
403 // | 433 // |
404 // numberOfTests - number of tests (time intervals) to run. | 434 // numberOfTests - number of tests (time intervals) to run. |
405 // | 435 // |
406 // initialValue - The initial value of the first time interval. | 436 // initialValue - The initial value of the first time interval. |
407 // | 437 // |
408 // setValueFunction - function that sets the specified value at the start of a t ime interval. | 438 // setValueFunction - function that sets the specified value at the start of a t ime interval. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
452 // testName - string indicating the test that is being run. | 482 // testName - string indicating the test that is being run. |
453 // | 483 // |
454 // maxError - maximum allowed error between the rendered data and the reference data | 484 // maxError - maximum allowed error between the rendered data and the reference data |
455 // | 485 // |
456 // referenceFunction - function that generates the reference data to be compared against the | 486 // referenceFunction - function that generates the reference data to be compared against the |
457 // rendered data. | 487 // rendered data. |
458 // | 488 // |
459 // jumpThreshold - optional parameter that specifies the threshold to use for de tecting | 489 // jumpThreshold - optional parameter that specifies the threshold to use for de tecting |
460 // discontinuities. If not specified, defaults to discontinuityThreshold. | 490 // discontinuities. If not specified, defaults to discontinuityThreshold. |
461 // | 491 // |
462 function createAudioGraphAndTest(numberOfTests, initialValue, setValueFunction, automationFunction, testName, maxError, referenceFunction, jumpThreshold, errorM etric) | 492 function createAudioGraphAndTest(task, should, numberOfTests, initialValue, setV alueFunction, automationFunction, testName, maxError, referenceFunction, jumpThr eshold, errorMetric) |
463 { | 493 { |
464 if (window.testRunner) { | |
465 testRunner.dumpAsText(); | |
466 testRunner.waitUntilDone(); | |
467 } | |
468 | |
469 window.jsTestIsAsync = true; | |
470 | |
471 // Create offline audio context. | 494 // Create offline audio context. |
472 context = new OfflineAudioContext(2, renderLength(numberOfTests), sampleRate ); | 495 context = new OfflineAudioContext(2, renderLength(numberOfTests), sampleRate ); |
473 var constantBuffer = createConstantBuffer(context, renderLength(numberOfTest s), 1); | 496 var constantBuffer = createConstantBuffer(context, renderLength(numberOfTest s), 1); |
474 | 497 |
475 // We use an AudioGainNode here simply as a convenient way to test the Audio Param | 498 // We use an AudioGainNode here simply as a convenient way to test the Audio Param |
476 // automation, since it's easy to pass a constant value through the node, au tomate the | 499 // automation, since it's easy to pass a constant value through the node, au tomate the |
477 // .gain attribute and observe the resulting values. | 500 // .gain attribute and observe the resulting values. |
478 | 501 |
479 gainNode = context.createGain(); | 502 gainNode = context.createGain(); |
480 | 503 |
481 var bufferSource = context.createBufferSource(); | 504 var bufferSource = context.createBufferSource(); |
482 bufferSource.buffer = constantBuffer; | 505 bufferSource.buffer = constantBuffer; |
483 bufferSource.connect(gainNode); | 506 bufferSource.connect(gainNode); |
484 gainNode.connect(context.destination); | 507 gainNode.connect(context.destination); |
485 | 508 |
486 // Set up default values for the parameters that control how the automation test values progress | 509 // Set up default values for the parameters that control how the automation test values progress |
487 // for each time interval. | 510 // for each time interval. |
488 startingValueDelta = initialValue / numberOfTests; | 511 startingValueDelta = initialValue / numberOfTests; |
489 startEndValueChange = startingValueDelta / 2; | 512 startEndValueChange = startingValueDelta / 2; |
490 discontinuityThreshold = startEndValueChange / 2; | 513 discontinuityThreshold = startEndValueChange / 2; |
491 | 514 |
492 // Run the automation tests. | 515 // Run the automation tests. |
493 timeValueInfo = doAutomation(numberOfTests, | 516 timeValueInfo = doAutomation(numberOfTests, |
494 initialValue, | 517 initialValue, |
495 setValueFunction, | 518 setValueFunction, |
496 automationFunction); | 519 automationFunction); |
497 bufferSource.start(0); | 520 bufferSource.start(0); |
498 | 521 |
499 context.oncomplete = checkResultFunction(testName, | 522 context.oncomplete = checkResultFunction(task, should, testName, |
500 maxError, | 523 maxError, |
501 referenceFunction, | 524 referenceFunction, |
502 jumpThreshold, | 525 jumpThreshold, |
503 errorMetric || relativeErrorMetric) ; | 526 errorMetric || relativeErrorMetric) ; |
504 context.startRendering(); | 527 context.startRendering(); |
505 } | 528 } |
OLD | NEW |