| OLD | NEW |
| (Empty) | |
| 1 <!doctype html> |
| 2 <html> |
| 3 <head> |
| 4 <title>Test Automation Following setValueCurveAtTime Automations</title> |
| 5 <script src="../resources/js-test.js"></script> |
| 6 <script src="resources/compatibility.js"></script> |
| 7 <script src="resources/audio-testing.js"></script> |
| 8 <script src="resources/audio-param.js"></script> |
| 9 </head> |
| 10 |
| 11 <body> |
| 12 <script> |
| 13 description("Test Automation Following setValueCurveAtTime Automations"); |
| 14 window.jsTestIsAsync = true; |
| 15 |
| 16 var sampleRate = 12800; |
| 17 // Some short duration because we don't need to run the test for very long
. |
| 18 var testDurationFrames = 256; |
| 19 var testDurationSec = testDurationFrames / sampleRate; |
| 20 var curveDuration = testDurationSec / 2; |
| 21 |
| 22 var audit = Audit.createTaskRunner(); |
| 23 |
| 24 // Configuration for each test. |
| 25 // |
| 26 // Required options: |
| 27 // automation - Name of automation method to test |
| 28 // time - Time for the automation method. |
| 29 // Optional options: |
| 30 // extraDuration - extra time for the duration of the setValueCurve |
| 31 // duration. Default is 0. This should not be on a |
| 32 // sample frame boundary. This is for testing that |
| 33 // curves that don't end on a frame boundary are handled |
| 34 // correctly. |
| 35 // threshold - Error threshold for the test; default is 0. |
| 36 var testConfigs = [{ |
| 37 automation: "linearRampToValueAtTime", |
| 38 time: testDurationSec, |
| 39 threshold: 3.9737e-8 |
| 40 }, { |
| 41 automation: "linearRampToValueAtTime", |
| 42 time: testDurationSec, |
| 43 extraDuration: 0.5 / sampleRate, |
| 44 threshold: 1.8141e-8 |
| 45 }, { |
| 46 automation: "exponentialRampToValueAtTime", |
| 47 time: testDurationSec, |
| 48 threshold: 3.9737e-8 |
| 49 }, { |
| 50 automation: "exponentialRampToValueAtTime", |
| 51 time: testDurationSec, |
| 52 extraDuration: 0.5 / sampleRate, |
| 53 threshold: 2.0312e-8 |
| 54 }, { |
| 55 automation: "setTargetAtTime", |
| 56 time: curveDuration, |
| 57 threshold: 1.5895e-7 |
| 58 }, { |
| 59 automation: "setTargetAtTime", |
| 60 time: curveDuration + 0.5 / sampleRate, |
| 61 extraDuration: 0.5 / sampleRate, |
| 62 threshold: 1.3278e-7 |
| 63 }]; |
| 64 |
| 65 // Define tests from the configs |
| 66 for (k in testConfigs) { |
| 67 audit.defineTask(k + ": " + testConfigs[k].automation, (function (config
) { |
| 68 return function (done) { |
| 69 runTest(config).then(done); |
| 70 }; |
| 71 })(testConfigs[k])); |
| 72 } |
| 73 |
| 74 audit.defineTask("finish", function (done) { |
| 75 finishJSTest(); |
| 76 done(); |
| 77 }); |
| 78 |
| 79 audit.runTasks(); |
| 80 |
| 81 function runTest(options) { |
| 82 // For the test, use a gain node with a constant input to test the |
| 83 // automations. |
| 84 var context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; |
| 85 var source = context.createBufferSource(); |
| 86 source.buffer = createConstantBuffer(context, 1, 1); |
| 87 source.loop = true; |
| 88 |
| 89 var gain = context.createGain(); |
| 90 |
| 91 // Any valid curve is ok. We only use the last value for testing. |
| 92 var curve = [0, 2, 0.3]; |
| 93 var actualDuration = curveDuration + (options.extraDuration || 0); |
| 94 gain.gain.setValueCurveAtTime(Float32Array.from(curve), 0, actualDuratio
n); |
| 95 |
| 96 // Run the desired test automation. The extra parameter (0.01) is only |
| 97 // used for setTargetAtTime tests; it's ignored for other tests. |
| 98 var automationValue = 2; |
| 99 gain.gain[options.automation](automationValue, options.time, 0.01); |
| 100 |
| 101 source.connect(gain); |
| 102 gain.connect(context.destination); |
| 103 |
| 104 source.start(); |
| 105 |
| 106 return context.startRendering().then(function (resultBuffer) { |
| 107 var result = resultBuffer.getChannelData(0); |
| 108 |
| 109 // Only need to verify that the ramp started at the right |
| 110 // value. Figure the nearest sample frame to the end curve. |
| 111 var curveEndFrame = Math.ceil(actualDuration * sampleRate); |
| 112 |
| 113 var expectedResult = curve[curve.length - 1]; |
| 114 |
| 115 // Determine the expected value after the end of the setValueCurve eve
nt. |
| 116 if (options.automation == "linearRampToValueAtTime") { |
| 117 expectedResult = audioParamLinearRamp( |
| 118 curveEndFrame / sampleRate, |
| 119 curve[curve.length - 1], actualDuration, |
| 120 automationValue, testDurationSec); |
| 121 } else if (options.automation == "exponentialRampToValueAtTime") { |
| 122 expectedResult = audioParamExponentialRamp( |
| 123 curveEndFrame / sampleRate, |
| 124 curve[curve.length - 1], actualDuration, |
| 125 automationValue, testDurationSec); |
| 126 } else if (options.automation == "setTargetAtTime") { |
| 127 expectedResult = audioParamSetTarget( |
| 128 curveEndFrame / sampleRate, |
| 129 curve[curve.length - 1], actualDuration, |
| 130 automationValue, 0.01); |
| 131 } |
| 132 |
| 133 var message = "setValueCurve(..., " + 0 + ", " + actualDuration + |
| 134 ")." + options.automation + |
| 135 "(2, " + testDurationSec; |
| 136 |
| 137 if (options.automation == "setTargetAtTime") |
| 138 message += ", 0.01"; |
| 139 message += ")"; |
| 140 |
| 141 Should(message + ": value at time " + curveEndFrame / sampleRate, resu
lt[curveEndFrame]) |
| 142 .beCloseTo(expectedResult, options.threshold || 0); |
| 143 }); |
| 144 } |
| 145 |
| 146 function linearRampValue(t, t0, v0, t1, v1) { |
| 147 return v0 + (v1 - v0) * (t - t0) / (t1 - t0); |
| 148 } |
| 149 |
| 150 function exponentialRampValue(t, t0, v0, t1, v1) { |
| 151 return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0)); |
| 152 } |
| 153 |
| 154 function setTargetValue(t, t0, v0, v1, timeConstant) { |
| 155 return v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant) |
| 156 } |
| 157 </script> |
| 158 </body> |
| 159 </html> |
| OLD | NEW |