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

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

Issue 1277443005: Use interpolation for setValueCurveAtTime (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: More tests Created 5 years, 4 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 <!doctype html>
2 <html>
3 <head>
4 <title>Test Interpolation for AudioParam.setValueCurveAtTime</title>
5 <script src="resources/compatibility.js"></script>
6 <script src="resources/audio-testing.js"></script>
7 <script src="../resources/js-test.js"></script>
hongchan 2015/08/07 17:32:51 js-test.js should be the first.
Raymond Toy 2015/08/07 18:58:32 Done.
8 </head>
9
10 <body>
11 <script>
12 description("Test Interpolation for AudioParam.setValueCurveAtTime");
13
14 // Play a constant signal through a gain node that is automated using setV alueCurveAtTime with
15 // a 2-element curve. The output should be a linear change.
16
17 // Chose a sample rate that is a multiple of 128, the rendering quantum si ze. This makes the
hongchan 2015/08/07 17:32:51 Chose -> Choose
Raymond Toy 2015/08/07 18:58:32 Done.
18 // math work out to be nice numbers.
19 var sampleRate = 25600;
20 var testDurationSec = 1;
21 var testDurationFrames = testDurationSec * sampleRate;
22
23 // Where the curve starts and its duration. This MUST be less than the to tal rendering time.
24 var curveStartTime = 256 / sampleRate;
25 var curveDuration = 300 / sampleRate;;
26 var curveValue = 0.75;
27
28 // At this time, the gain node goes to gain 1. This is used to make sure the value curve is
29 // propagated correctly until the next event.
30 var fullGainTime = 0.75;
31
32 // Thresholds use to determine if the test passes; these are experimentall y determined. The
33 // SNR between the actual and expected result should be at least |snrThres hold|. The maximum
34 // difference betwen them should not exceed |maxErrorThreshold|.
35 var snrThreshold = 10000;
36 var maxErrorThreshold = 0;
37
38 var context;
39 var actualResult;
40 var expectedResult;
41
42 var audit = Audit.createTaskRunner();
43
44 audit.defineTask("initialize", function (done) {
45 window.jsTestIsAsync = true;
hongchan 2015/08/07 17:32:51 This can be done right after description() method.
Raymond Toy 2015/08/07 18:58:33 Done. And initialize task deleted.
46 done();
47 });
48
49
50 // Array of test configs. Each config must specify curveStartTime, curveD uration,
51 // curveLength, fullGainTime, maxErrorThreshold, and snrThreshold.
52 var testConfigs = [
hongchan 2015/08/07 17:32:51 This can be re-written: var testConfig = [{ /
Raymond Toy 2015/08/07 18:58:32 Done.
53 // The main test
54 {
55 curveStartTime: 256 / sampleRate,
56 curveDuration: 300 / sampleRate,
57 curveLength: 2,
58 fullGainTime: 0.75,
59 maxErrorThreshold: 0,
60 snrThreshold: 10000
61 },
62 // Increase the curve length
63 {
64 curveStartTime: 256 / sampleRate,
65 curveDuration: 300 / sampleRate,
66 curveLength: 3,
67 fullGainTime: 0.75,
68 maxErrorThreshold: 0,
69 snrThreshold: 10000
70 },
71 // Increase the curve length
72 {
73 curveStartTime: 256 / sampleRate,
74 curveDuration: 300 / sampleRate,
75 curveLength: 16,
76 fullGainTime: 0.75,
77 maxErrorThreshold: 0,
78 snrThreshold: 10000
79 },
80 // Increase the curve length
81 {
82 curveStartTime: 256 / sampleRate,
83 curveDuration: 300 / sampleRate,
84 curveLength: 100,
85 fullGainTime: 0.75,
86 maxErrorThreshold: 0,
87 snrThreshold: 10000
88 },
89 // Corner case with duration less than a frame!
90 {
91 curveStartTime: 256 / sampleRate,
92 curveDuration: 0.25 / sampleRate,
93 curveLength: 2,
94 fullGainTime: 0.75,
95 maxErrorThreshold: 0,
96 snrThreshold: 10000
97 },
98 // Short duration test
99 {
100 curveStartTime: 256 / sampleRate,
101 curveDuration: 2 / sampleRate,
102 curveLength: 2,
103 fullGainTime: 0.75,
104 maxErrorThreshold: 0,
105 snrThreshold: 10000
106 },
107 // Short duration test with many points.
108 {
109 curveStartTime: 256 / sampleRate,
110 curveDuration: 2 / sampleRate,
111 curveLength: 8,
112 fullGainTime: 0.75,
113 maxErrorThreshold: 0,
114 snrThreshold: 10000
115 },
116 // Long duration, big curve
117 {
118 curveStartTime: 256 / sampleRate,
119 curveDuration: .5,
120 curveLength: 1000,
121 fullGainTime: 0.75,
122 maxErrorThreshold: 0,
123 snrThreshold: 10000
124 }
125 ];
126
127 // Creates a function based on the test config that is suitable for use by defineTask().
128 function createTaskFunction (config) {
hongchan 2015/08/07 17:32:51 [Optional] Usually the named function does not hav
Raymond Toy 2015/08/07 18:58:33 Done.
129 return function (done) {
hongchan 2015/08/07 17:32:51 The anonymous function can have a space between th
Raymond Toy 2015/08/07 18:58:33 Acknowledged.
130 runTest(config).then(done);
131 };
132 }
133
134 // Define a task for each config, in the order listed in testConfigs.
135 for (var k = 0; k < testConfigs.length; ++k) {
136 var config = testConfigs[k];
137 var name = k + ":curve=" + config.curveLength + ",duration=" + (config.c urveDuration * sampleRate);
138 audit.defineTask(name, createTaskFunction(config));
139 }
140
141 // Must be the last defined task.
142 audit.defineTask("end", function (done) {
143 finishJSTest();
144 done();
145 });
146
147 function runTest (config) {
hongchan 2015/08/07 17:32:51 No space between the name in the parentheses. The
Raymond Toy 2015/08/07 18:58:32 Done.
148 context = new OfflineAudioContext(1, testDurationFrames, sampleRate);
149
150 // A constant audio source of value 1.
151 var source = context.createBufferSource();
152 source.buffer = createConstantBuffer(context, 1, 1);
153 source.loop = true;
154
155 // The value curve for testing. Just to make things easy for testing, m ake the curve a
156 // simple ramp up to curveValue.
157 // TODO: Maybe allow more complicated curves?
hongchan 2015/08/07 17:32:51 TODO(rtoy)
Raymond Toy 2015/08/07 18:58:32 Done.
158 var curve = new Float32Array(config.curveLength);
159 for (var k = 0; k < config.curveLength; ++k) {
160 curve[k] = curveValue / (config.curveLength - 1) * k;
161 }
162
163 // A gain node that is to be automated using setValueCurveAtTime.
164 var gain = context.createGain();
165 gain.gain.value = 0;
166 gain.gain.setValueCurveAtTime(curve, config.curveStartTime, config.curve Duration);
167 // This is to verify that setValueCurveAtTime ends appropriately.
168 gain.gain.setValueAtTime(1, config.fullGainTime);
169
170 source.connect(gain);
171 gain.connect(context.destination);
172 source.start();
173
174 // Some consistency checks on the test parameters
175 Should("Check: Curve end time", config.curveStartTime + config.curveDura tion)
176 .beLessThanOrEqualTo(testDurationSec);
177 Should("Check: Full gain start time", config.fullGainTime).beLessThanOrE qualTo(testDurationSec);
178 Should("Check: Full gain start time", config.fullGainTime).beGreaterThan OrEqualTo(config.curveStartTime + config.curveDuration);
179
180 // Rock and roll!
181 return context.startRendering().then(checkResult(config));
182 }
183
184 // Return a function to check that the rendered result matches the expecte d result.
185 function checkResult(config)
hongchan 2015/08/07 17:32:51 Let's move the curly brace one line up.
Raymond Toy 2015/08/07 18:58:33 Done.
186 {
187 return function (renderedBuffer) {
188 var success = true;
189
190 actualResult = renderedBuffer.getChannelData(0);
191 expectedResult = computeExpectedResult(config);
192
193 // Compute the SNR and max absolute difference between the actual and expected result.
194 var SNR = 10*Math.log10(computeSNR(actualResult, expectedResult));
195 var maxDiff = -1;
196 var posn = -1;
197
198 for (var k = 0; k < actualResult.length; ++k) {
199 var diff = Math.abs(actualResult[k] - expectedResult[k]);
200 if (maxDiff < diff) {
201 maxDiff = diff;
202 posn = k;
203 }
204 }
205
206 success = success && Should("SNR", SNR).beGreaterThanOrEqualTo(config. snrThreshold);
207
208 if (maxDiff <= config.maxErrorThreshold) {
209 testPassed("Max difference is less than or equal to " + config.maxEr rorThreshold + ".");
210 } else {
211 testFailed("Max difference (" + maxDiff + ") NOT less than or equal to " +
212 config.maxErrorThreshold + " at frame " + posn + ".");
213 success = false;
214 }
215
216 var message = "Test: curve length = " + config.curveLength + "; durati on frames = " +
217 config.curveDuration * sampleRate + ".\n";
218
219 if (success)
220 testPassed(message);
221 else
222 testFailed(message);
223 }
224 }
225
226 // Compute the expected result based on the config settings.
227 function computeExpectedResult(config)
228 {
229 // The automation curve starts at |curveStartTime| and has duration |cu rveDuration|. So,
230 // the output should be zero until curveStartTime, linearly ramp up fro m there to
231 // |curveValue|, and then be constant 1 from then to the end of the buf fer.
232
233 var expected = new Float32Array(testDurationFrames);
234
235 var curveStartFrame = config.curveStartTime * sampleRate;
236 var curveEndFrame = Math.floor((config.curveStartTime + config.curveDur ation) * sampleRate);
237 var fullGainFrame = config.fullGainTime * sampleRate;
238
239 // TODO(crbug.com/517491): setValueAtTime is off by one rendering quant um.
240 fullGainFrame += 128;
241
242 var k;
243
244 // Zero out the start.
245 for (k = 0; k < curveStartFrame; ++k) {
hongchan 2015/08/07 17:32:51 One-line loop block does not curly embraces around
Raymond Toy 2015/08/07 18:58:32 Done.
246 expected[k] = 0;
247 }
248
249 // Linearly ramp now. This assumes that the actual curve used is a lin ear ramp, even if
250 // there are many curve points.
251 var stepSize = curveValue / (config.curveDuration * sampleRate - 1);
252 for (; k < curveEndFrame; ++k) {
hongchan 2015/08/07 17:32:51 ditto.
Raymond Toy 2015/08/07 18:58:32 Done.
253 expected[k] = stepSize * (k - curveStartFrame);
254 }
255
256 // Hold it constant until the next event
257 for (; k < fullGainFrame; ++k) {
hongchan 2015/08/07 17:32:51 ditto.
Raymond Toy 2015/08/07 18:58:32 Done.
258 expected[k] = curveValue;
259 }
260
261 // Amplitude is one for the rest of the test.
262 for (; k < testDurationFrames; ++k) {
hongchan 2015/08/07 17:32:51 ditto.
Raymond Toy 2015/08/07 18:58:32 Done.
263 expected[k] = 1;
264 }
265
266 return expected;
267 }
268
269 //runTest();
hongchan 2015/08/07 17:32:51 Why is this commented out? Let's remove if this is
Raymond Toy 2015/08/07 18:58:33 Done.
270
271 audit.runTasks();
272
273 successfullyParsed = true;
274 </script>
275 </body>
276 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698