OLD | NEW |
---|---|
1 var sampleRate = 44100; | 1 var sampleRate = 44100; |
hongchan
2015/09/30 22:14:18
Not relevant to this CL, but this test can be sepa
Raymond Toy
2015/09/30 22:30:18
Sorry, I don't understand this comment. What test
hongchan
2015/09/30 22:47:59
First, this file is a bit bloated now. I thought w
Raymond Toy
2015/10/01 18:05:55
Ok. But I did remove createConstantBuffer in favo
| |
2 | 2 |
3 // Information about the starting/ending times and starting/ending values for ea ch time interval. | 3 // Information about the starting/ending times and starting/ending values for ea ch time interval. |
4 var timeValueInfo; | 4 var timeValueInfo; |
5 | 5 |
6 // The difference between starting values between each time interval. | 6 // The difference between starting values between each time interval. |
7 var startingValueDelta; | 7 var startingValueDelta; |
8 | 8 |
9 // For any automation function that has an end or target value, the end value is based the starting | 9 // For any automation function that has an end or target value, the end value is based the starting |
10 // value of the time interval. The starting value will be increased or decrease d by | 10 // value of the time interval. The starting value will be increased or decrease d by |
11 // |startEndValueChange|. We choose half of |startingValueDelta| so that the end ing value will be | 11 // |startEndValueChange|. We choose half of |startingValueDelta| so that the end ing value will be |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
53 { | 53 { |
54 var startFrame = timeToSampleFrame(startTime, sampleRate); | 54 var startFrame = timeToSampleFrame(startTime, sampleRate); |
55 var endFrame = timeToSampleFrame(endTime, sampleRate); | 55 var endFrame = timeToSampleFrame(endTime, sampleRate); |
56 var length = endFrame - startFrame; | 56 var length = endFrame - startFrame; |
57 | 57 |
58 var buffer = createConstantBuffer(context, value, length); | 58 var buffer = createConstantBuffer(context, value, length); |
59 | 59 |
60 return buffer.getChannelData(0); | 60 return buffer.getChannelData(0); |
61 } | 61 } |
62 | 62 |
63 function getStartEndFrames(startTime, endTime, sampleRate) | |
64 { | |
65 // Start frame is the ceiling of the start time because the ramp | |
66 // starts at or after the sample frame. End frame is the ceiling | |
67 // because it's the exclusive ending frame of the automation. | |
68 var startFrame = Math.ceil(startTime * sampleRate); | |
69 var endFrame = Math.ceil(endTime * sampleRate); | |
70 | |
71 return {startFrame: startFrame, endFrame: endFrame}; | |
72 } | |
73 | |
63 // Create a linear ramp starting at |startValue| and ending at |endValue|. The ramp starts at time | 74 // Create a linear ramp starting at |startValue| and ending at |endValue|. The ramp starts at time |
64 // |startTime| and ends at |endTime|. (The start and end times are only used to compute how many | 75 // |startTime| and ends at |endTime|. (The start and end times are only used to compute how many |
65 // samples to return.) | 76 // samples to return.) |
66 function createLinearRampArray(startTime, endTime, startValue, endValue, sampleR ate) | 77 function createLinearRampArray(startTime, endTime, startValue, endValue, sampleR ate) |
67 { | 78 { |
68 var startFrame = timeToSampleFrame(startTime, sampleRate); | 79 var frameInfo = getStartEndFrames(startTime, endTime, sampleRate); |
69 var endFrame = timeToSampleFrame(endTime, sampleRate); | 80 var startFrame = frameInfo.startFrame; |
81 var endFrame = frameInfo.endFrame; | |
70 var length = endFrame - startFrame; | 82 var length = endFrame - startFrame; |
71 var array = new Array(length); | 83 var array = new Array(length); |
72 | 84 |
73 var step = (endValue - startValue) / length; | 85 var step = Math.fround((endValue - startValue) / (endTime - startTime) / sam pleRate); |
86 var start = Math.fround(startValue + (endValue - startValue) * (startFrame / sampleRate - startTime) / (endTime - startTime)); | |
74 | 87 |
88 var slope = (endValue - startValue) / (endTime - startTime); | |
89 | |
90 // v(t) = v0 + (v1 - v0)*(t-t0)/(t1-t0) | |
75 for (k = 0; k < length; ++k) { | 91 for (k = 0; k < length; ++k) { |
76 array[k] = startValue + k * step; | 92 //array[k] = Math.fround(start + k * step); |
93 var t = (startFrame + k) / sampleRate; | |
94 array[k] = startValue + slope * (t - startTime); | |
77 } | 95 } |
78 | 96 |
79 return array; | 97 return array; |
80 } | 98 } |
81 | 99 |
82 // Create an exponential ramp starting at |startValue| and ending at |endValue|. The ramp starts at | 100 // Create an exponential ramp starting at |startValue| and ending at |endValue|. The ramp starts at |
83 // time |startTime| and ends at |endTime|. (The start and end times are only us ed to compute how | 101 // time |startTime| and ends at |endTime|. (The start and end times are only us ed to compute how |
84 // many samples to return.) | 102 // many samples to return.) |
85 function createExponentialRampArray(startTime, endTime, startValue, endValue, sa mpleRate) | 103 function createExponentialRampArray(startTime, endTime, startValue, endValue, sa mpleRate) |
86 { | 104 { |
87 var startFrame = timeToSampleFrame(startTime, sampleRate); | 105 var deltaTime = endTime - startTime; |
88 var endFrame = timeToSampleFrame(endTime, sampleRate); | 106 |
107 var frameInfo = getStartEndFrames(startTime, endTime, sampleRate); | |
108 var startFrame = frameInfo.startFrame; | |
109 var endFrame = frameInfo.endFrame; | |
89 var length = endFrame - startFrame; | 110 var length = endFrame - startFrame; |
90 var array = new Array(length); | 111 var array = new Array(length); |
91 | 112 |
92 var multiplier = Math.pow(endValue / startValue, 1 / length); | 113 var ratio = endValue / startValue; |
93 | 114 |
115 // v(t) = v0*(v1/v0)^((t-t0)/(t1-t0)) | |
94 for (var k = 0; k < length; ++k) { | 116 for (var k = 0; k < length; ++k) { |
95 array[k] = startValue * Math.pow(multiplier, k); | 117 var t = Math.fround((startFrame + k) / sampleRate); |
118 array[k] = Math.fround(startValue * Math.pow(ratio, (t - startTime) / de ltaTime)); | |
96 } | 119 } |
97 | 120 |
98 return array; | 121 return array; |
99 } | 122 } |
100 | 123 |
101 function discreteTimeConstantForSampleRate(timeConstant, sampleRate) | 124 function discreteTimeConstantForSampleRate(timeConstant, sampleRate) |
102 { | 125 { |
103 return 1 - Math.exp(-1 / (sampleRate * timeConstant)); | 126 return 1 - Math.exp(-1 / (sampleRate * timeConstant)); |
104 } | 127 } |
105 | 128 |
106 // Create a signal that starts at |startValue| and exponentially approaches the target value of | 129 // Create a signal that starts at |startValue| and exponentially approaches the target value of |
107 // |targetValue|, using a time constant of |timeConstant|. The ramp starts at t ime |startTime| and | 130 // |targetValue|, using a time constant of |timeConstant|. The ramp starts at t ime |startTime| and |
108 // ends at |endTime|. (The start and end times are only used to compute how man y samples to | 131 // ends at |endTime|. (The start and end times are only used to compute how man y samples to |
109 // return.) | 132 // return.) |
110 function createExponentialApproachArray(startTime, endTime, startValue, targetVa lue, sampleRate, timeConstant) | 133 function createExponentialApproachArray(startTime, endTime, startValue, targetVa lue, sampleRate, timeConstant) |
111 { | 134 { |
112 var startFrame = timeToSampleFrame(startTime, sampleRate); | 135 var startFrameFloat = startTime * sampleRate; |
113 var endFrame = timeToSampleFrame(endTime, sampleRate); | 136 var frameInfo = getStartEndFrames(startTime, endTime, sampleRate); |
114 var length = endFrame - startFrame; | 137 var startFrame = frameInfo.startFrame; |
138 var endFrame = frameInfo.endFrame; | |
139 var length = Math.floor(endFrame - startFrame); | |
115 var array = new Array(length); | 140 var array = new Array(length); |
116 var c = discreteTimeConstantForSampleRate(timeConstant, sampleRate); | 141 var c = discreteTimeConstantForSampleRate(timeConstant, sampleRate); |
117 | 142 |
118 var value = startValue; | 143 var delta = startValue - targetValue; |
119 | 144 |
145 // v(t) = v1 + (v0 - v1) * exp(-(t-t0)/tau) | |
120 for (var k = 0; k < length; ++k) { | 146 for (var k = 0; k < length; ++k) { |
147 var t = (startFrame + k) / sampleRate; | |
148 var value = targetValue + delta * Math.exp(-(t - startTime) / timeConsta nt); | |
121 array[k] = value; | 149 array[k] = value; |
122 value += (targetValue - value) * c; | |
123 } | 150 } |
124 | 151 |
125 return array; | 152 return array; |
153 } | |
154 | |
155 // Create a sine wave of the specified duration. | |
156 function createReferenceSineArray(startTime, endTime, startValue, endValue, samp leRate) | |
157 { | |
158 // Ignore |startValue| and |endValue| for the sine wave. | |
159 var curve = createSineWaveArray(endTime - startTime, freqHz, sineAmplitude, sampleRate); | |
160 // Sample the curve appropriately. | |
161 var frameInfo = getStartEndFrames(startTime, endTime, sampleRate); | |
162 var startFrame = frameInfo.startFrame; | |
163 var endFrame = frameInfo.endFrame; | |
164 var length = Math.floor(endFrame - startFrame); | |
165 var array = new Array(length); | |
166 | |
167 // v(t) = linearly interpolate between V[k] and V[k + 1] where k = floor(N/d uration*(t - t0)) | |
168 var f = length / (endTime - startTime); | |
169 | |
170 for (var k = 0; k < length; ++k) { | |
171 var t = (startFrame + k) / sampleRate; | |
172 var indexFloat = f * (t - startTime); | |
173 var index = Math.floor(indexFloat); | |
174 if (index + 1 < length) { | |
175 var v0 = curve[index]; | |
176 var v1 = curve[index + 1]; | |
177 array[k] = v0 + (v1 - v0) * (indexFloat - index); | |
178 } else { | |
179 array[k] = curve[length - 1]; | |
180 } | |
181 } | |
182 | |
183 return array; | |
126 } | 184 } |
127 | 185 |
128 // Create a sine wave of the given frequency and amplitude. The sine wave is of fset by half the | 186 // Create a sine wave of the given frequency and amplitude. The sine wave is of fset by half the |
129 // amplitude so that result is always positive. | 187 // amplitude so that result is always positive. |
130 function createSineWaveArray(durationSeconds, freqHz, amplitude, sampleRate) | 188 function createSineWaveArray(durationSeconds, freqHz, amplitude, sampleRate) |
131 { | 189 { |
132 var length = timeToSampleFrame(durationSeconds, sampleRate); | 190 var length = timeToSampleFrame(durationSeconds, sampleRate); |
133 var signal = new Float32Array(length); | 191 var signal = new Float32Array(length); |
134 var omega = 2 * Math.PI * freqHz / sampleRate; | 192 var omega = 2 * Math.PI * freqHz / sampleRate; |
135 var halfAmplitude = amplitude / 2; | 193 var halfAmplitude = amplitude / 2; |
(...skipping 10 matching lines...) Expand all Loading... | |
146 // value. | 204 // value. |
147 function endValueDelta(timeIntervalIndex) | 205 function endValueDelta(timeIntervalIndex) |
148 { | 206 { |
149 if (timeIntervalIndex & 1) { | 207 if (timeIntervalIndex & 1) { |
150 return -startEndValueChange; | 208 return -startEndValueChange; |
151 } else { | 209 } else { |
152 return startEndValueChange; | 210 return startEndValueChange; |
153 } | 211 } |
154 } | 212 } |
155 | 213 |
214 // Relative error metric | |
215 function relativeErrorMetric(actual, expected) | |
216 { | |
217 return (actual - expected) / Math.abs(expected); | |
218 } | |
219 | |
220 // Difference metric | |
221 function differenceErrorMetric(actual, expected) | |
222 { | |
223 return actual - expected; | |
224 } | |
225 | |
156 // Return the difference between the starting value at |timeIntervalIndex| and t he starting value at | 226 // Return the difference between the starting value at |timeIntervalIndex| and t he starting value at |
157 // the next time interval. Since we started at a large initial value, we decrea se the value at each | 227 // the next time interval. Since we started at a large initial value, we decrea se the value at each |
158 // time interval. | 228 // time interval. |
159 function valueUpdate(timeIntervalIndex) | 229 function valueUpdate(timeIntervalIndex) |
160 { | 230 { |
161 return -startingValueDelta; | 231 return -startingValueDelta; |
162 } | 232 } |
163 | 233 |
164 // Compare a section of the rendered data against our expected signal. | 234 // Compare a section of the rendered data against our expected signal. |
165 function comparePartialSignals(rendered, expectedFunction, startTime, endTime, v alueInfo, sampleRate) | 235 function comparePartialSignals(rendered, expectedFunction, startTime, endTime, v alueInfo, sampleRate, errorMetric) |
166 { | 236 { |
167 var startSample = timeToSampleFrame(startTime, sampleRate); | 237 var startSample = timeToSampleFrame(startTime, sampleRate); |
168 var expected = expectedFunction(startTime, endTime, valueInfo.startValue, va lueInfo.endValue, sampleRate, timeConstant); | 238 var expected = expectedFunction(startTime, endTime, valueInfo.startValue, va lueInfo.endValue, sampleRate, timeConstant); |
169 | 239 |
170 var n = expected.length; | 240 var n = expected.length; |
171 var maxError = -1; | 241 var maxError = -1; |
172 var maxErrorIndex = -1; | 242 var maxErrorIndex = -1; |
173 | 243 |
174 for (var k = 0; k < n; ++k) { | 244 for (var k = 0; k < n; ++k) { |
175 // Make sure we don't pass these tests because a NaN has been generated in either the | 245 // Make sure we don't pass these tests because a NaN has been generated in either the |
176 // rendered data or the reference data. | 246 // rendered data or the reference data. |
177 if (!isValidNumber(rendered[startSample + k])) { | 247 if (!isValidNumber(rendered[startSample + k])) { |
178 maxError = Infinity; | 248 maxError = Infinity; |
179 maxErrorIndex = startSample + k; | 249 maxErrorIndex = startSample + k; |
180 testFailed("NaN or infinity for rendered data at " + maxErrorIndex); | 250 testFailed("NaN or infinity for rendered data at " + maxErrorIndex); |
181 break; | 251 break; |
182 } | 252 } |
183 if (!isValidNumber(expected[k])) { | 253 if (!isValidNumber(expected[k])) { |
184 maxError = Infinity; | 254 maxError = Infinity; |
185 maxErrorIndex = startSample + k; | 255 maxErrorIndex = startSample + k; |
186 testFailed("Nan or infinity for reference data at " + maxErrorIndex) ; | 256 testFailed("Nan or infinity for reference data at " + maxErrorIndex) ; |
187 break; | 257 break; |
188 } | 258 } |
189 var error = Math.abs(rendered[startSample + k] - expected[k]); | 259 var error = Math.abs(errorMetric(rendered[startSample + k], expected[k]) ); |
190 if (error > maxError) { | 260 if (error > maxError) { |
191 maxError = error; | 261 maxError = error; |
192 maxErrorIndex = k; | 262 maxErrorIndex = k; |
193 } | 263 } |
194 } | 264 } |
195 | 265 |
196 return {maxError : maxError, index : maxErrorIndex}; | 266 return {maxError : maxError, index : maxErrorIndex, expected: expected}; |
197 } | 267 } |
198 | 268 |
199 // Find the discontinuities in the data and compare the locations of the discont inuities with the | 269 // Find the discontinuities in the data and compare the locations of the discont inuities with the |
200 // times that define the time intervals. There is a discontinuity if the differe nce between | 270 // times that define the time intervals. There is a discontinuity if the differe nce between |
201 // successive samples exceeds the threshold. | 271 // successive samples exceeds the threshold. |
202 function verifyDiscontinuities(values, times, threshold) | 272 function verifyDiscontinuities(values, times, threshold) |
203 { | 273 { |
204 var n = values.length; | 274 var n = values.length; |
205 var success = true; | 275 var success = true; |
206 var badLocations = 0; | 276 var badLocations = 0; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 // maxError - maximum allowed difference between the rendered data and the expec ted data | 333 // maxError - maximum allowed difference between the rendered data and the expec ted data |
264 // | 334 // |
265 // rendererdData - array containing the rendered (actual) data | 335 // rendererdData - array containing the rendered (actual) data |
266 // | 336 // |
267 // expectedFunction - function to compute the expected data | 337 // expectedFunction - function to compute the expected data |
268 // | 338 // |
269 // timeValueInfo - array containing information about the start and end times an d the start and end | 339 // timeValueInfo - array containing information about the start and end times an d the start and end |
270 // values of each interval. | 340 // values of each interval. |
271 // | 341 // |
272 // breakThreshold - threshold to use for determining discontinuities. | 342 // breakThreshold - threshold to use for determining discontinuities. |
273 function compareSignals(testName, maxError, renderedData, expectedFunction, time ValueInfo, breakThreshold) | 343 function compareSignals(testName, maxError, renderedData, expectedFunction, time ValueInfo, breakThreshold, errorMetric) |
274 { | 344 { |
275 var success = true; | 345 var success = true; |
276 var failedTestCount = 0; | 346 var failedTestCount = 0; |
277 var times = timeValueInfo.times; | 347 var times = timeValueInfo.times; |
278 var values = timeValueInfo.values; | 348 var values = timeValueInfo.values; |
279 var n = values.length; | 349 var n = values.length; |
350 var expectedSignal = []; | |
280 | 351 |
281 success = verifyDiscontinuities(renderedData, times, breakThreshold); | 352 success = verifyDiscontinuities(renderedData, times, breakThreshold); |
282 | 353 |
283 for (var k = 0; k < n; ++k) { | 354 for (var k = 0; k < n; ++k) { |
284 var result = comparePartialSignals(renderedData, expectedFunction, times [k], times[k + 1], values[k], sampleRate); | 355 var result = comparePartialSignals(renderedData, expectedFunction, times [k], times[k + 1], values[k], sampleRate, errorMetric); |
356 | |
357 expectedSignal = expectedSignal.concat(Array.prototype.slice.call(result .expected)); | |
285 | 358 |
286 if (result.maxError > maxError) { | 359 if (result.maxError > maxError) { |
287 testFailed("Incorrect value for test " + k + ". Max error = " + resu lt.maxError + " at offset " + (result.index + timeToSampleFrame(times[k], sample Rate))); | 360 var offset = result.index + timeToSampleFrame(times[k], sampleRate); |
361 testFailed("Incorrect value for test " + k + ". Max error = " + resu lt.maxError | |
362 + " at offset " + offset | |
363 + ": actual = " + renderedData[offset] | |
364 + ", expected = " + expectedSignal[offset] + "."); | |
288 ++failedTestCount; | 365 ++failedTestCount; |
289 } | 366 } |
290 } | 367 } |
291 | 368 |
292 if (failedTestCount) { | 369 if (failedTestCount) { |
293 testFailed(failedTestCount + " tests failed out of " + n); | 370 testFailed(failedTestCount + " tests failed out of " + n); |
294 success = false; | 371 success = false; |
295 } else { | 372 } else { |
296 testPassed("All " + n + " tests passed within an acceptable tolerance.") ; | 373 testPassed("All " + n + " tests passed within an acceptable relative tol erance of " + maxError + "."); |
297 } | 374 } |
298 | 375 |
299 if (success) { | 376 if (success) { |
300 testPassed("AudioParam " + testName + " test passed."); | 377 testPassed("AudioParam " + testName + " test passed."); |
301 } else { | 378 } else { |
302 testFailed("AudioParam " + testName + " test failed."); | 379 testFailed("AudioParam " + testName + " test failed."); |
303 } | 380 } |
304 } | 381 } |
305 | 382 |
306 // Create a function to test the rendered data with the reference data. | 383 // Create a function to test the rendered data with the reference data. |
307 // | 384 // |
308 // testName - string describing the test | 385 // testName - string describing the test |
309 // | 386 // |
310 // error - max allowed error between rendered data and the reference data. | 387 // error - max allowed error between rendered data and the reference data. |
311 // | 388 // |
312 // referenceFunction - function that generates the reference data to be compared with the rendered | 389 // referenceFunction - function that generates the reference data to be compared with the rendered |
313 // data. | 390 // data. |
314 // | 391 // |
315 // jumpThreshold - optional parameter that specifies the threshold to use for de tecting | 392 // jumpThreshold - optional parameter that specifies the threshold to use for de tecting |
316 // discontinuities. If not specified, defaults to discontinuityThreshold. | 393 // discontinuities. If not specified, defaults to discontinuityThreshold. |
317 // | 394 // |
318 function checkResultFunction(testName, error, referenceFunction, jumpThreshold) | 395 function checkResultFunction(testName, error, referenceFunction, jumpThreshold, errorMetric) |
319 { | 396 { |
320 return function(event) { | 397 return function(event) { |
321 var buffer = event.renderedBuffer; | 398 var buffer = event.renderedBuffer; |
322 renderedData = buffer.getChannelData(0); | 399 renderedData = buffer.getChannelData(0); |
323 | 400 |
324 var threshold; | 401 var threshold; |
325 | 402 |
326 if (!jumpThreshold) { | 403 if (!jumpThreshold) { |
327 threshold = discontinuityThreshold; | 404 threshold = discontinuityThreshold; |
328 } else { | 405 } else { |
329 threshold = jumpThreshold; | 406 threshold = jumpThreshold; |
330 } | 407 } |
331 | 408 |
332 compareSignals(testName, error, renderedData, referenceFunction, timeVal ueInfo, threshold); | 409 compareSignals(testName, error, renderedData, referenceFunction, timeVal ueInfo, threshold, errorMetric); |
333 | 410 |
334 finishJSTest(); | 411 finishJSTest(); |
335 } | 412 } |
336 } | 413 } |
337 | 414 |
338 // Run all the automation tests. | 415 // Run all the automation tests. |
339 // | 416 // |
340 // numberOfTests - number of tests (time intervals) to run. | 417 // numberOfTests - number of tests (time intervals) to run. |
341 // | 418 // |
342 // initialValue - The initial value of the first time interval. | 419 // initialValue - The initial value of the first time interval. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
388 // testName - string indicating the test that is being run. | 465 // testName - string indicating the test that is being run. |
389 // | 466 // |
390 // maxError - maximum allowed error between the rendered data and the reference data | 467 // maxError - maximum allowed error between the rendered data and the reference data |
391 // | 468 // |
392 // referenceFunction - function that generates the reference data to be compared against the | 469 // referenceFunction - function that generates the reference data to be compared against the |
393 // rendered data. | 470 // rendered data. |
394 // | 471 // |
395 // jumpThreshold - optional parameter that specifies the threshold to use for de tecting | 472 // jumpThreshold - optional parameter that specifies the threshold to use for de tecting |
396 // discontinuities. If not specified, defaults to discontinuityThreshold. | 473 // discontinuities. If not specified, defaults to discontinuityThreshold. |
397 // | 474 // |
398 function createAudioGraphAndTest(numberOfTests, initialValue, setValueFunction, automationFunction, testName, maxError, referenceFunction, jumpThreshold) | 475 function createAudioGraphAndTest(numberOfTests, initialValue, setValueFunction, automationFunction, testName, maxError, referenceFunction, jumpThreshold, errorM etric) |
399 { | 476 { |
400 if (window.testRunner) { | 477 if (window.testRunner) { |
401 testRunner.dumpAsText(); | 478 testRunner.dumpAsText(); |
402 testRunner.waitUntilDone(); | 479 testRunner.waitUntilDone(); |
403 } | 480 } |
404 | 481 |
405 window.jsTestIsAsync = true; | 482 window.jsTestIsAsync = true; |
406 | 483 |
407 // Create offline audio context. | 484 // Create offline audio context. |
408 context = new OfflineAudioContext(2, renderLength(numberOfTests), sampleRate ); | 485 context = new OfflineAudioContext(2, renderLength(numberOfTests), sampleRate ); |
(...skipping 19 matching lines...) Expand all Loading... | |
428 // Run the automation tests. | 505 // Run the automation tests. |
429 timeValueInfo = doAutomation(numberOfTests, | 506 timeValueInfo = doAutomation(numberOfTests, |
430 initialValue, | 507 initialValue, |
431 setValueFunction, | 508 setValueFunction, |
432 automationFunction); | 509 automationFunction); |
433 bufferSource.start(0); | 510 bufferSource.start(0); |
434 | 511 |
435 context.oncomplete = checkResultFunction(testName, | 512 context.oncomplete = checkResultFunction(testName, |
436 maxError, | 513 maxError, |
437 referenceFunction, | 514 referenceFunction, |
438 jumpThreshold); | 515 jumpThreshold, |
516 errorMetric || relativeErrorMetric) ; | |
439 context.startRendering(); | 517 context.startRendering(); |
440 } | 518 } |
OLD | NEW |