| OLD | NEW |
| 1 <!doctype html> | 1 <!DOCTYPE html> |
| 2 <html> | 2 <html> |
| 3 <head> | 3 <head> |
| 4 <title>Test Interpolation for AudioParam.setValueCurveAtTime</title> | 4 <title> |
| 5 Test Interpolation for AudioParam.setValueCurveAtTime |
| 6 </title> |
| 5 <script src="../../resources/testharness.js"></script> | 7 <script src="../../resources/testharness.js"></script> |
| 6 <script src="../../resources/testharnessreport.js"></script> | 8 <script src="../../resources/testharnessreport.js"></script> |
| 7 <script src="../resources/audit-util.js"></script> | 9 <script src="../resources/audit-util.js"></script> |
| 8 <script src="../resources/audit.js"></script> | 10 <script src="../resources/audit.js"></script> |
| 9 <title>Test Interpolation for AudioParam.setValueCurveAtTime</title> | 11 <title> |
| 12 Test Interpolation for AudioParam.setValueCurveAtTime |
| 13 </title> |
| 10 </head> | 14 </head> |
| 15 <body> |
| 16 <script id="layout-test-code"> |
| 17 // Play a constant signal through a gain node that is automated using |
| 18 // setValueCurveAtTime with a 2-element curve. The output should be a |
| 19 // linear change. |
| 11 | 20 |
| 12 <body> | 21 // Choose a sample rate that is a multiple of 128, the rendering quantum |
| 13 <script> | 22 // size. This makes the math work out to be nice numbers. |
| 23 let sampleRate = 25600; |
| 24 let testDurationSec = 1; |
| 25 let testDurationFrames = testDurationSec * sampleRate; |
| 14 | 26 |
| 15 // Play a constant signal through a gain node that is automated using setV
alueCurveAtTime with | 27 // Where the curve starts and its duration. This MUST be less than the |
| 16 // a 2-element curve. The output should be a linear change. | 28 // total rendering time. |
| 29 let curveStartTime = 256 / sampleRate; |
| 30 let curveDuration = 300 / sampleRate; |
| 31 ; |
| 32 let curveValue = 0.75; |
| 17 | 33 |
| 18 // Choose a sample rate that is a multiple of 128, the rendering quantum s
ize. This makes the | 34 // At this time, the gain node goes to gain 1. This is used to make sure |
| 19 // math work out to be nice numbers. | 35 // the value curve is propagated correctly until the next event. |
| 20 var sampleRate = 25600; | 36 let fullGainTime = 0.75; |
| 21 var testDurationSec = 1; | |
| 22 var testDurationFrames = testDurationSec * sampleRate; | |
| 23 | 37 |
| 24 // Where the curve starts and its duration. This MUST be less than the to
tal rendering time. | 38 // Thresholds use to determine if the test passes; these are |
| 25 var curveStartTime = 256 / sampleRate; | 39 // experimentally determined. The SNR between the actual and expected |
| 26 var curveDuration = 300 / sampleRate;; | 40 // result should be at least |snrThreshold|. The maximum difference |
| 27 var curveValue = 0.75; | 41 // betwen them should not exceed |maxErrorThreshold|. |
| 42 let snrThreshold = 10000; |
| 43 let maxErrorThreshold = 0; |
| 28 | 44 |
| 29 // At this time, the gain node goes to gain 1. This is used to make sure
the value curve is | 45 let context; |
| 30 // propagated correctly until the next event. | 46 let actualResult; |
| 31 var fullGainTime = 0.75; | 47 let expectedResult; |
| 32 | |
| 33 // Thresholds use to determine if the test passes; these are experimentall
y determined. The | |
| 34 // SNR between the actual and expected result should be at least |snrThres
hold|. The maximum | |
| 35 // difference betwen them should not exceed |maxErrorThreshold|. | |
| 36 var snrThreshold = 10000; | |
| 37 var maxErrorThreshold = 0; | |
| 38 | 48 |
| 39 var context; | 49 let audit = Audit.createTaskRunner(); |
| 40 var actualResult; | |
| 41 var expectedResult; | |
| 42 | 50 |
| 43 var audit = Audit.createTaskRunner(); | 51 // Array of test configs. Each config must specify curveStartTime, |
| 52 // curveDuration, curveLength, fullGainTime, maxErrorThreshold, and |
| 53 // snrThreshold. |
| 54 let testConfigs = [ |
| 55 { |
| 56 // The main test |
| 57 curveStartTime: 256 / sampleRate, |
| 58 curveDuration: 300 / sampleRate, |
| 59 curveLength: 2, |
| 60 fullGainTime: 0.75, |
| 61 maxErrorThreshold: 5.9605e-8, |
| 62 snrThreshold: 171.206 |
| 63 }, |
| 64 { |
| 65 // Increase the curve length |
| 66 curveStartTime: 256 / sampleRate, |
| 67 curveDuration: 300 / sampleRate, |
| 68 curveLength: 3, |
| 69 fullGainTime: 0.75, |
| 70 maxErrorThreshold: 5.9605e-8, |
| 71 snrThreshold: 171.206 |
| 72 }, |
| 73 { |
| 74 // Increase the curve length |
| 75 curveStartTime: 256 / sampleRate, |
| 76 curveDuration: 300 / sampleRate, |
| 77 curveLength: 16, |
| 78 fullGainTime: 0.75, |
| 79 maxErrorThreshold: 5.9605e-8, |
| 80 snrThreshold: 170.892 |
| 81 }, |
| 82 { |
| 83 // Increase the curve length |
| 84 curveStartTime: 256 / sampleRate, |
| 85 curveDuration: 300 / sampleRate, |
| 86 curveLength: 100, |
| 87 fullGainTime: 0.75, |
| 88 maxErrorThreshold: 1.1921e-7, |
| 89 snrThreshold: 168.712 |
| 90 }, |
| 91 { |
| 92 // Corner case with duration less than a frame! |
| 93 curveStartTime: 256 / sampleRate, |
| 94 curveDuration: 0.25 / sampleRate, |
| 95 curveLength: 2, |
| 96 fullGainTime: 0.75, |
| 97 maxErrorThreshold: 0, |
| 98 snrThreshold: 10000 |
| 99 }, |
| 100 { |
| 101 // Short duration test |
| 102 curveStartTime: 256 / sampleRate, |
| 103 curveDuration: 2 / sampleRate, |
| 104 curveLength: 2, |
| 105 fullGainTime: 0.75, |
| 106 maxErrorThreshold: 0, |
| 107 snrThreshold: 10000 |
| 108 }, |
| 109 { |
| 110 // Short duration test with many points. |
| 111 curveStartTime: 256 / sampleRate, |
| 112 curveDuration: 2 / sampleRate, |
| 113 curveLength: 8, |
| 114 fullGainTime: 0.75, |
| 115 maxErrorThreshold: 0, |
| 116 snrThreshold: 10000 |
| 117 }, |
| 118 { |
| 119 // Long duration, big curve |
| 120 curveStartTime: 256 / sampleRate, |
| 121 curveDuration: .5, |
| 122 curveLength: 1000, |
| 123 fullGainTime: 0.75, |
| 124 maxErrorThreshold: 5.9605e-8, |
| 125 snrThreshold: 152.784 |
| 126 } |
| 127 ]; |
| 44 | 128 |
| 45 // Array of test configs. Each config must specify curveStartTime, curveD
uration, | 129 // Creates a function based on the test config that is suitable for use by |
| 46 // curveLength, fullGainTime, maxErrorThreshold, and snrThreshold. | 130 // defineTask(). |
| 47 var testConfigs = [{ | |
| 48 // The main test | |
| 49 curveStartTime: 256 / sampleRate, | |
| 50 curveDuration: 300 / sampleRate, | |
| 51 curveLength: 2, | |
| 52 fullGainTime: 0.75, | |
| 53 maxErrorThreshold: 5.9605e-8, | |
| 54 snrThreshold: 171.206 | |
| 55 }, { | |
| 56 // Increase the curve length | |
| 57 curveStartTime: 256 / sampleRate, | |
| 58 curveDuration: 300 / sampleRate, | |
| 59 curveLength: 3, | |
| 60 fullGainTime: 0.75, | |
| 61 maxErrorThreshold: 5.9605e-8, | |
| 62 snrThreshold: 171.206 | |
| 63 }, { | |
| 64 // Increase the curve length | |
| 65 curveStartTime: 256 / sampleRate, | |
| 66 curveDuration: 300 / sampleRate, | |
| 67 curveLength: 16, | |
| 68 fullGainTime: 0.75, | |
| 69 maxErrorThreshold: 5.9605e-8, | |
| 70 snrThreshold: 170.892 | |
| 71 }, { | |
| 72 // Increase the curve length | |
| 73 curveStartTime: 256 / sampleRate, | |
| 74 curveDuration: 300 / sampleRate, | |
| 75 curveLength: 100, | |
| 76 fullGainTime: 0.75, | |
| 77 maxErrorThreshold: 1.1921e-7, | |
| 78 snrThreshold: 168.712 | |
| 79 }, { | |
| 80 // Corner case with duration less than a frame! | |
| 81 curveStartTime: 256 / sampleRate, | |
| 82 curveDuration: 0.25 / sampleRate, | |
| 83 curveLength: 2, | |
| 84 fullGainTime: 0.75, | |
| 85 maxErrorThreshold: 0, | |
| 86 snrThreshold: 10000 | |
| 87 }, { | |
| 88 // Short duration test | |
| 89 curveStartTime: 256 / sampleRate, | |
| 90 curveDuration: 2 / sampleRate, | |
| 91 curveLength: 2, | |
| 92 fullGainTime: 0.75, | |
| 93 maxErrorThreshold: 0, | |
| 94 snrThreshold: 10000 | |
| 95 }, { | |
| 96 // Short duration test with many points. | |
| 97 curveStartTime: 256 / sampleRate, | |
| 98 curveDuration: 2 / sampleRate, | |
| 99 curveLength: 8, | |
| 100 fullGainTime: 0.75, | |
| 101 maxErrorThreshold: 0, | |
| 102 snrThreshold: 10000 | |
| 103 }, { | |
| 104 // Long duration, big curve | |
| 105 curveStartTime: 256 / sampleRate, | |
| 106 curveDuration: .5, | |
| 107 curveLength: 1000, | |
| 108 fullGainTime: 0.75, | |
| 109 maxErrorThreshold: 5.9605e-8, | |
| 110 snrThreshold: 152.784 | |
| 111 }]; | |
| 112 | |
| 113 // Creates a function based on the test config that is suitable for use by
defineTask(). | |
| 114 function createTaskFunction(config) { | 131 function createTaskFunction(config) { |
| 115 return function (task, should) { | 132 return function(task, should) { |
| 116 runTest(should, config).then(() => task.done()); | 133 runTest(should, config).then(() => task.done()); |
| 117 }; | 134 }; |
| 118 } | 135 } |
| 119 | 136 |
| 120 // Define a task for each config, in the order listed in testConfigs. | 137 // Define a task for each config, in the order listed in testConfigs. |
| 121 for (var k = 0; k < testConfigs.length; ++k) { | 138 for (let k = 0; k < testConfigs.length; ++k) { |
| 122 var config = testConfigs[k]; | 139 let config = testConfigs[k]; |
| 123 var name = k + ":curve=" + config.curveLength + ",duration=" + (config.c
urveDuration * sampleRate); | 140 let name = k + ':curve=' + config.curveLength + |
| 141 ',duration=' + (config.curveDuration * sampleRate); |
| 124 audit.define(name, createTaskFunction(config)); | 142 audit.define(name, createTaskFunction(config)); |
| 125 } | 143 } |
| 126 | 144 |
| 127 // Simple test from crbug.com/441471. Makes sure the end points and the m
iddle point are | 145 // Simple test from crbug.com/441471. Makes sure the end points and the |
| 128 // interpolated correctly. | 146 // middle point are interpolated correctly. |
| 129 audit.define("crbug-441471", (task, should) => { | 147 audit.define('crbug-441471', (task, should) => { |
| 130 // Any sample rate should work; we pick something small such that the ti
me end points are on | 148 // Any sample rate should work; we pick something small such that the |
| 131 // a sampling point. | 149 // time end points are on a sampling point. |
| 132 var context = new OfflineAudioContext(1, 5000, 5000) | 150 let context = new OfflineAudioContext(1, 5000, 5000) |
| 133 | 151 |
| 134 // A constant source | 152 // A constant source |
| 135 var source = context.createBufferSource(); | 153 let source = context.createBufferSource(); |
| 136 source.buffer = createConstantBuffer(context, 1, 1); | 154 source.buffer = createConstantBuffer(context, 1, 1); |
| 137 source.loop = true; | 155 source.loop = true; |
| 138 | 156 |
| 139 var gain = context.createGain(); | 157 let gain = context.createGain(); |
| 140 | 158 |
| 141 var startTime = 0.7; | 159 let startTime = 0.7; |
| 142 var duration = 0.2; | 160 let duration = 0.2; |
| 143 | |
| 144 // Create the curve. The interpolated result should be just a straight
line from -1 to 1 | |
| 145 // from time startTime to startTime + duration. | |
| 146 | 161 |
| 147 var c = new Float32Array(3); | 162 // Create the curve. The interpolated result should be just a straight |
| 163 // line from -1 to 1 from time startTime to startTime + duration. |
| 164 |
| 165 let c = new Float32Array(3); |
| 148 c[0] = -1; | 166 c[0] = -1; |
| 149 c[1] = 0; | 167 c[1] = 0; |
| 150 c[2] = 1; | 168 c[2] = 1; |
| 151 gain.gain.setValueCurveAtTime(c, startTime, duration); | 169 gain.gain.setValueCurveAtTime(c, startTime, duration); |
| 152 source.connect(gain); | 170 source.connect(gain); |
| 153 gain.connect(context.destination); | 171 gain.connect(context.destination); |
| 154 source.start(); | 172 source.start(); |
| 155 | 173 |
| 156 context.startRendering().then(function (renderedBuffer) { | 174 context.startRendering() |
| 157 var data = renderedBuffer.getChannelData(0); | 175 .then(function(renderedBuffer) { |
| 158 var endTime = startTime + duration; | 176 let data = renderedBuffer.getChannelData(0); |
| 159 var midPoint = (startTime + endTime) / 2; | 177 let endTime = startTime + duration; |
| 178 let midPoint = (startTime + endTime) / 2; |
| 160 | 179 |
| 161 should(data[timeToSampleFrame(startTime, context.sampleRate)], | 180 should( |
| 162 "Curve value at time " + startTime) | 181 data[timeToSampleFrame(startTime, context.sampleRate)], |
| 163 .beEqualTo(c[0]); | 182 'Curve value at time ' + startTime) |
| 164 // Due to round-off, the value at the midpoint is not exactly zero on
arm64. See | 183 .beEqualTo(c[0]); |
| 165 // crbug.com/558563. The current value is experimentally determined. | 184 // Due to round-off, the value at the midpoint is not exactly zero |
| 166 should(data[timeToSampleFrame(midPoint, context.sampleRate)], | 185 // on arm64. See crbug.com/558563. The current value is |
| 167 "Curve value at time " + midPoint) | 186 // experimentally determined. |
| 168 .beCloseTo(0, {threshold: Math.pow(2, -51)}); | 187 should( |
| 169 should(data[timeToSampleFrame(endTime, context.sampleRate)], | 188 data[timeToSampleFrame(midPoint, context.sampleRate)], |
| 170 "Curve value at time " + endTime) | 189 'Curve value at time ' + midPoint) |
| 171 .beEqualTo(c[2]); | 190 .beCloseTo(0, {threshold: Math.pow(2, -51)}); |
| 172 }).then(() => task.done()); | 191 should( |
| 192 data[timeToSampleFrame(endTime, context.sampleRate)], |
| 193 'Curve value at time ' + endTime) |
| 194 .beEqualTo(c[2]); |
| 195 }) |
| 196 .then(() => task.done()); |
| 173 }); | 197 }); |
| 174 | 198 |
| 175 function runTest(should, config) { | 199 function runTest(should, config) { |
| 176 context = new OfflineAudioContext(1, testDurationFrames, sampleRate); | 200 context = new OfflineAudioContext(1, testDurationFrames, sampleRate); |
| 177 | 201 |
| 178 // A constant audio source of value 1. | 202 // A constant audio source of value 1. |
| 179 var source = context.createBufferSource(); | 203 let source = context.createBufferSource(); |
| 180 source.buffer = createConstantBuffer(context, 1, 1); | 204 source.buffer = createConstantBuffer(context, 1, 1); |
| 181 source.loop = true; | 205 source.loop = true; |
| 182 | 206 |
| 183 // The value curve for testing. Just to make things easy for testing, m
ake the curve a | 207 // The value curve for testing. Just to make things easy for testing, |
| 184 // simple ramp up to curveValue. | 208 // make the curve a simple ramp up to curveValue. |
| 185 // TODO(rtoy): Maybe allow more complicated curves? | 209 // TODO(rtoy): Maybe allow more complicated curves? |
| 186 var curve = new Float32Array(config.curveLength); | 210 let curve = new Float32Array(config.curveLength); |
| 187 for (var k = 0; k < config.curveLength; ++k) { | 211 for (let k = 0; k < config.curveLength; ++k) { |
| 188 curve[k] = curveValue / (config.curveLength - 1) * k; | 212 curve[k] = curveValue / (config.curveLength - 1) * k; |
| 189 } | 213 } |
| 190 | 214 |
| 191 // A gain node that is to be automated using setValueCurveAtTime. | 215 // A gain node that is to be automated using setValueCurveAtTime. |
| 192 var gain = context.createGain(); | 216 let gain = context.createGain(); |
| 193 gain.gain.value = 0; | 217 gain.gain.value = 0; |
| 194 gain.gain.setValueCurveAtTime(curve, config.curveStartTime, config.curve
Duration); | 218 gain.gain.setValueCurveAtTime( |
| 219 curve, config.curveStartTime, config.curveDuration); |
| 195 // This is to verify that setValueCurveAtTime ends appropriately. | 220 // This is to verify that setValueCurveAtTime ends appropriately. |
| 196 gain.gain.setValueAtTime(1, config.fullGainTime); | 221 gain.gain.setValueAtTime(1, config.fullGainTime); |
| 197 | 222 |
| 198 source.connect(gain); | 223 source.connect(gain); |
| 199 gain.connect(context.destination); | 224 gain.connect(context.destination); |
| 200 source.start(); | 225 source.start(); |
| 201 | 226 |
| 202 // Some consistency checks on the test parameters | 227 // Some consistency checks on the test parameters |
| 203 let prefix = "Length " + config.curveLength + ", duration " + config.cur
veDuration; | 228 let prefix = 'Length ' + config.curveLength + ', duration ' + |
| 204 should(config.curveStartTime + config.curveDuration, | 229 config.curveDuration; |
| 205 prefix + ": Check: Curve end time") | 230 should( |
| 206 .beLessThanOrEqualTo(testDurationSec); | 231 config.curveStartTime + config.curveDuration, |
| 207 should(config.fullGainTime, prefix + ": Check: Full gain start time") | 232 prefix + ': Check: Curve end time') |
| 208 .beLessThanOrEqualTo(testDurationSec); | 233 .beLessThanOrEqualTo(testDurationSec); |
| 209 should(config.fullGainTime, | 234 should(config.fullGainTime, prefix + ': Check: Full gain start time') |
| 210 prefix + ": Check: Full gain start time") | 235 .beLessThanOrEqualTo(testDurationSec); |
| 211 .beGreaterThanOrEqualTo(config.curveStartTime + config.curveDuration); | 236 should(config.fullGainTime, prefix + ': Check: Full gain start time') |
| 237 .beGreaterThanOrEqualTo( |
| 238 config.curveStartTime + config.curveDuration); |
| 212 | 239 |
| 213 // Rock and roll! | 240 // Rock and roll! |
| 214 return context.startRendering().then(checkResult(should, config)); | 241 return context.startRendering().then(checkResult(should, config)); |
| 215 } | 242 } |
| 216 | 243 |
| 217 // Return a function to check that the rendered result matches the expecte
d result. | 244 // Return a function to check that the rendered result matches the |
| 245 // expected result. |
| 218 function checkResult(should, config) { | 246 function checkResult(should, config) { |
| 219 return function (renderedBuffer) { | 247 return function(renderedBuffer) { |
| 220 var success = true; | 248 let success = true; |
| 221 | 249 |
| 222 actualResult = renderedBuffer.getChannelData(0); | 250 actualResult = renderedBuffer.getChannelData(0); |
| 223 expectedResult = computeExpectedResult(config); | 251 expectedResult = computeExpectedResult(config); |
| 224 | 252 |
| 225 // Compute the SNR and max absolute difference between the actual and
expected result. | 253 // Compute the SNR and max absolute difference between the actual and |
| 226 var SNR = 10*Math.log10(computeSNR(actualResult, expectedResult)); | 254 // expected result. |
| 227 var maxDiff = -1; | 255 let SNR = 10 * Math.log10(computeSNR(actualResult, expectedResult)); |
| 228 var posn = -1; | 256 let maxDiff = -1; |
| 257 let posn = -1; |
| 229 | 258 |
| 230 for (var k = 0; k < actualResult.length; ++k) { | 259 for (let k = 0; k < actualResult.length; ++k) { |
| 231 var diff = Math.abs(actualResult[k] - expectedResult[k]); | 260 let diff = Math.abs(actualResult[k] - expectedResult[k]); |
| 232 if (maxDiff < diff) { | 261 if (maxDiff < diff) { |
| 233 maxDiff = diff; | 262 maxDiff = diff; |
| 234 posn = k; | 263 posn = k; |
| 235 } | 264 } |
| 236 } | 265 } |
| 237 | 266 |
| 238 let prefix = "Curve length " + config.curveLength + ", duration " + co
nfig.curveDuration; | 267 let prefix = 'Curve length ' + config.curveLength + ', duration ' + |
| 239 should(SNR, prefix + ": SNR") | 268 config.curveDuration; |
| 240 .beGreaterThanOrEqualTo(config.snrThreshold); | 269 should(SNR, prefix + ': SNR') |
| 270 .beGreaterThanOrEqualTo(config.snrThreshold); |
| 241 | 271 |
| 242 should(maxDiff, prefix + ": Max difference") | 272 should(maxDiff, prefix + ': Max difference') |
| 243 .beLessThanOrEqualTo(config.maxErrorThreshold); | 273 .beLessThanOrEqualTo(config.maxErrorThreshold); |
| 244 } | 274 } |
| 245 } | 275 } |
| 246 | 276 |
| 247 // Compute the expected result based on the config settings. | 277 // Compute the expected result based on the config settings. |
| 248 function computeExpectedResult(config) { | 278 function computeExpectedResult(config) { |
| 249 // The automation curve starts at |curveStartTime| and has duration |cu
rveDuration|. So, | 279 // The automation curve starts at |curveStartTime| and has duration |
| 250 // the output should be zero until curveStartTime, linearly ramp up fro
m there to | 280 // |curveDuration|. So, the output should be zero until curveStartTime, |
| 251 // |curveValue|, and then be constant 1 from then to the end of the buf
fer. | 281 // linearly ramp up from there to |curveValue|, and then be constant 1 |
| 282 // from then to the end of the buffer. |
| 252 | 283 |
| 253 var expected = new Float32Array(testDurationFrames); | 284 let expected = new Float32Array(testDurationFrames); |
| 254 | 285 |
| 255 var curveStartFrame = config.curveStartTime * sampleRate; | 286 let curveStartFrame = config.curveStartTime * sampleRate; |
| 256 var curveEndFrame = (config.curveStartTime + config.curveDuration) * sa
mpleRate; | 287 let curveEndFrame = |
| 257 var fullGainFrame = config.fullGainTime * sampleRate; | 288 (config.curveStartTime + config.curveDuration) * sampleRate; |
| 289 let fullGainFrame = config.fullGainTime * sampleRate; |
| 258 | 290 |
| 259 var k; | 291 let k; |
| 260 | 292 |
| 261 // Zero out the start. | 293 // Zero out the start. |
| 262 for (k = 0; k < curveStartFrame; ++k) | 294 for (k = 0; k < curveStartFrame; ++k) |
| 263 expected[k] = 0; | 295 expected[k] = 0; |
| 264 | 296 |
| 265 // Linearly ramp now. This assumes that the actual curve used is a lin
ear ramp, even if | 297 // Linearly ramp now. This assumes that the actual curve used is a |
| 266 // there are many curve points. | 298 // linear ramp, even if there are many curve points. |
| 267 var stepSize = curveValue / (config.curveDuration * sampleRate); | 299 let stepSize = curveValue / (config.curveDuration * sampleRate); |
| 268 for (; k < curveEndFrame; ++k) | 300 for (; k < curveEndFrame; ++k) |
| 269 expected[k] = stepSize * (k - curveStartFrame); | 301 expected[k] = stepSize * (k - curveStartFrame); |
| 270 | 302 |
| 271 // Hold it constant until the next event | 303 // Hold it constant until the next event |
| 272 for (; k < fullGainFrame; ++k) | 304 for (; k < fullGainFrame; ++k) |
| 273 expected[k] = curveValue; | 305 expected[k] = curveValue; |
| 274 | 306 |
| 275 // Amplitude is one for the rest of the test. | 307 // Amplitude is one for the rest of the test. |
| 276 for (; k < testDurationFrames; ++k) | 308 for (; k < testDurationFrames; ++k) |
| 277 expected[k] = 1; | 309 expected[k] = 1; |
| 278 | 310 |
| 279 return expected; | 311 return expected; |
| 280 } | 312 } |
| 281 | 313 |
| 282 audit.run(); | 314 audit.run(); |
| 283 </script> | 315 </script> |
| 284 </body> | 316 </body> |
| 285 </html> | 317 </html> |
| OLD | NEW |