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

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: Corrected test thresholds and results 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/js-test.js"></script>
6 <script src="resources/compatibility.js"></script>
7 <script src="resources/audio-testing.js"></script>
8 </head>
9
10 <body>
11 <script>
12 description("Test Interpolation for AudioParam.setValueCurveAtTime");
13 window.jsTestIsAsync = true;
14
15 // Play a constant signal through a gain node that is automated using setV alueCurveAtTime with
16 // a 2-element curve. The output should be a linear change.
17
18 // Choose a sample rate that is a multiple of 128, the rendering quantum s ize. This makes the
19 // math work out to be nice numbers.
20 var sampleRate = 25600;
21 var testDurationSec = 1;
22 var testDurationFrames = testDurationSec * sampleRate;
23
24 // Where the curve starts and its duration. This MUST be less than the to tal rendering time.
25 var curveStartTime = 256 / sampleRate;
26 var curveDuration = 300 / sampleRate;;
27 var curveValue = 0.75;
28
29 // At this time, the gain node goes to gain 1. This is used to make sure the value curve is
30 // propagated correctly until the next event.
31 var fullGainTime = 0.75;
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
39 var context;
40 var actualResult;
41 var expectedResult;
42
43 var audit = Audit.createTaskRunner();
44
45 // Array of test configs. Each config must specify curveStartTime, curveD uration,
46 // curveLength, fullGainTime, maxErrorThreshold, and snrThreshold.
47 var testConfigs = [{
48 // The main test
49 curveStartTime: 256 / sampleRate,
50 curveDuration: 300 / sampleRate,
51 curveLength: 2,
52 fullGainTime: 0.75,
53 maxErrorThreshold: 0,
54 snrThreshold: 10000
55 }, {
56 // Increase the curve length
57 curveStartTime: 256 / sampleRate,
58 curveDuration: 300 / sampleRate,
59 curveLength: 3,
60 fullGainTime: 0.75,
61 maxErrorThreshold: 0,
62 snrThreshold: 10000
63 }, {
64 // Increase the curve length
65 curveStartTime: 256 / sampleRate,
66 curveDuration: 300 / sampleRate,
67 curveLength: 16,
68 fullGainTime: 0.75,
69 maxErrorThreshold: 5.961e-8,
70 snrThreshold: 172.746
71 }, {
72 // Increase the curve length
73 curveStartTime: 256 / sampleRate,
74 curveDuration: 300 / sampleRate,
75 curveLength: 100,
76 fullGainTime: 0.75,
77 maxErrorThreshold: 5.961e-8,
78 snrThreshold: 172.799
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.961e-8,
110 snrThreshold: 155.310
111 }];
112
113 // Creates a function based on the test config that is suitable for use by defineTask().
114 function createTaskFunction(config) {
115 return function (done) {
116 runTest(config).then(done);
117 };
118 }
119
120 // Define a task for each config, in the order listed in testConfigs.
121 for (var k = 0; k < testConfigs.length; ++k) {
122 var config = testConfigs[k];
123 var name = k + ":curve=" + config.curveLength + ",duration=" + (config.c urveDuration * sampleRate);
124 audit.defineTask(name, createTaskFunction(config));
125 }
126
127 // Must be the last defined task.
128 audit.defineTask("end", function (done) {
129 finishJSTest();
130 done();
131 });
132
133 function runTest(config) {
134 context = new OfflineAudioContext(1, testDurationFrames, sampleRate);
135
136 // A constant audio source of value 1.
137 var source = context.createBufferSource();
138 source.buffer = createConstantBuffer(context, 1, 1);
139 source.loop = true;
140
141 // The value curve for testing. Just to make things easy for testing, m ake the curve a
142 // simple ramp up to curveValue.
143 // TODO(rtoy): Maybe allow more complicated curves?
144 var curve = new Float32Array(config.curveLength);
145 for (var k = 0; k < config.curveLength; ++k) {
146 curve[k] = curveValue / (config.curveLength - 1) * k;
147 }
148
149 // A gain node that is to be automated using setValueCurveAtTime.
150 var gain = context.createGain();
151 gain.gain.value = 0;
152 gain.gain.setValueCurveAtTime(curve, config.curveStartTime, config.curve Duration);
153 // This is to verify that setValueCurveAtTime ends appropriately.
154 gain.gain.setValueAtTime(1, config.fullGainTime);
155
156 source.connect(gain);
157 gain.connect(context.destination);
158 source.start();
159
160 // Some consistency checks on the test parameters
161 Should("Check: Curve end time", config.curveStartTime + config.curveDura tion)
162 .beLessThanOrEqualTo(testDurationSec);
163 Should("Check: Full gain start time", config.fullGainTime).beLessThanOrE qualTo(testDurationSec);
164 Should("Check: Full gain start time", config.fullGainTime).beGreaterThan OrEqualTo(config.curveStartTime + config.curveDuration);
165
166 // Rock and roll!
167 return context.startRendering().then(checkResult(config));
168 }
169
170 // Return a function to check that the rendered result matches the expecte d result.
171 function checkResult(config) {
172 return function (renderedBuffer) {
173 var success = true;
174
175 actualResult = renderedBuffer.getChannelData(0);
176 expectedResult = computeExpectedResult(config);
177
178 // Compute the SNR and max absolute difference between the actual and expected result.
179 var SNR = 10*Math.log10(computeSNR(actualResult, expectedResult));
180 var maxDiff = -1;
181 var posn = -1;
182
183 for (var k = 0; k < actualResult.length; ++k) {
184 var diff = Math.abs(actualResult[k] - expectedResult[k]);
185 if (maxDiff < diff) {
186 maxDiff = diff;
187 posn = k;
188 }
189 }
190
191 success = success && Should("SNR", SNR).beGreaterThanOrEqualTo(config. snrThreshold);
192
193 if (maxDiff <= config.maxErrorThreshold) {
194 testPassed("Max difference is less than or equal to " + config.maxEr rorThreshold + ".");
195 } else {
196 testFailed("Max difference (" + maxDiff + ") NOT less than or equal to " +
197 config.maxErrorThreshold + " at frame " + posn + ".");
198 success = false;
199 }
200
201 var message = "Test: curve length = " + config.curveLength + "; durati on frames = " +
202 config.curveDuration * sampleRate + ".\n";
203
204 if (success)
205 testPassed(message);
206 else
207 testFailed(message);
208 }
209 }
210
211 // Compute the expected result based on the config settings.
212 function computeExpectedResult(config) {
213 // The automation curve starts at |curveStartTime| and has duration |cu rveDuration|. So,
214 // the output should be zero until curveStartTime, linearly ramp up fro m there to
215 // |curveValue|, and then be constant 1 from then to the end of the buf fer.
216
217 var expected = new Float32Array(testDurationFrames);
218
219 var curveStartFrame = config.curveStartTime * sampleRate;
220 var curveEndFrame = Math.floor((config.curveStartTime + config.curveDur ation) * sampleRate);
221 var fullGainFrame = config.fullGainTime * sampleRate;
222
223 // TODO(crbug.com/517491): setValueAtTime is off by one rendering quant um.
224 fullGainFrame += 128;
225
226 var k;
227
228 // Zero out the start.
229 for (k = 0; k < curveStartFrame; ++k)
230 expected[k] = 0;
231
232 // Linearly ramp now. This assumes that the actual curve used is a lin ear ramp, even if
233 // there are many curve points.
234 var stepSize = curveValue / (config.curveDuration * sampleRate - 1);
235 for (; k < curveEndFrame; ++k)
236 expected[k] = stepSize * (k - curveStartFrame);
237
238 // Hold it constant until the next event
239 for (; k < fullGainFrame; ++k)
240 expected[k] = curveValue;
241
242 // Amplitude is one for the rest of the test.
243 for (; k < testDurationFrames; ++k)
244 expected[k] = 1;
245
246 return expected;
247 }
248
249 audit.runTasks();
250
251 successfullyParsed = true;
252 </script>
253 </body>
254 </html>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698