Chromium Code Reviews| 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 |