| 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 |