| OLD | NEW |
| (Empty) |
| 1 <!doctype html> | |
| 2 <html> | |
| 3 | |
| 4 <head> | |
| 5 <script src="../resources/js-test.js"></script> | |
| 6 <script src="resources/compatibility.js"></script> | |
| 7 <script src="resources/audit-util.js"></script> | |
| 8 <script src="resources/audio-testing.js"></script> | |
| 9 <script src="resources/audioparam-testing.js"></script> | |
| 10 <title>AudioParam Initial Events </title> | |
| 11 </head> | |
| 12 | |
| 13 <body> | |
| 14 <script> | |
| 15 description("Test Automation Ramps without Initial Event"); | |
| 16 window.jsTestIsAsync = true; | |
| 17 | |
| 18 var sampleRate = 48000; | |
| 19 // Number of frames in a rendering quantum. | |
| 20 var quantumFrames = 128; | |
| 21 // Test doesn't need to run for very long. | |
| 22 var renderDuration = 0.2; | |
| 23 var renderFrames = renderDuration * sampleRate; | |
| 24 var automationEndTime = 0.1; | |
| 25 | |
| 26 var audit = Audit.createTaskRunner(); | |
| 27 | |
| 28 // The following tests start a ramp automation without an initial event. Th
is should cause an | |
| 29 // initial event to be added implicitly to give a starting point. | |
| 30 audit.defineTask("linear-ramp", function (done) { | |
| 31 runTest("Linear ramp", { | |
| 32 automationFunction: function (node, value, time) { | |
| 33 node.gain.linearRampToValueAtTime(value, time); | |
| 34 }, | |
| 35 referenceFunction: linearRamp, | |
| 36 // Experimentally determined threshold | |
| 37 threshold: 6.0003e-8, | |
| 38 // The starting value of the gain node | |
| 39 v0: 0.5, | |
| 40 // The target value of the automation | |
| 41 v1: 0, | |
| 42 }) | |
| 43 .then(done); | |
| 44 }); | |
| 45 | |
| 46 audit.defineTask("exponential-ramp", function (done) { | |
| 47 runTest("Exponential ramp", { | |
| 48 automationFunction: function (node, value, time) { | |
| 49 node.gain.exponentialRampToValueAtTime(value, time); | |
| 50 }, | |
| 51 referenceFunction: exponentialRamp, | |
| 52 threshold: 2.3842e-6, | |
| 53 v0: 0.5, | |
| 54 v1: 2, | |
| 55 }) | |
| 56 .then(done); | |
| 57 }); | |
| 58 | |
| 59 // Same tests as above, but we delay the call to the automation function. Th
is is to verify that | |
| 60 // the we still do the right thing after the context has started. | |
| 61 audit.defineTask("delayed-linear-ramp", function (done) { | |
| 62 runTest("Delayed linear ramp", { | |
| 63 automationFunction: function (node, value, time) { | |
| 64 node.gain.linearRampToValueAtTime(value, time); | |
| 65 }, | |
| 66 referenceFunction: linearRamp, | |
| 67 // Experimentally determined threshold | |
| 68 threshold: 9.87968e-8, | |
| 69 // The starting value of the gain node | |
| 70 v0: 0.5, | |
| 71 // The target value of the automation | |
| 72 v1: 0, | |
| 73 delay: quantumFrames / sampleRate | |
| 74 }) | |
| 75 .then(done); | |
| 76 }); | |
| 77 | |
| 78 audit.defineTask("delayed-exponential-ramp", function (done) { | |
| 79 runTest("Delayed exponential ramp", { | |
| 80 automationFunction: function (node, value, time) { | |
| 81 node.gain.exponentialRampToValueAtTime(value, time); | |
| 82 }, | |
| 83 referenceFunction: exponentialRamp, | |
| 84 // Experimentally determined threshold | |
| 85 threshold: 1.3948e-5, | |
| 86 // The starting value of the gain node | |
| 87 v0: 0.5, | |
| 88 // The target value of the automation | |
| 89 v1: 2, | |
| 90 delay: quantumFrames / sampleRate | |
| 91 }) | |
| 92 .then(done); | |
| 93 }); | |
| 94 | |
| 95 audit.defineTask("finish", function (done) { | |
| 96 finishJSTest(); | |
| 97 done(); | |
| 98 }); | |
| 99 | |
| 100 audit.runTasks(); | |
| 101 | |
| 102 // Generate the expected waveform for a linear ramp starting from the value
|v0|, ramping to | |
| 103 // |v1| at time |endTime|. The time of |v0| is assumed to be 0. |nFrames|
is how many frames | |
| 104 // to generate. | |
| 105 function linearRamp(v0, v1, startTime, endTime, nFrames) { | |
| 106 var expected = createLinearRampArray(startTime, endTime, v0, v1, sampleRat
e); | |
| 107 var preFiller = new Array(Math.floor(startTime * sampleRate)); | |
| 108 var postFiller = new Array(nFrames - Math.ceil(endTime * sampleRate)); | |
| 109 preFiller.fill(v0); | |
| 110 return preFiller.concat(expected.concat(postFiller.fill(v1))); | |
| 111 } | |
| 112 | |
| 113 // Generate the expected waveform for an exponential ramp starting from the
value |v0|, | |
| 114 // ramping to |v1| at time |endTime|. The time of |v0| is assumed to be 0.
|nFrames| is how | |
| 115 // many frames to generate. | |
| 116 function exponentialRamp(v0, v1, startTime, endTime, nFrames) { | |
| 117 var expected = createExponentialRampArray(startTime, endTime, v0, v1, samp
leRate); | |
| 118 var preFiller = new Array(Math.floor(startTime * sampleRate)); | |
| 119 preFiller.fill(v0); | |
| 120 var postFiller = new Array(nFrames - Math.ceil(endTime * sampleRate)); | |
| 121 return preFiller.concat(expected.concat(postFiller.fill(v1))); | |
| 122 } | |
| 123 | |
| 124 // Run an automation test. |message| is the message to use for printing the
results. |options| | |
| 125 // is a property bag containing the configuration of the test including the
following: | |
| 126 // | |
| 127 // automationFunction - automation function to use, | |
| 128 // referenceFunction - function generating the expected result | |
| 129 // threshold - comparison threshold | |
| 130 // v0 - starting value | |
| 131 // v1 - end value for automation | |
| 132 function runTest(message, options) { | |
| 133 var automationFunction = options.automationFunction; | |
| 134 var referenceFunction = options.referenceFunction; | |
| 135 var threshold = options.threshold; | |
| 136 var v0 = options.v0; | |
| 137 var v1 = options.v1; | |
| 138 var delay = options.delay; | |
| 139 | |
| 140 var context = new OfflineAudioContext(1, renderFrames, sampleRate); | |
| 141 | |
| 142 // A constant source of amplitude 1. | |
| 143 var source = context.createBufferSource(); | |
| 144 source.buffer = createConstantBuffer(context, 1, 1); | |
| 145 source.loop = true; | |
| 146 | |
| 147 // Automation is applied to a gain node | |
| 148 var gain = context.createGain(); | |
| 149 gain.gain.value = v0; | |
| 150 | |
| 151 // Delay start of automation, if requested | |
| 152 if (delay) { | |
| 153 context.suspend(options.delay).then(function () { | |
| 154 automationFunction(gain, v1, automationEndTime); | |
| 155 context.resume(); | |
| 156 }); | |
| 157 } else { | |
| 158 automationFunction(gain, v1, automationEndTime); | |
| 159 } | |
| 160 | |
| 161 source.connect(gain); | |
| 162 gain.connect(context.destination); | |
| 163 | |
| 164 source.start(); | |
| 165 | |
| 166 return context.startRendering() | |
| 167 .then(function (resultBuffer) { | |
| 168 var result = resultBuffer.getChannelData(0); | |
| 169 var expected = referenceFunction(v0, v1, delay ? delay : 0, automation
EndTime, renderFrames); | |
| 170 Should(message, result).beCloseToArray(expected, threshold); | |
| 171 }); | |
| 172 } | |
| 173 </script> | |
| 174 </body> | |
| 175 | |
| 176 </html> | |
| OLD | NEW |