Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/resources/audioparam-testing.js

Issue 2657033002: Convert AudioParam tests to testharness and new Audit (Closed)
Patch Set: clang-format the JS code. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurveAtTime-expected.txt ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 var sampleRate = 44100; 1 var sampleRate = 44100;
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
4 // each time interval.
4 var timeValueInfo; 5 var timeValueInfo;
5 6
6 // The difference between starting values between each time interval. 7 // The difference between starting values between each time interval.
7 var startingValueDelta; 8 var startingValueDelta;
8 9
9 // For any automation function that has an end or target value, the end value is based the starting 10 // For any automation function that has an end or target value, the end value is
10 // value of the time interval. The starting value will be increased or decrease d by 11 // based the starting value of the time interval. The starting value will be
11 // |startEndValueChange|. We choose half of |startingValueDelta| so that the end ing value will be 12 // increased or decreased by |startEndValueChange|. We choose half of
12 // distinct from the starting value for next time interval. This allows us to d etect where the ramp 13 // |startingValueDelta| so that the ending value will be distinct from the
13 // begins and ends. 14 // starting value for next time interval. This allows us to detect where the
15 // ramp begins and ends.
14 var startEndValueChange; 16 var startEndValueChange;
15 17
16 // Default threshold to use for detecting discontinuities that should appear at each time interval. 18 // Default threshold to use for detecting discontinuities that should appear at
19 // each time interval.
17 var discontinuityThreshold; 20 var discontinuityThreshold;
18 21
19 // Time interval between value changes. It is best if 1 / numberOfTests is not close to timeInterval. 22 // Time interval between value changes. It is best if 1 / numberOfTests is not
23 // close to timeInterval.
20 var timeInterval = .03; 24 var timeInterval = .03;
21 25
22 // Some suitable time constant so that we can see a significant change over a ti meInterval. This is 26 // Some suitable time constant so that we can see a significant change over a
23 // only needed by setTargetAtTime() which needs a time constant. 27 // timeInterval. This is only needed by setTargetAtTime() which needs a time
28 // constant.
24 var timeConstant = timeInterval / 3; 29 var timeConstant = timeInterval / 3;
25 30
26 var gainNode; 31 var gainNode;
27 32
28 var context; 33 var context;
29 34
30 // Make sure we render long enough to capture all of our test data. 35 // Make sure we render long enough to capture all of our test data.
31 function renderLength(numberOfTests) 36 function renderLength(numberOfTests) {
32 { 37 return timeToSampleFrame((numberOfTests + 1) * timeInterval, sampleRate);
33 return timeToSampleFrame((numberOfTests + 1) * timeInterval, sampleRate); 38 }
34 } 39
35 40 // Create a constant reference signal with the given |value|. Basically the
36 // Create a constant reference signal with the given |value|. Basically the sam e as 41 // same as |createConstantBuffer|, but with the parameters to match the other
37 // |createConstantBuffer|, but with the parameters to match the other create fun ctions. The 42 // create functions. The |endValue| is ignored.
38 // |endValue| is ignored. 43 function createConstantArray(startTime, endTime, value, endValue, sampleRate) {
39 function createConstantArray(startTime, endTime, value, endValue, sampleRate) 44 var startFrame = timeToSampleFrame(startTime, sampleRate);
40 { 45 var endFrame = timeToSampleFrame(endTime, sampleRate);
41 var startFrame = timeToSampleFrame(startTime, sampleRate); 46 var length = endFrame - startFrame;
42 var endFrame = timeToSampleFrame(endTime, sampleRate); 47
43 var length = endFrame - startFrame; 48 var buffer = createConstantBuffer(context, length, value);
44 49
45 var buffer = createConstantBuffer(context, length, value); 50 return buffer.getChannelData(0);
46 51 }
47 return buffer.getChannelData(0); 52
48 } 53 function getStartEndFrames(startTime, endTime, sampleRate) {
49 54 // Start frame is the ceiling of the start time because the ramp starts at or
50 function getStartEndFrames(startTime, endTime, sampleRate) 55 // after the sample frame. End frame is the ceiling because it's the
51 { 56 // exclusive ending frame of the automation.
52 // Start frame is the ceiling of the start time because the ramp 57 var startFrame = Math.ceil(startTime * sampleRate);
53 // starts at or after the sample frame. End frame is the ceiling 58 var endFrame = Math.ceil(endTime * sampleRate);
54 // because it's the exclusive ending frame of the automation. 59
55 var startFrame = Math.ceil(startTime * sampleRate); 60 return {startFrame: startFrame, endFrame: endFrame};
56 var endFrame = Math.ceil(endTime * sampleRate); 61 }
57 62
58 return {startFrame: startFrame, endFrame: endFrame}; 63 // Create a linear ramp starting at |startValue| and ending at |endValue|. The
59 } 64 // ramp starts at time |startTime| and ends at |endTime|. (The start and end
60 65 // times are only used to compute how many samples to return.)
61 // Create a linear ramp starting at |startValue| and ending at |endValue|. The ramp starts at time 66 function createLinearRampArray(
62 // |startTime| and ends at |endTime|. (The start and end times are only used to compute how many 67 startTime, endTime, startValue, endValue, sampleRate) {
63 // samples to return.) 68 var frameInfo = getStartEndFrames(startTime, endTime, sampleRate);
64 function createLinearRampArray(startTime, endTime, startValue, endValue, sampleR ate) 69 var startFrame = frameInfo.startFrame;
65 { 70 var endFrame = frameInfo.endFrame;
66 var frameInfo = getStartEndFrames(startTime, endTime, sampleRate); 71 var length = endFrame - startFrame;
67 var startFrame = frameInfo.startFrame; 72 var array = new Array(length);
68 var endFrame = frameInfo.endFrame; 73
69 var length = endFrame - startFrame; 74 var step =
70 var array = new Array(length); 75 Math.fround((endValue - startValue) / (endTime - startTime) / sampleRate);
71 76 var start = Math.fround(
72 var step = Math.fround((endValue - startValue) / (endTime - startTime) / sam pleRate); 77 startValue +
73 var start = Math.fround(startValue + (endValue - startValue) * (startFrame / sampleRate - startTime) / (endTime - startTime)); 78 (endValue - startValue) * (startFrame / sampleRate - startTime) /
74 79 (endTime - startTime));
75 var slope = (endValue - startValue) / (endTime - startTime); 80
76 81 var slope = (endValue - startValue) / (endTime - startTime);
77 // v(t) = v0 + (v1 - v0)*(t-t0)/(t1-t0) 82
78 for (k = 0; k < length; ++k) { 83 // v(t) = v0 + (v1 - v0)*(t-t0)/(t1-t0)
79 //array[k] = Math.fround(start + k * step); 84 for (k = 0; k < length; ++k) {
80 var t = (startFrame + k) / sampleRate; 85 // array[k] = Math.fround(start + k * step);
81 array[k] = startValue + slope * (t - startTime); 86 var t = (startFrame + k) / sampleRate;
82 } 87 array[k] = startValue + slope * (t - startTime);
83 88 }
84 return array; 89
85 } 90 return array;
86 91 }
87 // Create an exponential ramp starting at |startValue| and ending at |endValue|. The ramp starts at 92
88 // time |startTime| and ends at |endTime|. (The start and end times are only us ed to compute how 93 // Create an exponential ramp starting at |startValue| and ending at |endValue|.
89 // many samples to return.) 94 // The ramp starts at time |startTime| and ends at |endTime|. (The start and
90 function createExponentialRampArray(startTime, endTime, startValue, endValue, sa mpleRate) 95 // end times are only used to compute how many samples to return.)
91 { 96 function createExponentialRampArray(
92 var deltaTime = endTime - startTime; 97 startTime, endTime, startValue, endValue, sampleRate) {
93 98 var deltaTime = endTime - startTime;
94 var frameInfo = getStartEndFrames(startTime, endTime, sampleRate); 99
95 var startFrame = frameInfo.startFrame; 100 var frameInfo = getStartEndFrames(startTime, endTime, sampleRate);
96 var endFrame = frameInfo.endFrame; 101 var startFrame = frameInfo.startFrame;
97 var length = endFrame - startFrame; 102 var endFrame = frameInfo.endFrame;
98 var array = new Array(length); 103 var length = endFrame - startFrame;
99 104 var array = new Array(length);
100 var ratio = endValue / startValue; 105
101 106 var ratio = endValue / startValue;
102 // v(t) = v0*(v1/v0)^((t-t0)/(t1-t0)) 107
103 for (var k = 0; k < length; ++k) { 108 // v(t) = v0*(v1/v0)^((t-t0)/(t1-t0))
104 var t = Math.fround((startFrame + k) / sampleRate); 109 for (var k = 0; k < length; ++k) {
105 array[k] = Math.fround(startValue * Math.pow(ratio, (t - startTime) / de ltaTime)); 110 var t = Math.fround((startFrame + k) / sampleRate);
106 } 111 array[k] =
107 112 Math.fround(startValue * Math.pow(ratio, (t - startTime) / deltaTime));
108 return array; 113 }
109 } 114
110 115 return array;
111 function discreteTimeConstantForSampleRate(timeConstant, sampleRate) 116 }
112 { 117
113 return 1 - Math.exp(-1 / (sampleRate * timeConstant)); 118 function discreteTimeConstantForSampleRate(timeConstant, sampleRate) {
114 } 119 return 1 - Math.exp(-1 / (sampleRate * timeConstant));
115 120 }
116 // Create a signal that starts at |startValue| and exponentially approaches the target value of 121
117 // |targetValue|, using a time constant of |timeConstant|. The ramp starts at t ime |startTime| and 122 // Create a signal that starts at |startValue| and exponentially approaches the
118 // ends at |endTime|. (The start and end times are only used to compute how man y samples to 123 // target value of |targetValue|, using a time constant of |timeConstant|. The
119 // return.) 124 // ramp starts at time |startTime| and ends at |endTime|. (The start and end
120 function createExponentialApproachArray(startTime, endTime, startValue, targetVa lue, sampleRate, timeConstant) 125 // times are only used to compute how many samples to return.)
121 { 126 function createExponentialApproachArray(
122 var startFrameFloat = startTime * sampleRate; 127 startTime, endTime, startValue, targetValue, sampleRate, timeConstant) {
123 var frameInfo = getStartEndFrames(startTime, endTime, sampleRate); 128 var startFrameFloat = startTime * sampleRate;
124 var startFrame = frameInfo.startFrame; 129 var frameInfo = getStartEndFrames(startTime, endTime, sampleRate);
125 var endFrame = frameInfo.endFrame; 130 var startFrame = frameInfo.startFrame;
126 var length = Math.floor(endFrame - startFrame); 131 var endFrame = frameInfo.endFrame;
127 var array = new Array(length); 132 var length = Math.floor(endFrame - startFrame);
128 var c = discreteTimeConstantForSampleRate(timeConstant, sampleRate); 133 var array = new Array(length);
129 134 var c = discreteTimeConstantForSampleRate(timeConstant, sampleRate);
130 var delta = startValue - targetValue; 135
131 136 var delta = startValue - targetValue;
132 // v(t) = v1 + (v0 - v1) * exp(-(t-t0)/tau) 137
133 for (var k = 0; k < length; ++k) { 138 // v(t) = v1 + (v0 - v1) * exp(-(t-t0)/tau)
134 var t = (startFrame + k) / sampleRate; 139 for (var k = 0; k < length; ++k) {
135 var value = targetValue + delta * Math.exp(-(t - startTime) / timeConsta nt); 140 var t = (startFrame + k) / sampleRate;
136 array[k] = value; 141 var value = targetValue + delta * Math.exp(-(t - startTime) / timeConstant);
137 } 142 array[k] = value;
138 143 }
139 return array; 144
145 return array;
140 } 146 }
141 147
142 // Create a sine wave of the specified duration. 148 // Create a sine wave of the specified duration.
143 function createReferenceSineArray(startTime, endTime, startValue, endValue, samp leRate) 149 function createReferenceSineArray(
144 { 150 startTime, endTime, startValue, endValue, sampleRate) {
145 // Ignore |startValue| and |endValue| for the sine wave. 151 // Ignore |startValue| and |endValue| for the sine wave.
146 var curve = createSineWaveArray(endTime - startTime, freqHz, sineAmplitude, sampleRate); 152 var curve = createSineWaveArray(
147 // Sample the curve appropriately. 153 endTime - startTime, freqHz, sineAmplitude, sampleRate);
148 var frameInfo = getStartEndFrames(startTime, endTime, sampleRate); 154 // Sample the curve appropriately.
149 var startFrame = frameInfo.startFrame; 155 var frameInfo = getStartEndFrames(startTime, endTime, sampleRate);
150 var endFrame = frameInfo.endFrame; 156 var startFrame = frameInfo.startFrame;
151 var length = Math.floor(endFrame - startFrame); 157 var endFrame = frameInfo.endFrame;
152 var array = new Array(length); 158 var length = Math.floor(endFrame - startFrame);
153 159 var array = new Array(length);
154 // v(t) = linearly interpolate between V[k] and V[k + 1] where k = floor((N- 1)/duration*(t - t0)) 160
155 var f = (length - 1) / (endTime - startTime); 161 // v(t) = linearly interpolate between V[k] and V[k + 1] where k =
156 162 // floor((N-1)/duration*(t - t0))
157 for (var k = 0; k < length; ++k) { 163 var f = (length - 1) / (endTime - startTime);
158 var t = (startFrame + k) / sampleRate; 164
159 var indexFloat = f * (t - startTime); 165 for (var k = 0; k < length; ++k) {
160 var index = Math.floor(indexFloat); 166 var t = (startFrame + k) / sampleRate;
161 if (index + 1 < length) { 167 var indexFloat = f * (t - startTime);
162 var v0 = curve[index]; 168 var index = Math.floor(indexFloat);
163 var v1 = curve[index + 1]; 169 if (index + 1 < length) {
164 array[k] = v0 + (v1 - v0) * (indexFloat - index); 170 var v0 = curve[index];
165 } else { 171 var v1 = curve[index + 1];
166 array[k] = curve[length - 1]; 172 array[k] = v0 + (v1 - v0) * (indexFloat - index);
167 }
168 }
169
170 return array;
171 }
172
173 // Create a sine wave of the given frequency and amplitude. The sine wave is of fset by half the
174 // amplitude so that result is always positive.
175 function createSineWaveArray(durationSeconds, freqHz, amplitude, sampleRate)
176 {
177 var length = timeToSampleFrame(durationSeconds, sampleRate);
178 var signal = new Float32Array(length);
179 var omega = 2 * Math.PI * freqHz / sampleRate;
180 var halfAmplitude = amplitude / 2;
181
182 for (var k = 0; k < length; ++k) {
183 signal[k] = halfAmplitude + halfAmplitude * Math.sin(omega * k);
184 }
185
186 return signal;
187 }
188
189 // Return the difference between the starting value and the ending value for tim e interval
190 // |timeIntervalIndex|. We alternate between an end value that is above or belo w the starting
191 // value.
192 function endValueDelta(timeIntervalIndex)
193 {
194 if (timeIntervalIndex & 1) {
195 return -startEndValueChange;
196 } else { 173 } else {
197 return startEndValueChange; 174 array[k] = curve[length - 1];
198 } 175 }
176 }
177
178 return array;
179 }
180
181 // Create a sine wave of the given frequency and amplitude. The sine wave is
182 // offset by half the amplitude so that result is always positive.
183 function createSineWaveArray(durationSeconds, freqHz, amplitude, sampleRate) {
184 var length = timeToSampleFrame(durationSeconds, sampleRate);
185 var signal = new Float32Array(length);
186 var omega = 2 * Math.PI * freqHz / sampleRate;
187 var halfAmplitude = amplitude / 2;
188
189 for (var k = 0; k < length; ++k) {
190 signal[k] = halfAmplitude + halfAmplitude * Math.sin(omega * k);
191 }
192
193 return signal;
194 }
195
196 // Return the difference between the starting value and the ending value for
197 // time interval |timeIntervalIndex|. We alternate between an end value that is
198 // above or below the starting value.
199 function endValueDelta(timeIntervalIndex) {
200 if (timeIntervalIndex & 1) {
201 return -startEndValueChange;
202 } else {
203 return startEndValueChange;
204 }
199 } 205 }
200 206
201 // Relative error metric 207 // Relative error metric
202 function relativeErrorMetric(actual, expected) 208 function relativeErrorMetric(actual, expected) {
203 { 209 return (actual - expected) / Math.abs(expected);
204 return (actual - expected) / Math.abs(expected);
205 } 210 }
206 211
207 // Difference metric 212 // Difference metric
208 function differenceErrorMetric(actual, expected) 213 function differenceErrorMetric(actual, expected) {
209 { 214 return actual - expected;
210 return actual - expected; 215 }
211 } 216
212 217 // Return the difference between the starting value at |timeIntervalIndex| and
213 // Return the difference between the starting value at |timeIntervalIndex| and t he starting value at 218 // the starting value at the next time interval. Since we started at a large
214 // the next time interval. Since we started at a large initial value, we decrea se the value at each 219 // initial value, we decrease the value at each time interval.
215 // time interval. 220 function valueUpdate(timeIntervalIndex) {
216 function valueUpdate(timeIntervalIndex) 221 return -startingValueDelta;
217 {
218 return -startingValueDelta;
219 } 222 }
220 223
221 // Compare a section of the rendered data against our expected signal. 224 // Compare a section of the rendered data against our expected signal.
222 function comparePartialSignals(rendered, expectedFunction, startTime, endTime, v alueInfo, sampleRate, errorMetric) 225 function comparePartialSignals(
223 { 226 should, rendered, expectedFunction, startTime, endTime, valueInfo,
224 var startSample = timeToSampleFrame(startTime, sampleRate); 227 sampleRate, errorMetric) {
225 var expected = expectedFunction(startTime, endTime, valueInfo.startValue, va lueInfo.endValue, sampleRate, timeConstant); 228 var startSample = timeToSampleFrame(startTime, sampleRate);
226 229 var expected = expectedFunction(
227 var n = expected.length; 230 startTime, endTime, valueInfo.startValue, valueInfo.endValue, sampleRate,
228 var maxError = -1; 231 timeConstant);
229 var maxErrorIndex = -1; 232
230 233 var n = expected.length;
231 for (var k = 0; k < n; ++k) { 234 var maxError = -1;
232 // Make sure we don't pass these tests because a NaN has been generated in either the 235 var maxErrorIndex = -1;
233 // rendered data or the reference data. 236
234 if (!isValidNumber(rendered[startSample + k])) { 237 for (var k = 0; k < n; ++k) {
235 maxError = Infinity; 238 // Make sure we don't pass these tests because a NaN has been generated in
236 maxErrorIndex = startSample + k; 239 // either the
237 testFailed("NaN or infinity for rendered data at " + maxErrorIndex); 240 // rendered data or the reference data.
238 break; 241 if (!isValidNumber(rendered[startSample + k])) {
239 } 242 maxError = Infinity;
240 if (!isValidNumber(expected[k])) { 243 maxErrorIndex = startSample + k;
241 maxError = Infinity; 244 should(
242 maxErrorIndex = startSample + k; 245 isValidNumber(rendered[startSample + k]),
243 testFailed("Nan or infinity for reference data at " + maxErrorIndex) ; 246 'NaN or infinity for rendered data at ' + maxErrorIndex)
244 break; 247 .beTrue();
245 } 248 break;
246 var error = Math.abs(errorMetric(rendered[startSample + k], expected[k]) ); 249 }
247 if (error > maxError) { 250 if (!isValidNumber(expected[k])) {
248 maxError = error; 251 maxError = Infinity;
249 maxErrorIndex = k; 252 maxErrorIndex = startSample + k;
250 } 253 should(
251 } 254 isValidNumber(expected[k]),
252 255 'NaN or infinity for rendered data at ' + maxErrorIndex)
253 return {maxError : maxError, index : maxErrorIndex, expected: expected}; 256 .beTrue();
254 } 257 break;
255 258 }
256 // Find the discontinuities in the data and compare the locations of the discont inuities with the 259 var error = Math.abs(errorMetric(rendered[startSample + k], expected[k]));
257 // times that define the time intervals. There is a discontinuity if the differe nce between 260 if (error > maxError) {
258 // successive samples exceeds the threshold. 261 maxError = error;
259 function verifyDiscontinuities(values, times, threshold) 262 maxErrorIndex = k;
260 { 263 }
261 var n = values.length; 264 }
262 var success = true; 265
263 var badLocations = 0; 266 return {maxError: maxError, index: maxErrorIndex, expected: expected};
264 var breaks = []; 267 }
265 268
266 // Find discontinuities. 269 // Find the discontinuities in the data and compare the locations of the
267 for (var k = 1; k < n; ++k) { 270 // discontinuities with the times that define the time intervals. There is a
268 if (Math.abs(values[k] - values[k - 1]) > threshold) { 271 // discontinuity if the difference between successive samples exceeds the
269 breaks.push(k); 272 // threshold.
270 } 273 function verifyDiscontinuities(should, values, times, threshold) {
271 } 274 var n = values.length;
272 275 var success = true;
273 var testCount; 276 var badLocations = 0;
274 277 var breaks = [];
275 // If there are numberOfTests intervals, there are only numberOfTests - 1 in ternal interval 278
276 // boundaries. Hence the maximum number of discontinuties we expect to find is numberOfTests - 279 // Find discontinuities.
277 // 1. If we find more than that, we have no reference to compare against. We also assume that 280 for (var k = 1; k < n; ++k) {
278 // the actual discontinuities are close to the expected ones. 281 if (Math.abs(values[k] - values[k - 1]) > threshold) {
279 // 282 breaks.push(k);
280 // This is just a sanity check when something goes really wrong. For exampl e, if the threshold 283 }
281 // is too low, every sample frame looks like a discontinuity. 284 }
282 if (breaks.length >= numberOfTests) { 285
283 testCount = numberOfTests - 1; 286 var testCount;
284 testFailed("Found more discontinuities (" + breaks.length + ") than expe cted. Only comparing first " + testCount + "discontinuities."); 287
285 success = false; 288 // If there are numberOfTests intervals, there are only numberOfTests - 1
286 } else { 289 // internal interval boundaries. Hence the maximum number of discontinuties we
287 testCount = breaks.length; 290 // expect to find is numberOfTests - 1. If we find more than that, we have no
288 } 291 // reference to compare against. We also assume that the actual
289 292 // discontinuities are close to the expected ones.
290 // Compare the location of each discontinuity with the end time of each inte rval. (There is no 293 //
291 // discontinuity at the start of the signal.) 294 // This is just a sanity check when something goes really wrong. For example,
292 for (var k = 0; k < testCount; ++k) { 295 // if the threshold is too low, every sample frame looks like a discontinuity.
293 var expectedSampleFrame = timeToSampleFrame(times[k + 1], sampleRate); 296 if (breaks.length >= numberOfTests) {
294 if (breaks[k] != expectedSampleFrame) { 297 testCount = numberOfTests - 1;
295 success = false; 298 should(breaks.length, 'Number of discontinuities')
296 ++badLocations; 299 .beLessThan(numberOfTests);
297 testFailed("Expected discontinuity at " + expectedSampleFrame + " bu t got " + breaks[k]); 300 success = false;
298 } 301 } else {
299 } 302 testCount = breaks.length;
300 303 }
301 if (badLocations) { 304
302 testFailed(badLocations + " discontinuities at incorrect locations"); 305 // Compare the location of each discontinuity with the end time of each
303 success = false; 306 // interval. (There is no discontinuity at the start of the signal.)
304 } else { 307 for (var k = 0; k < testCount; ++k) {
305 if (breaks.length == numberOfTests - 1) { 308 var expectedSampleFrame = timeToSampleFrame(times[k + 1], sampleRate);
306 testPassed("All " + numberOfTests + " tests started and ended at the correct time."); 309 if (breaks[k] != expectedSampleFrame) {
307 } else { 310 success = false;
308 testFailed("Found " + breaks.length + " discontinuities but expected " + (numberOfTests - 1)); 311 ++badLocations;
309 success = false; 312 should(breaks[k], 'Discontinuity at index')
310 } 313 .beEqualTo(expectedSampleFrame);
311 } 314 }
312 315 }
313 return success; 316
317 if (badLocations) {
318 should(badLocations, 'Number of discontinuites at incorrect locations')
319 .beEqualTo(0);
320 success = false;
321 } else {
322 should(
323 breaks.length + 1,
324 'Number of tests started and ended at the correct time')
325 .beEqualTo(numberOfTests);
326 }
327
328 return success;
314 } 329 }
315 330
316 // Compare the rendered data with the expected data. 331 // Compare the rendered data with the expected data.
317 // 332 //
318 // testName - string describing the test 333 // testName - string describing the test
319 // 334 //
320 // maxError - maximum allowed difference between the rendered data and the expec ted data 335 // maxError - maximum allowed difference between the rendered data and the
336 // expected data
321 // 337 //
322 // rendererdData - array containing the rendered (actual) data 338 // rendererdData - array containing the rendered (actual) data
323 // 339 //
324 // expectedFunction - function to compute the expected data 340 // expectedFunction - function to compute the expected data
325 // 341 //
326 // timeValueInfo - array containing information about the start and end times an d the start and end 342 // timeValueInfo - array containing information about the start and end times
327 // values of each interval. 343 // and the start and end values of each interval.
328 // 344 //
329 // breakThreshold - threshold to use for determining discontinuities. 345 // breakThreshold - threshold to use for determining discontinuities.
330 function compareSignals(testName, maxError, renderedData, expectedFunction, time ValueInfo, breakThreshold, errorMetric) 346 function compareSignals(
331 { 347 should, testName, maxError, renderedData, expectedFunction, timeValueInfo,
332 var success = true; 348 breakThreshold, errorMetric) {
333 var failedTestCount = 0; 349 var success = true;
334 var times = timeValueInfo.times; 350 var failedTestCount = 0;
335 var values = timeValueInfo.values; 351 var times = timeValueInfo.times;
336 var n = values.length; 352 var values = timeValueInfo.values;
337 var expectedSignal = []; 353 var n = values.length;
338 354 var expectedSignal = [];
339 success = verifyDiscontinuities(renderedData, times, breakThreshold); 355
340 356 success = verifyDiscontinuities(should, renderedData, times, breakThreshold);
341 for (var k = 0; k < n; ++k) { 357
342 var result = comparePartialSignals(renderedData, expectedFunction, times [k], times[k + 1], values[k], sampleRate, errorMetric); 358 for (var k = 0; k < n; ++k) {
343 359 var result = comparePartialSignals(
344 expectedSignal = expectedSignal.concat(Array.prototype.slice.call(result .expected)); 360 should, renderedData, expectedFunction, times[k], times[k + 1],
345 361 values[k], sampleRate, errorMetric);
346 if (result.maxError > maxError) { 362
347 var offset = result.index + timeToSampleFrame(times[k], sampleRate); 363 expectedSignal =
348 testFailed("Incorrect value for test " + k + ". Max error = " + resu lt.maxError 364 expectedSignal.concat(Array.prototype.slice.call(result.expected));
349 + " at offset " + offset 365
350 + ": actual = " + renderedData[offset] 366 should(
351 + ", expected = " + expectedSignal[offset] + "."); 367 result.maxError,
352 ++failedTestCount; 368 'Max error for test ' + k + ' at offset ' +
353 } 369 (result.index + timeToSampleFrame(times[k], sampleRate)))
354 } 370 .beLessThanOrEqualTo(maxError);
355 371 }
356 if (failedTestCount) { 372
357 testFailed(failedTestCount + " tests failed out of " + n); 373 should(
358 success = false; 374 failedTestCount,
359 } else { 375 'Number of failed tests with an acceptable relative tolerance of ' +
360 testPassed("All " + n + " tests passed within an acceptable relative tol erance of " + maxError + "."); 376 maxError)
361 } 377 .beEqualTo(0);
362
363 if (success) {
364 testPassed("AudioParam " + testName + " test passed.");
365 } else {
366 testFailed("AudioParam " + testName + " test failed.");
367 }
368 } 378 }
369 379
370 // Create a function to test the rendered data with the reference data. 380 // Create a function to test the rendered data with the reference data.
371 // 381 //
372 // testName - string describing the test 382 // testName - string describing the test
373 // 383 //
374 // error - max allowed error between rendered data and the reference data. 384 // error - max allowed error between rendered data and the reference data.
375 // 385 //
376 // referenceFunction - function that generates the reference data to be compared with the rendered 386 // referenceFunction - function that generates the reference data to be compared
377 // data. 387 // with the rendered data.
378 // 388 //
379 // jumpThreshold - optional parameter that specifies the threshold to use for de tecting 389 // jumpThreshold - optional parameter that specifies the threshold to use for
380 // discontinuities. If not specified, defaults to discontinuityThreshold. 390 // detecting discontinuities. If not specified, defaults to
391 // discontinuityThreshold.
381 // 392 //
382 function checkResultFunction(testName, error, referenceFunction, jumpThreshold, errorMetric) 393 function checkResultFunction(
383 { 394 task, should, testName, error, referenceFunction, jumpThreshold,
384 return function(event) { 395 errorMetric) {
385 var buffer = event.renderedBuffer; 396 return function(event) {
386 renderedData = buffer.getChannelData(0); 397 var buffer = event.renderedBuffer;
398 renderedData = buffer.getChannelData(0);
387 399
388 var threshold; 400 var threshold;
389 401
390 if (!jumpThreshold) { 402 if (!jumpThreshold) {
391 threshold = discontinuityThreshold; 403 threshold = discontinuityThreshold;
392 } else { 404 } else {
393 threshold = jumpThreshold; 405 threshold = jumpThreshold;
394 } 406 }
395
396 compareSignals(testName, error, renderedData, referenceFunction, timeVal ueInfo, threshold, errorMetric);
397 407
398 finishJSTest(); 408 compareSignals(
399 } 409 should, testName, error, renderedData, referenceFunction, timeValueInfo,
410 threshold, errorMetric);
411 task.done();
412 }
400 } 413 }
401 414
402 // Run all the automation tests. 415 // Run all the automation tests.
403 // 416 //
404 // numberOfTests - number of tests (time intervals) to run. 417 // numberOfTests - number of tests (time intervals) to run.
405 // 418 //
406 // initialValue - The initial value of the first time interval. 419 // initialValue - The initial value of the first time interval.
407 // 420 //
408 // setValueFunction - function that sets the specified value at the start of a t ime interval. 421 // setValueFunction - function that sets the specified value at the start of a
422 // time interval.
409 // 423 //
410 // automationFunction - function that sets the end value for the time interval. It specifies how 424 // automationFunction - function that sets the end value for the time interval.
411 // the value approaches the end value. 425 // It specifies how the value approaches the end value.
412 // 426 //
413 // An object is returned containing an array of start times for each time interv al, and an array 427 // An object is returned containing an array of start times for each time
414 // giving the start and end values for the interval. 428 // interval, and an array giving the start and end values for the interval.
415 function doAutomation(numberOfTests, initialValue, setValueFunction, automationF unction) 429 function doAutomation(
416 { 430 numberOfTests, initialValue, setValueFunction, automationFunction) {
417 var timeInfo = [0]; 431 var timeInfo = [0];
418 var valueInfo = []; 432 var valueInfo = [];
419 var value = initialValue; 433 var value = initialValue;
420
421 for (var k = 0; k < numberOfTests; ++k) {
422 var startTime = k * timeInterval;
423 var endTime = (k + 1) * timeInterval;
424 var endValue = value + endValueDelta(k);
425 434
426 // Set the value at the start of the time interval. 435 for (var k = 0; k < numberOfTests; ++k) {
427 setValueFunction(value, startTime); 436 var startTime = k * timeInterval;
437 var endTime = (k + 1) * timeInterval;
438 var endValue = value + endValueDelta(k);
428 439
429 // Specify the end or target value, and how we should approach it. 440 // Set the value at the start of the time interval.
430 automationFunction(endValue, startTime, endTime); 441 setValueFunction(value, startTime);
431 442
432 // Keep track of the start times, and the start and end values for each time interval. 443 // Specify the end or target value, and how we should approach it.
433 timeInfo.push(endTime); 444 automationFunction(endValue, startTime, endTime);
434 valueInfo.push({startValue: value, endValue : endValue});
435 445
436 value += valueUpdate(k); 446 // Keep track of the start times, and the start and end values for each time
437 } 447 // interval.
448 timeInfo.push(endTime);
449 valueInfo.push({startValue: value, endValue: endValue});
438 450
439 return {times : timeInfo, values : valueInfo}; 451 value += valueUpdate(k);
452 }
453
454 return {times: timeInfo, values: valueInfo};
440 } 455 }
441 456
442 // Create the audio graph for the test and then run the test. 457 // Create the audio graph for the test and then run the test.
443 // 458 //
444 // numberOfTests - number of time intervals (tests) to run. 459 // numberOfTests - number of time intervals (tests) to run.
445 // 460 //
446 // initialValue - the initial value of the gain at time 0. 461 // initialValue - the initial value of the gain at time 0.
447 // 462 //
448 // setValueFunction - function to set the value at the beginning of each time in terval. 463 // setValueFunction - function to set the value at the beginning of each time
464 // interval.
449 // 465 //
450 // automationFunction - the AudioParamTimeline automation function 466 // automationFunction - the AudioParamTimeline automation function
451 // 467 //
452 // testName - string indicating the test that is being run. 468 // testName - string indicating the test that is being run.
453 // 469 //
454 // maxError - maximum allowed error between the rendered data and the reference data 470 // maxError - maximum allowed error between the rendered data and the reference
471 // data
455 // 472 //
456 // referenceFunction - function that generates the reference data to be compared against the 473 // referenceFunction - function that generates the reference data to be compared
457 // rendered data. 474 // against the rendered data.
458 // 475 //
459 // jumpThreshold - optional parameter that specifies the threshold to use for de tecting 476 // jumpThreshold - optional parameter that specifies the threshold to use for
460 // discontinuities. If not specified, defaults to discontinuityThreshold. 477 // detecting discontinuities. If not specified, defaults to
478 // discontinuityThreshold.
461 // 479 //
462 function createAudioGraphAndTest(numberOfTests, initialValue, setValueFunction, automationFunction, testName, maxError, referenceFunction, jumpThreshold, errorM etric) 480 function createAudioGraphAndTest(
463 { 481 task, should, numberOfTests, initialValue, setValueFunction,
464 if (window.testRunner) { 482 automationFunction, testName, maxError, referenceFunction, jumpThreshold,
465 testRunner.dumpAsText(); 483 errorMetric) {
466 testRunner.waitUntilDone(); 484 // Create offline audio context.
467 } 485 context = new OfflineAudioContext(2, renderLength(numberOfTests), sampleRate);
486 var constantBuffer =
487 createConstantBuffer(context, renderLength(numberOfTests), 1);
468 488
469 window.jsTestIsAsync = true; 489 // We use an AudioGainNode here simply as a convenient way to test the
490 // AudioParam automation, since it's easy to pass a constant value through the
491 // node, automate the .gain attribute and observe the resulting values.
470 492
471 // Create offline audio context. 493 gainNode = context.createGain();
472 context = new OfflineAudioContext(2, renderLength(numberOfTests), sampleRate );
473 var constantBuffer = createConstantBuffer(context, renderLength(numberOfTest s), 1);
474 494
475 // We use an AudioGainNode here simply as a convenient way to test the Audio Param 495 var bufferSource = context.createBufferSource();
476 // automation, since it's easy to pass a constant value through the node, au tomate the 496 bufferSource.buffer = constantBuffer;
477 // .gain attribute and observe the resulting values. 497 bufferSource.connect(gainNode);
498 gainNode.connect(context.destination);
478 499
479 gainNode = context.createGain(); 500 // Set up default values for the parameters that control how the automation
501 // test values progress for each time interval.
502 startingValueDelta = initialValue / numberOfTests;
503 startEndValueChange = startingValueDelta / 2;
504 discontinuityThreshold = startEndValueChange / 2;
480 505
481 var bufferSource = context.createBufferSource(); 506 // Run the automation tests.
482 bufferSource.buffer = constantBuffer; 507 timeValueInfo = doAutomation(
483 bufferSource.connect(gainNode); 508 numberOfTests, initialValue, setValueFunction, automationFunction);
484 gainNode.connect(context.destination); 509 bufferSource.start(0);
485 510
486 // Set up default values for the parameters that control how the automation test values progress 511 context.oncomplete = checkResultFunction(
487 // for each time interval. 512 task, should, testName, maxError, referenceFunction, jumpThreshold,
488 startingValueDelta = initialValue / numberOfTests; 513 errorMetric || relativeErrorMetric);
489 startEndValueChange = startingValueDelta / 2; 514 context.startRendering();
490 discontinuityThreshold = startEndValueChange / 2;
491
492 // Run the automation tests.
493 timeValueInfo = doAutomation(numberOfTests,
494 initialValue,
495 setValueFunction,
496 automationFunction);
497 bufferSource.start(0);
498
499 context.oncomplete = checkResultFunction(testName,
500 maxError,
501 referenceFunction,
502 jumpThreshold,
503 errorMetric || relativeErrorMetric) ;
504 context.startRendering();
505 } 515 }
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/webaudio/AudioParam/audioparam-setValueCurveAtTime-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698