| OLD | NEW |
| 1 <!doctype html> | 1 <!doctype html> |
| 2 <html> | 2 <html> |
| 3 <head> | 3 <head> |
| 4 <script src="../../resources/testharness.js"></script> | 4 <script src="../../resources/testharness.js"></script> |
| 5 <script src="../../resources/testharnessreport.js"></script> | 5 <script src="../../resources/testharnessreport.js"></script> |
| 6 <script src="../resources/audit-util.js"></script> | 6 <script src="../resources/audit-util.js"></script> |
| 7 <script src="../resources/audio-testing.js"></script> | 7 <script src="../resources/audit.js"></script> |
| 8 <script src="../resources/audioparam-testing.js"></script> | 8 <script src="../resources/audioparam-testing.js"></script> |
| 9 <title>SetTarget Followed by Linear or Exponential Ramp Is Continuous</title
> | 9 <title>SetTarget Followed by Linear or Exponential Ramp Is Continuous</title
> |
| 10 </head> | 10 </head> |
| 11 | 11 |
| 12 <body> | 12 <body> |
| 13 <script> | 13 <script> |
| 14 | 14 |
| 15 var sampleRate = 48000; | 15 var sampleRate = 48000; |
| 16 var renderQuantum = 128; | 16 var renderQuantum = 128; |
| 17 // Test doesn't need to run for very long. | 17 // Test doesn't need to run for very long. |
| 18 var renderDuration = 0.1; | 18 var renderDuration = 0.1; |
| 19 // Where the ramp should end | 19 // Where the ramp should end |
| 20 var rampEndTime = renderDuration - .05; | 20 var rampEndTime = renderDuration - .05; |
| 21 var renderFrames = renderDuration * sampleRate; | 21 var renderFrames = renderDuration * sampleRate; |
| 22 var timeConstant = 0.01; | 22 var timeConstant = 0.01; |
| 23 | 23 |
| 24 var audit = Audit.createTaskRunner(); | 24 var audit = Audit.createTaskRunner(); |
| 25 | 25 |
| 26 // All of the tests start a SetTargetAtTime after one rendering quantum.
The following tests | 26 // All of the tests start a SetTargetAtTime after one rendering quantum.
The following tests |
| 27 // handle various cases where a linear or exponential ramp is scheduled at
or after | 27 // handle various cases where a linear or exponential ramp is scheduled at
or after |
| 28 // SetTargetAtTime starts. | 28 // SetTargetAtTime starts. |
| 29 | 29 |
| 30 audit.defineTask("linear ramp replace", function (done) { | 30 audit.define("linear ramp replace", (task, should) => { |
| 31 // Schedule a linear ramp to start at the same time as SetTargetAtTime.
This effectively | 31 // Schedule a linear ramp to start at the same time as SetTargetAtTime.
This effectively |
| 32 // replaces the SetTargetAtTime as if it never existed. | 32 // replaces the SetTargetAtTime as if it never existed. |
| 33 runTest("Linear ramp", { | 33 runTest(should, "Linear ramp", { |
| 34 automationFunction: function (audioparam, endValue, endTime) { | 34 automationFunction: function (audioparam, endValue, endTime) { |
| 35 audioparam.linearRampToValueAtTime(endValue, endTime); | 35 audioparam.linearRampToValueAtTime(endValue, endTime); |
| 36 }, | 36 }, |
| 37 referenceFunction: linearResult, | 37 referenceFunction: linearResult, |
| 38 automationTime: renderQuantum / sampleRate, | 38 automationTime: renderQuantum / sampleRate, |
| 39 thresholdSetTarget: 0, | 39 thresholdSetTarget: 0, |
| 40 thresholdRamp: 1.26765e-6 | 40 thresholdRamp: 1.26765e-6 |
| 41 }).then(done); | 41 }).then(() => task.done()); |
| 42 }); | 42 }); |
| 43 | 43 |
| 44 audit.defineTask("delayed linear ramp", function (done) { | 44 audit.define("delayed linear ramp", (task, should) => { |
| 45 // Schedule a linear ramp to start after the SetTargetAtTime has already
started rendering. | 45 // Schedule a linear ramp to start after the SetTargetAtTime has already
started rendering. |
| 46 // This is the main test to verify that the linear ramp is continuous wi
th the | 46 // This is the main test to verify that the linear ramp is continuous wi
th the |
| 47 // SetTargetAtTime curve. | 47 // SetTargetAtTime curve. |
| 48 runTest("Delayed linear ramp", { | 48 runTest(should, "Delayed linear ramp", { |
| 49 automationFunction: function (audioparam, endValue, endTime) { | 49 automationFunction: function (audioparam, endValue, endTime) { |
| 50 audioparam.linearRampToValueAtTime(endValue, endTime); | 50 audioparam.linearRampToValueAtTime(endValue, endTime); |
| 51 }, | 51 }, |
| 52 referenceFunction: linearResult, | 52 referenceFunction: linearResult, |
| 53 automationTime: 4 * renderQuantum / sampleRate, | 53 automationTime: 4 * renderQuantum / sampleRate, |
| 54 thresholdSetTarget: 3.43632e-7, | 54 thresholdSetTarget: 3.43632e-7, |
| 55 thresholdRamp: 1.07972e-6 | 55 thresholdRamp: 1.07972e-6 |
| 56 }).then(done); | 56 }).then(() => task.done()); |
| 57 }); | 57 }); |
| 58 | 58 |
| 59 audit.defineTask("expo ramp replace", function (done) { | 59 audit.define("expo ramp replace", (task, should) => { |
| 60 // Like "linear ramp replace", but with an exponential ramp instead. | 60 // Like "linear ramp replace", but with an exponential ramp instead. |
| 61 runTest("Exponential ramp", { | 61 runTest(should, "Exponential ramp", { |
| 62 automationFunction: function (audioparam, endValue, endTime) { | 62 automationFunction: function (audioparam, endValue, endTime) { |
| 63 audioparam.exponentialRampToValueAtTime(endValue, endTime); | 63 audioparam.exponentialRampToValueAtTime(endValue, endTime); |
| 64 }, | 64 }, |
| 65 referenceFunction: exponentialResult, | 65 referenceFunction: exponentialResult, |
| 66 automationTime: renderQuantum / sampleRate, | 66 automationTime: renderQuantum / sampleRate, |
| 67 thresholdSetTarget: 0, | 67 thresholdSetTarget: 0, |
| 68 thresholdRamp: 1.14441e-5 | 68 thresholdRamp: 1.14441e-5 |
| 69 }).then(done); | 69 }).then(() => task.done()); |
| 70 }); | 70 }); |
| 71 | 71 |
| 72 audit.defineTask("delayed expo ramp", function (done) { | 72 audit.define("delayed expo ramp", (task, should) => { |
| 73 // Like "delayed linear ramp", but with an exponential ramp instead. | 73 // Like "delayed linear ramp", but with an exponential ramp instead. |
| 74 runTest("Delayed exponential ramp", { | 74 runTest(should, "Delayed exponential ramp", { |
| 75 automationFunction: function (audioparam, endValue, endTime) { | 75 automationFunction: function (audioparam, endValue, endTime) { |
| 76 audioparam.exponentialRampToValueAtTime(endValue, endTime); | 76 audioparam.exponentialRampToValueAtTime(endValue, endTime); |
| 77 }, | 77 }, |
| 78 referenceFunction: exponentialResult, | 78 referenceFunction: exponentialResult, |
| 79 automationTime: 4 * renderQuantum / sampleRate, | 79 automationTime: 4 * renderQuantum / sampleRate, |
| 80 thresholdSetTarget: 3.43632e-7, | 80 thresholdSetTarget: 3.43632e-7, |
| 81 thresholdRamp: 4.29154e-6 | 81 thresholdRamp: 4.29154e-6 |
| 82 }).then(done); | 82 }).then(() => task.done()); |
| 83 }); | 83 }); |
| 84 | 84 |
| 85 audit.defineTask("finish", function (done) { | 85 audit.run(); |
| 86 done(); | |
| 87 }); | |
| 88 | |
| 89 audit.runTasks(); | |
| 90 | 86 |
| 91 function computeExpectedResult(automationTime, timeConstant, endValue, end
Time, rampFunction) { | 87 function computeExpectedResult(automationTime, timeConstant, endValue, end
Time, rampFunction) { |
| 92 // The result is a constant value of 1 for one rendering quantum, then a
SetTarget event | 88 // The result is a constant value of 1 for one rendering quantum, then a
SetTarget event |
| 93 // lasting to |automationTime|, at which point a ramp starts which ends
at |endValue| | 89 // lasting to |automationTime|, at which point a ramp starts which ends
at |endValue| |
| 94 // at |endTime|. Then the rest of curve should be held constant at |end
Value|. | 90 // at |endTime|. Then the rest of curve should be held constant at |end
Value|. |
| 95 var initialPart = new Array(renderQuantum); | 91 var initialPart = new Array(renderQuantum); |
| 96 initialPart.fill(1); | 92 initialPart.fill(1); |
| 97 | 93 |
| 98 // Generate 1 extra frame so that we know where to start the linear ramp
. The last sample | 94 // Generate 1 extra frame so that we know where to start the linear ramp
. The last sample |
| 99 // of the array is where the ramp should start from. | 95 // of the array is where the ramp should start from. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 // timeConstant - time constant used for SetTargetAtTime | 139 // timeConstant - time constant used for SetTargetAtTime |
| 144 // rampEndValue - end value for the ramp (same value used for auto
mationFunction) | 140 // rampEndValue - end value for the ramp (same value used for auto
mationFunction) |
| 145 // rampEndTime - end time for the ramp (same value used for autom
ationFunction) | 141 // rampEndTime - end time for the ramp (same value used for autom
ationFunction) |
| 146 // |options.automationTime| | 142 // |options.automationTime| |
| 147 // Time at which the |automationFunction| is called to start the autom
ation. | 143 // Time at which the |automationFunction| is called to start the autom
ation. |
| 148 // |options.thresholdSetTarget| | 144 // |options.thresholdSetTarget| |
| 149 // Threshold to use for verifying that the initial (if any) SetTargetA
tTime portion had | 145 // Threshold to use for verifying that the initial (if any) SetTargetA
tTime portion had |
| 150 // the correct values. | 146 // the correct values. |
| 151 // |options.thresholdRamp| | 147 // |options.thresholdRamp| |
| 152 // Threshold to use for verifying that the ramp portion had the correc
t values. | 148 // Threshold to use for verifying that the ramp portion had the correc
t values. |
| 153 function runTest(prefix, options) { | 149 function runTest(should, prefix, options) { |
| 154 var automationFunction = options.automationFunction; | 150 var automationFunction = options.automationFunction; |
| 155 var referenceFunction = options.referenceFunction; | 151 var referenceFunction = options.referenceFunction; |
| 156 var automationTime = options.automationTime; | 152 var automationTime = options.automationTime; |
| 157 var thresholdSetTarget = options.thresholdSetTarget || 0; | 153 var thresholdSetTarget = options.thresholdSetTarget || 0; |
| 158 var thresholdRamp = options.thresholdRamp || 0; | 154 var thresholdRamp = options.thresholdRamp || 0; |
| 159 | 155 |
| 160 // End value for the ramp. Fairly arbitrary, but should be distinctly d
ifferent from the | 156 // End value for the ramp. Fairly arbitrary, but should be distinctly d
ifferent from the |
| 161 // target value for SetTargetAtTime and the initial value of gain.gain. | 157 // target value for SetTargetAtTime and the initial value of gain.gain. |
| 162 var rampEndValue = 2; | 158 var rampEndValue = 2; |
| 163 var context = new OfflineAudioContext(1, renderFrames, sampleRate); | 159 var context = new OfflineAudioContext(1, renderFrames, sampleRate); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 189 return context.startRendering().then(function (resultBuffer) { | 185 return context.startRendering().then(function (resultBuffer) { |
| 190 var success = true; | 186 var success = true; |
| 191 var result = resultBuffer.getChannelData(0); | 187 var result = resultBuffer.getChannelData(0); |
| 192 var expected = referenceFunction(automationTime, timeConstant, rampEnd
Value, rampEndTime); | 188 var expected = referenceFunction(automationTime, timeConstant, rampEnd
Value, rampEndTime); |
| 193 | 189 |
| 194 // Verify each part of the curve separately. | 190 // Verify each part of the curve separately. |
| 195 var startIndex = 0; | 191 var startIndex = 0; |
| 196 var length = expected.initialPart.length; | 192 var length = expected.initialPart.length; |
| 197 | 193 |
| 198 // Verify that the initial part of the curve is constant. | 194 // Verify that the initial part of the curve is constant. |
| 199 success = Should(prefix + ": Initial part", result.slice(0, length)) | 195 should(result.slice(0, length), prefix + ": Initial part") |
| 200 .beCloseToArray(expected.initialPart, 0) && success; | 196 .beCloseToArray(expected.initialPart); |
| 201 | 197 |
| 202 // Verify the SetTarget part of the curve, if the SetTarget did actual
ly run. | 198 // Verify the SetTarget part of the curve, if the SetTarget did actual
ly run. |
| 203 startIndex += length; | 199 startIndex += length; |
| 204 length = expected.setTargetPart.length; | 200 length = expected.setTargetPart.length; |
| 205 if (length) { | 201 if (length) { |
| 206 success = Should(prefix + ": SetTarget part", result.slice(startInde
x, startIndex + | 202 should(result.slice(startIndex, startIndex + length), |
| 207 length)) | 203 prefix + ": SetTarget part") |
| 208 .beCloseToArray(expected.setTargetPart, thresholdSetTarget) && suc
cess; | 204 .beCloseToArray(expected.setTargetPart, { |
| 205 absoluteThreshold: thresholdSetTarget |
| 206 }); |
| 209 } else { | 207 } else { |
| 210 Should(prefix + ": SetTarget part", !length) | 208 should(!length, prefix + ": SetTarget part") |
| 211 .summarize("was correctly replaced by the ramp", | 209 .message("was correctly replaced by the ramp", |
| 212 "was incorrectly replaced by the ramp"); | 210 "was incorrectly replaced by the ramp"); |
| 213 } | 211 } |
| 214 | 212 |
| 215 // Verify the ramp part of the curve | 213 // Verify the ramp part of the curve |
| 216 startIndex += length; | 214 startIndex += length; |
| 217 length = expected.rampPart.length; | 215 length = expected.rampPart.length; |
| 218 success = Should(prefix, result.slice(startIndex, startIndex + length)
) | 216 should(result.slice(startIndex, startIndex + length), prefix) |
| 219 .beCloseToArray(expected.rampPart, thresholdRamp) && success; | 217 .beCloseToArray(expected.rampPart, { |
| 218 absoluteThreshold: thresholdRamp |
| 219 }); |
| 220 | 220 |
| 221 // Verify that the end of the curve after the ramp (if any) is a const
ant. | 221 // Verify that the end of the curve after the ramp (if any) is a const
ant. |
| 222 startIndex += length; | 222 startIndex += length; |
| 223 success = Should(prefix + ": Tail part", result.slice(startIndex)) | 223 should(result.slice(startIndex), prefix + ": Tail part") |
| 224 .beCloseToArray(expected.tailPart, 0) && success; | 224 .beCloseToArray(expected.tailPart); |
| 225 | 225 |
| 226 Should(prefix, success) | |
| 227 .summarize("preceded by SetTarget is continuous", | |
| 228 "preceded by SetTarget was not continuous"); | |
| 229 }); | 226 }); |
| 230 } | 227 } |
| 231 </script> | 228 </script> |
| 232 </body> | 229 </body> |
| 233 </html> | 230 </html> |
| OLD | NEW |