OLD | NEW |
1 <!doctype html> | 1 <!DOCTYPE html> |
2 <html> | 2 <html> |
3 <head> | 3 <head> |
| 4 <title> |
| 5 Test CancelValuesAndHoldAtTime |
| 6 </title> |
4 <script src="../../resources/testharness.js"></script> | 7 <script src="../../resources/testharness.js"></script> |
5 <script src="../../resources/testharnessreport.js"></script> | 8 <script src="../../resources/testharnessreport.js"></script> |
6 <script src="../resources/audit-util.js"></script> | 9 <script src="../resources/audit-util.js"></script> |
7 <script src="../resources/audit.js"></script> | 10 <script src="../resources/audit.js"></script> |
8 <title>Test CancelValuesAndHoldAtTime</title> | |
9 </head> | 11 </head> |
10 | |
11 <body> | 12 <body> |
12 <script> | 13 <script id="layout-test-code"> |
13 let sampleRate = 48000; | 14 let sampleRate = 48000; |
14 let renderDuration = 0.5; | 15 let renderDuration = 0.5; |
15 | 16 |
16 let audit = Audit.createTaskRunner(); | 17 let audit = Audit.createTaskRunner(); |
17 | 18 |
18 // The first few tasks test the cancellation of each relevant automation | 19 // The first few tasks test the cancellation of each relevant automation |
19 // function. For the test, a simple linear ramp from 0 to 1 is used to | 20 // function. For the test, a simple linear ramp from 0 to 1 is used to |
20 // start things off. Then the automation to be tested is scheduled and | 21 // start things off. Then the automation to be tested is scheduled and |
21 // cancelled. | 22 // cancelled. |
22 | 23 |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 let v1 = 0; | 370 let v1 = 0; |
370 let t1 = renderDuration; | 371 let t1 = renderDuration; |
371 g[0].gain.linearRampToValueAtTime(v1, t1); | 372 g[0].gain.linearRampToValueAtTime(v1, t1); |
372 g[1].gain.linearRampToValueAtTime(v1, t1); | 373 g[1].gain.linearRampToValueAtTime(v1, t1); |
373 | 374 |
374 expectedConstant = | 375 expectedConstant = |
375 Math.fround(v0 + (v1 - v0) * (cancelTime - t0) / (t1 - t0)); | 376 Math.fround(v0 + (v1 - v0) * (cancelTime - t0) / (t1 - t0)); |
376 | 377 |
377 return { | 378 return { |
378 expectedConstant: expectedConstant, | 379 expectedConstant: expectedConstant, |
379 autoMessage: message + ': linearRampToValue(' + v1 + ', ' + t1 + ')'
, | 380 autoMessage: |
| 381 message + ': linearRampToValue(' + v1 + ', ' + t1 + ')', |
380 summary: message, | 382 summary: message, |
381 }; | 383 }; |
382 } | 384 } |
383 } | 385 } |
384 | 386 |
385 // Run the cancellation test. A set of automations is created and | 387 // Run the cancellation test. A set of automations is created and |
386 // canceled. | 388 // canceled. |
387 // | 389 // |
388 // |testFunction| is a function that generates the automation to be | 390 // |testFunction| is a function that generates the automation to be |
389 // tested. It is given an array of 3 gain nodes, the value and time of an | 391 // tested. It is given an array of 3 gain nodes, the value and time of an |
(...skipping 13 matching lines...) Expand all Loading... |
403 // | 405 // |
404 // For cancellation tests, |postCancelTest| is a function that schedules | 406 // For cancellation tests, |postCancelTest| is a function that schedules |
405 // some automation after the cancellation. It takes 3 arguments: an array | 407 // some automation after the cancellation. It takes 3 arguments: an array |
406 // of the gain nodes, the cancellation time, and the expected value at the | 408 // of the gain nodes, the cancellation time, and the expected value at the |
407 // cancellation time. This function must return a dictionary consisting | 409 // cancellation time. This function must return a dictionary consisting |
408 // of |constantEndtime| indicating when the held constant from | 410 // of |constantEndtime| indicating when the held constant from |
409 // cancellation stops being constant, |message| giving a summary of what | 411 // cancellation stops being constant, |message| giving a summary of what |
410 // automation is being used, and |errorThreshold| that is the error | 412 // automation is being used, and |errorThreshold| that is the error |
411 // threshold between the expected curve and the actual curve. | 413 // threshold between the expected curve and the actual curve. |
412 // | 414 // |
413 function cancelTest(should, testerFunction, thresholdOptions, | 415 function cancelTest( |
414 postCancelTest) { | 416 should, testerFunction, thresholdOptions, postCancelTest) { |
415 // Create a context with three channels. Channel 0 is the test channel | 417 // Create a context with three channels. Channel 0 is the test channel |
416 // containing the actual output that includes the cancellation of | 418 // containing the actual output that includes the cancellation of |
417 // events. Channel 1 is the expected data upto the cancellation so we | 419 // events. Channel 1 is the expected data upto the cancellation so we |
418 // can verify the cancellation produced the correct result. Channel 2 | 420 // can verify the cancellation produced the correct result. Channel 2 |
419 // is for verifying events inserted after the cancellation so we can | 421 // is for verifying events inserted after the cancellation so we can |
420 // verify that automations are correctly generated after the | 422 // verify that automations are correctly generated after the |
421 // cancellation point. | 423 // cancellation point. |
422 let context = new OfflineAudioContext(3, renderDuration * sampleRate, | 424 let context = |
423 sampleRate); | 425 new OfflineAudioContext(3, renderDuration * sampleRate, sampleRate); |
424 | 426 |
425 // Test source is a constant signal | 427 // Test source is a constant signal |
426 let src = context.createBufferSource(); | 428 let src = context.createBufferSource(); |
427 src.buffer = createConstantBuffer(context, 1, 1); | 429 src.buffer = createConstantBuffer(context, 1, 1); |
428 src.loop = true; | 430 src.loop = true; |
429 | 431 |
430 // We'll do the automation tests with three gain nodes. One (g0) will | 432 // We'll do the automation tests with three gain nodes. One (g0) will |
431 // have cancelAndHoldAtTime and the other (g1) will not. g1 is | 433 // have cancelAndHoldAtTime and the other (g1) will not. g1 is |
432 // used as the expected result for that automation up to the | 434 // used as the expected result for that automation up to the |
433 // cancellation point. They should be the same. The third node (g2) is | 435 // cancellation point. They should be the same. The third node (g2) is |
(...skipping 15 matching lines...) Expand all Loading... |
449 let expectedConstant = autoResult.expectedConstant; | 451 let expectedConstant = autoResult.expectedConstant; |
450 let autoMessage = autoResult.autoMessage; | 452 let autoMessage = autoResult.autoMessage; |
451 let summaryMessage = autoResult.summary; | 453 let summaryMessage = autoResult.summary; |
452 | 454 |
453 // Cancel scheduled events somewhere in the middle of the test | 455 // Cancel scheduled events somewhere in the middle of the test |
454 // automation. | 456 // automation. |
455 g0.gain.cancelAndHoldAtTime(cancelTime); | 457 g0.gain.cancelAndHoldAtTime(cancelTime); |
456 | 458 |
457 let constantEndTime; | 459 let constantEndTime; |
458 if (postCancelTest) { | 460 if (postCancelTest) { |
459 postResult = postCancelTest([g0, g1, g2], cancelTime, | 461 postResult = |
460 expectedConstant); | 462 postCancelTest([g0, g1, g2], cancelTime, expectedConstant); |
461 constantEndTime = postResult.constantEndTime; | 463 constantEndTime = postResult.constantEndTime; |
462 } | 464 } |
463 | 465 |
464 // Connect everything together (with a merger to make a two-channel | 466 // Connect everything together (with a merger to make a two-channel |
465 // result). Channel 0 is the test (with cancelAndHoldAtTime) and | 467 // result). Channel 0 is the test (with cancelAndHoldAtTime) and |
466 // channel 1 is the reference (without cancelAndHoldAtTime). | 468 // channel 1 is the reference (without cancelAndHoldAtTime). |
467 // Channel 1 is used to verify that everything up to the cancellation | 469 // Channel 1 is used to verify that everything up to the cancellation |
468 // has the correct values. | 470 // has the correct values. |
469 src.connect(g0); | 471 src.connect(g0); |
470 src.connect(g1); | 472 src.connect(g1); |
471 src.connect(g2); | 473 src.connect(g2); |
472 let merger = context.createChannelMerger(3); | 474 let merger = context.createChannelMerger(3); |
473 g0.connect(merger, 0, 0); | 475 g0.connect(merger, 0, 0); |
474 g1.connect(merger, 0, 1); | 476 g1.connect(merger, 0, 1); |
475 g2.connect(merger, 0, 2); | 477 g2.connect(merger, 0, 2); |
476 merger.connect(context.destination); | 478 merger.connect(context.destination); |
477 | 479 |
478 // Go! | 480 // Go! |
479 src.start(); | 481 src.start(); |
480 | 482 |
481 return context.startRendering().then(function (buffer) { | 483 return context.startRendering().then(function(buffer) { |
482 let actual = buffer.getChannelData(0); | 484 let actual = buffer.getChannelData(0); |
483 let expected = buffer.getChannelData(1); | 485 let expected = buffer.getChannelData(1); |
484 | 486 |
485 // The actual output should be a constant from the cancel time to the | 487 // The actual output should be a constant from the cancel time to the |
486 // end. We use the last value of the actual output as the constant, | 488 // end. We use the last value of the actual output as the constant, |
487 // but we also want to compare that with what we thought it should | 489 // but we also want to compare that with what we thought it should |
488 // really be. | 490 // really be. |
489 | 491 |
490 let cancelFrame = Math.ceil(cancelTime * sampleRate); | 492 let cancelFrame = Math.ceil(cancelTime * sampleRate); |
491 | 493 |
492 // Verify that the curves up to the cancel time are "identical". The | 494 // Verify that the curves up to the cancel time are "identical". The |
493 // should be but round-off may make them differ slightly due to the | 495 // should be but round-off may make them differ slightly due to the |
494 // way cancelling is done. | 496 // way cancelling is done. |
495 let endFrame = Math.floor(cancelTime * sampleRate); | 497 let endFrame = Math.floor(cancelTime * sampleRate); |
496 should(actual.slice(0, endFrame), | 498 should( |
497 autoMessage + " up to time " + cancelTime) | 499 actual.slice(0, endFrame), |
498 .beCloseToArray(expected.slice(0, endFrame), { | 500 autoMessage + ' up to time ' + cancelTime) |
499 absoluteThreshold: thresholdOptions.curveThreshold | 501 .beCloseToArray( |
500 }); | 502 expected.slice(0, endFrame), |
| 503 {absoluteThreshold: thresholdOptions.curveThreshold}); |
501 | 504 |
502 // Verify the output after the cancellation is a constant. | 505 // Verify the output after the cancellation is a constant. |
503 let actualTail; | 506 let actualTail; |
504 let constantEndFrame; | 507 let constantEndFrame; |
505 | 508 |
506 if (postCancelTest) { | 509 if (postCancelTest) { |
507 constantEndFrame = Math.ceil(constantEndTime * sampleRate); | 510 constantEndFrame = Math.ceil(constantEndTime * sampleRate); |
508 actualTail = actual.slice(cancelFrame, constantEndFrame); | 511 actualTail = actual.slice(cancelFrame, constantEndFrame); |
509 } else { | 512 } else { |
510 actualTail = actual.slice(cancelFrame); | 513 actualTail = actual.slice(cancelFrame); |
511 } | 514 } |
512 | 515 |
513 let actualConstant = actual[cancelFrame]; | 516 let actualConstant = actual[cancelFrame]; |
514 | 517 |
515 should(actualTail, "Cancelling " + autoMessage + " at time " + | 518 should( |
516 cancelTime) | 519 actualTail, |
517 .beConstantValueOf(actualConstant); | 520 'Cancelling ' + autoMessage + ' at time ' + cancelTime) |
| 521 .beConstantValueOf(actualConstant); |
518 | 522 |
519 // Verify that the constant is the value we expect. | 523 // Verify that the constant is the value we expect. |
520 should(actualConstant, "Expected value for cancelling " + | 524 should( |
521 autoMessage + " at time " + | 525 actualConstant, |
522 cancelTime) | 526 'Expected value for cancelling ' + autoMessage + ' at time ' + |
523 .beCloseTo(expectedConstant, { | 527 cancelTime) |
524 threshold: thresholdOptions.valueThreshold | 528 .beCloseTo( |
525 }); | 529 expectedConstant, |
| 530 {threshold: thresholdOptions.valueThreshold}); |
526 | 531 |
527 // Verify the curve after the constantEndTime matches our | 532 // Verify the curve after the constantEndTime matches our |
528 // expectations. | 533 // expectations. |
529 if (postCancelTest) { | 534 if (postCancelTest) { |
530 let c2 = buffer.getChannelData(2); | 535 let c2 = buffer.getChannelData(2); |
531 should(actual.slice(constantEndFrame), postResult.message) | 536 should(actual.slice(constantEndFrame), postResult.message) |
532 .beCloseToArray(c2.slice(constantEndFrame), { | 537 .beCloseToArray( |
533 absoluteThreshold: postResult.errorThreshold || 0 | 538 c2.slice(constantEndFrame), |
534 }); | 539 {absoluteThreshold: postResult.errorThreshold || 0}); |
535 } | 540 } |
536 }); | 541 }); |
537 } | 542 } |
538 </script> | 543 </script> |
539 </body> | 544 </body> |
540 </html> | 545 </html> |
OLD | NEW |