| 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/audio-param.js"></script> | 8 <script src="../resources/audio-param.js"></script> |
| 9 <title>Updating of Value Attribute from Timeline</title> | 9 <title>Updating of Value Attribute from Timeline</title> |
| 10 </head> | 10 </head> |
| 11 | 11 |
| 12 <body> | 12 <body> |
| 13 <script> | 13 <script> |
| 14 | 14 |
| 15 // This should be a power of two so that all time computations have no rou
nd-off errors. | 15 // This should be a power of two so that all time computations have no rou
nd-off errors. |
| 16 var sampleRate = 32768; | 16 var sampleRate = 32768; |
| 17 var renderQuantumSize = 128; | 17 var renderQuantumSize = 128; |
| 18 // How many tests to run. | 18 // How many tests to run. |
| 19 var renderLoops = 20; | 19 var renderLoops = 20; |
| 20 var renderFrames = renderLoops * renderQuantumSize; | 20 var renderFrames = renderLoops * renderQuantumSize; |
| 21 var renderDuration = renderFrames / sampleRate; | 21 var renderDuration = renderFrames / sampleRate; |
| 22 | 22 |
| 23 var audit = Audit.createTaskRunner(); | 23 var audit = Audit.createTaskRunner(); |
| 24 | 24 |
| 25 audit.defineTask("linear", function (done) { | 25 audit.define("linear", (task, should) => { |
| 26 // Test the value attribute from a linearRamp event | 26 // Test the value attribute from a linearRamp event |
| 27 runTest(function (g, v0, t0, v1, t1) { | 27 runTest(should, function (g, v0, t0, v1, t1) { |
| 28 g.gain.linearRampToValueAtTime(v1, t1); | 28 g.gain.linearRampToValueAtTime(v1, t1); |
| 29 return { | 29 return { |
| 30 expectedValue: function (testTime) { | 30 expectedValue: function (testTime) { |
| 31 return audioParamLinearRamp(testTime, v0, t0, v1, t1); | 31 return audioParamLinearRamp(testTime, v0, t0, v1, t1); |
| 32 }, | 32 }, |
| 33 message: "linearRamp(" + v1 + ", " + t1 + ")", | 33 message: "linearRamp(" + v1 + ", " + t1 + ")", |
| 34 errorThreshold: 1.1650e-6 | 34 errorThreshold: 1.1650e-6 |
| 35 }; | 35 }; |
| 36 }).then(done); | 36 }).then(done); |
| 37 }); | 37 }); |
| 38 | 38 |
| 39 audit.defineTask("exponential", function (done) { | 39 audit.define("exponential", (task, should) => { |
| 40 // Test the value attribute from an exponentialRamp event | 40 // Test the value attribute from an exponentialRamp event |
| 41 runTest(function (g, v0, t0, v1, t1) { | 41 runTest(should, function (g, v0, t0, v1, t1) { |
| 42 g.gain.exponentialRampToValueAtTime(v1, t1); | 42 g.gain.exponentialRampToValueAtTime(v1, t1); |
| 43 return { | 43 return { |
| 44 expectedValue: function (testTime) { | 44 expectedValue: function (testTime) { |
| 45 return audioParamExponentialRamp(testTime, v0, t0, v1, t1); | 45 return audioParamExponentialRamp(testTime, v0, t0, v1, t1); |
| 46 }, | 46 }, |
| 47 message: "exponentialRamp(" + v1 + ", " + t1 + ")", | 47 message: "exponentialRamp(" + v1 + ", " + t1 + ")", |
| 48 errorThreshold: 7.4601e-7 | 48 errorThreshold: 7.4601e-7 |
| 49 }; | 49 }; |
| 50 }).then(done); | 50 }).then(done); |
| 51 }); | 51 }); |
| 52 | 52 |
| 53 audit.defineTask("setTarget", function (done) { | 53 audit.define("setTarget", (task, should) => { |
| 54 // Test the value attribute from a setTargetAtTime event | 54 // Test the value attribute from a setTargetAtTime event |
| 55 runTest(function (g, v0, t0, v1, t1) { | 55 runTest(should, function (g, v0, t0, v1, t1) { |
| 56 var timeConstant = 0.1; | 56 var timeConstant = 0.1; |
| 57 var vFinal = 0; | 57 var vFinal = 0; |
| 58 g.gain.setTargetAtTime(vFinal, t0, timeConstant); | 58 g.gain.setTargetAtTime(vFinal, t0, timeConstant); |
| 59 return { | 59 return { |
| 60 expectedValue: function (testTime) { | 60 expectedValue: function (testTime) { |
| 61 return audioParamSetTarget(testTime, v0, t0, vFinal, timeConstant)
; | 61 return audioParamSetTarget(testTime, v0, t0, vFinal, timeConstant)
; |
| 62 }, | 62 }, |
| 63 message: "setTargetAtTime(" + vFinal + ", " + t0 + ", " + timeConsta
nt + ")", | 63 message: "setTargetAtTime(" + vFinal + ", " + t0 + ", " + timeConsta
nt + ")", |
| 64 errorThreshold: 2.2599e-6 | 64 errorThreshold: 2.2599e-6 |
| 65 }; | 65 }; |
| 66 }).then(done); | 66 }).then(done); |
| 67 }); | 67 }); |
| 68 | 68 |
| 69 audit.defineTask("setValueCurve", function (done) { | 69 audit.define("setValueCurve", (task, should) => { |
| 70 // Test the value attribute from a setValueCurve event | 70 // Test the value attribute from a setValueCurve event |
| 71 runTest(function (g, v0, t0, v1, t1) { | 71 runTest(should, function (g, v0, t0, v1, t1) { |
| 72 var curve = [1, 1.5, 4]; | 72 var curve = [1, 1.5, 4]; |
| 73 var duration = t1 - t0; | 73 var duration = t1 - t0; |
| 74 g.gain.setValueCurveAtTime(Float32Array.from(curve), t0, duration); | 74 g.gain.setValueCurveAtTime(Float32Array.from(curve), t0, duration); |
| 75 return { | 75 return { |
| 76 expectedValue: function (testTime) { | 76 expectedValue: function (testTime) { |
| 77 return audioParamSetValueCurve(testTime, curve, t0, duration); | 77 return audioParamSetValueCurve(testTime, curve, t0, duration); |
| 78 }, | 78 }, |
| 79 message: "setValueCurveAtTime([" + curve + "], " + t0 + ", " + durat
ion + ")", | 79 message: "setValueCurveAtTime([" + curve + "], " + t0 + ", " + durat
ion + ")", |
| 80 errorThreshold: 7.9577e-8 | 80 errorThreshold: 7.9577e-8 |
| 81 }; | 81 }; |
| 82 }).then(done); | 82 }).then(done); |
| 83 }); | 83 }); |
| 84 | 84 |
| 85 audit.defineTask("finish", function (done) { | 85 audit.run(); |
| 86 done(); | |
| 87 }); | |
| 88 | |
| 89 audit.runTasks(); | |
| 90 | 86 |
| 91 // Test that the .value getter has the correct value when a timeline is ru
nning. | 87 // Test that the .value getter has the correct value when a timeline is ru
nning. |
| 92 // The |testFunction| is the underlying test to be run. | 88 // The |testFunction| is the underlying test to be run. |
| 93 function runTest(testFunction) { | 89 function runTest(should, testFunction) { |
| 94 // Create a simple graph consisting of a constant source and a gain node
where the | 90 // Create a simple graph consisting of a constant source and a gain node
where the |
| 95 // automations are run. A setValueAtTime event starts things off. | 91 // automations are run. A setValueAtTime event starts things off. |
| 96 var context = new OfflineAudioContext(1, renderFrames, sampleRate); | 92 var context = new OfflineAudioContext(1, renderFrames, sampleRate); |
| 97 var source = context.createBufferSource(); | 93 var source = context.createBufferSource(); |
| 98 source.buffer = createConstantBuffer(context, 1, 1); | 94 source.buffer = createConstantBuffer(context, 1, 1); |
| 99 source.loop = true; | 95 source.loop = true; |
| 100 var gain = context.createGain(); | 96 var gain = context.createGain(); |
| 101 | 97 |
| 102 source.connect(gain); | 98 source.connect(gain); |
| 103 gain.connect(context.destination); | 99 gain.connect(context.destination); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 116 // Run the desired automation test. The test function returns a diction
ary consisting of | 112 // Run the desired automation test. The test function returns a diction
ary consisting of |
| 117 // the following properties: | 113 // the following properties: |
| 118 // | 114 // |
| 119 // |message| an informative message about the automation being te
sted. | 115 // |message| an informative message about the automation being te
sted. |
| 120 // |errorThreshold| error threshold to determine if the test passes or n
ot. | 116 // |errorThreshold| error threshold to determine if the test passes or n
ot. |
| 121 // |expectedValue| a function that compute the expected value at time |
t|. | 117 // |expectedValue| a function that compute the expected value at time |
t|. |
| 122 var test = testFunction(gain, v0, t0, v1, t1); | 118 var test = testFunction(gain, v0, t0, v1, t1); |
| 123 | 119 |
| 124 // Print an informative message about the test being run. | 120 // Print an informative message about the test being run. |
| 125 //testPassed("Initialize " + test.message + " with setValueAtTime(" + v0
+ ", " + t0 + ")."); | 121 //testPassed("Initialize " + test.message + " with setValueAtTime(" + v0
+ ", " + t0 + ")."); |
| 126 Should("Initialize", true) | 122 should(true, "Initialize") |
| 127 .summarize(test.message + " with setValueAtTime(" + v0 + ", " + t0 + "
)", | 123 .message(test.message + " with setValueAtTime(" + v0 + ", " + t0 + ")"
, |
| 128 ""); | 124 ""); |
| 129 | 125 |
| 130 var success = true; | 126 var success = true; |
| 131 | 127 |
| 132 // Max relative error found for this test. This is printed if the test f
ails so that setting | 128 // Max relative error found for this test. This is printed if the test f
ails so that setting |
| 133 // the thresholds is easier. | 129 // the thresholds is easier. |
| 134 var maxError = 0; | 130 var maxError = 0; |
| 135 | 131 |
| 136 // For every rendering quantum (except the first), suspend the context s
o the we can inspect | 132 // For every rendering quantum (except the first), suspend the context s
o the we can inspect |
| 137 // the value attribute and compare it with the expected value. | 133 // the value attribute and compare it with the expected value. |
| 138 for (var k = 1; k < renderLoops; ++k) { | 134 for (var k = 1; k < renderLoops; ++k) { |
| 139 var time = k * renderQuantumSize / sampleRate; | 135 var time = k * renderQuantumSize / sampleRate; |
| 140 context.suspend(time).then(function () { | 136 context.suspend(time).then(function () { |
| 141 // The context is supsended at time |time|, which is just before the
rendering quantum | 137 // The context is supsended at time |time|, which is just before the
rendering quantum |
| 142 // starts. Thus, the value of the attribute is actually 1 frame bef
ore the current | 138 // starts. Thus, the value of the attribute is actually 1 frame bef
ore the current |
| 143 // context time. | 139 // context time. |
| 144 var sampleTime = context.currentTime - 1 / sampleRate; | 140 var sampleTime = context.currentTime - 1 / sampleRate; |
| 145 | 141 |
| 146 // Compute the max relative error | 142 // Compute the max relative error |
| 147 var expected = test.expectedValue(sampleTime); | 143 var expected = test.expectedValue(sampleTime); |
| 148 var relError = Math.abs(expected - gain.gain.value) / Math.abs(expec
ted); | 144 var relError = Math.abs(expected - gain.gain.value) / Math.abs(expec
ted); |
| 149 maxError = Math.max(relError, maxError); | 145 maxError = Math.max(relError, maxError); |
| 150 | 146 |
| 151 success = Should(test.message + " at frame " + (sampleRate * sampleT
ime), | 147 success = should(gain.gain.value, test.message + " at frame " + (sam
pleRate * sampleTime)) |
| 152 gain.gain.value, { | 148 .beCloseTo(expected, {threshold: test.errorThreshold || 0}); |
| 153 precision: 7 | |
| 154 }) | |
| 155 .beCloseTo(expected, test.errorThreshold || 0) && success; | |
| 156 }).then(context.resume.bind(context)); | 149 }).then(context.resume.bind(context)); |
| 157 } | 150 } |
| 158 | 151 |
| 159 source.start(); | 152 source.start(); |
| 160 | 153 |
| 161 return context.startRendering().then(function (resultBuffer) { | 154 return context.startRendering().then(function (resultBuffer) { |
| 162 // Just print a final pass (or fail) message. | 155 // Just print a final pass (or fail) message. |
| 163 Should("Gain .value attribute for " + test.message, success) | 156 should(success, "Gain .value attribute for " + test.message) |
| 164 .summarize("correctly updated during automation", | 157 .message("correctly updated during automation", |
| 165 "not correctly updated during automation; max error = " +
maxError); | 158 "not correctly updated during automation; max error = " + m
axError); |
| 166 }); | 159 }); |
| 167 } | 160 } |
| 168 </script> | 161 </script> |
| 169 </body> | 162 </body> |
| 170 </html> | 163 </html> |
| OLD | NEW |