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

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/audioparam-setValueCurveAtTime-interpolation.html

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

Powered by Google App Engine
This is Rietveld 408576698