Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / LayoutTests / webaudio / audioparam-setValueCurveAtTime-interpolation.html
blob73f242aa11fac3e8ba182aff464d8249b719af52
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>
10 <body>
11 <script>
12 description("Test Interpolation for AudioParam.setValueCurveAtTime");
13 window.jsTestIsAsync = true;
15 // Play a constant signal through a gain node that is automated using setValueCurveAtTime with
16 // a 2-element curve. The output should be a linear change.
18 // Choose a sample rate that is a multiple of 128, the rendering quantum size. This makes the
19 // math work out to be nice numbers.
20 var sampleRate = 25600;
21 var testDurationSec = 1;
22 var testDurationFrames = testDurationSec * sampleRate;
24 // Where the curve starts and its duration. This MUST be less than the total rendering time.
25 var curveStartTime = 256 / sampleRate;
26 var curveDuration = 300 / sampleRate;;
27 var curveValue = 0.75;
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;
33 // Thresholds use to determine if the test passes; these are experimentally determined. The
34 // SNR between the actual and expected result should be at least |snrThreshold|. The maximum
35 // difference betwen them should not exceed |maxErrorThreshold|.
36 var snrThreshold = 10000;
37 var maxErrorThreshold = 0;
39 var context;
40 var actualResult;
41 var expectedResult;
43 var audit = Audit.createTaskRunner();
45 // Array of test configs. Each config must specify curveStartTime, curveDuration,
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
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);
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.curveDuration * sampleRate);
124 audit.defineTask(name, createTaskFunction(config));
127 // Must be the last defined task.
128 audit.defineTask("end", function (done) {
129 finishJSTest();
130 done();
133 function runTest(config) {
134 context = new OfflineAudioContext(1, testDurationFrames, sampleRate);
136 // A constant audio source of value 1.
137 var source = context.createBufferSource();
138 source.buffer = createConstantBuffer(context, 1, 1);
139 source.loop = true;
141 // The value curve for testing. Just to make things easy for testing, make 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;
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.curveDuration);
153 // This is to verify that setValueCurveAtTime ends appropriately.
154 gain.gain.setValueAtTime(1, config.fullGainTime);
156 source.connect(gain);
157 gain.connect(context.destination);
158 source.start();
160 // Some consistency checks on the test parameters
161 Should("Check: Curve end time", config.curveStartTime + config.curveDuration)
162 .beLessThanOrEqualTo(testDurationSec);
163 Should("Check: Full gain start time", config.fullGainTime).beLessThanOrEqualTo(testDurationSec);
164 Should("Check: Full gain start time", config.fullGainTime).beGreaterThanOrEqualTo(config.curveStartTime + config.curveDuration);
166 // Rock and roll!
167 return context.startRendering().then(checkResult(config));
170 // Return a function to check that the rendered result matches the expected result.
171 function checkResult(config) {
172 return function (renderedBuffer) {
173 var success = true;
175 actualResult = renderedBuffer.getChannelData(0);
176 expectedResult = computeExpectedResult(config);
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;
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;
191 success = success && Should("SNR", SNR).beGreaterThanOrEqualTo(config.snrThreshold);
193 if (maxDiff <= config.maxErrorThreshold) {
194 testPassed("Max difference is less than or equal to " + config.maxErrorThreshold + ".");
195 } else {
196 testFailed("Max difference (" + maxDiff + ") NOT less than or equal to " +
197 config.maxErrorThreshold + " at frame " + posn + ".");
198 success = false;
201 var message = "Test: curve length = " + config.curveLength + "; duration frames = " +
202 config.curveDuration * sampleRate + ".\n";
204 if (success)
205 testPassed(message);
206 else
207 testFailed(message);
211 // Compute the expected result based on the config settings.
212 function computeExpectedResult(config) {
213 // The automation curve starts at |curveStartTime| and has duration |curveDuration|. So,
214 // the output should be zero until curveStartTime, linearly ramp up from there to
215 // |curveValue|, and then be constant 1 from then to the end of the buffer.
217 var expected = new Float32Array(testDurationFrames);
219 var curveStartFrame = config.curveStartTime * sampleRate;
220 var curveEndFrame = Math.floor((config.curveStartTime + config.curveDuration) * sampleRate);
221 var fullGainFrame = config.fullGainTime * sampleRate;
223 var k;
225 // Zero out the start.
226 for (k = 0; k < curveStartFrame; ++k)
227 expected[k] = 0;
229 // Linearly ramp now. This assumes that the actual curve used is a linear ramp, even if
230 // there are many curve points.
231 var stepSize = curveValue / (config.curveDuration * sampleRate - 1);
232 for (; k < curveEndFrame; ++k)
233 expected[k] = stepSize * (k - curveStartFrame);
235 // Hold it constant until the next event
236 for (; k < fullGainFrame; ++k)
237 expected[k] = curveValue;
239 // Amplitude is one for the rest of the test.
240 for (; k < testDurationFrames; ++k)
241 expected[k] = 1;
243 return expected;
246 audit.runTasks();
248 successfullyParsed = true;
249 </script>
250 </body>
251 </html>