OLD | NEW |
| (Empty) |
1 <!doctype html> | |
2 <html> | |
3 <head> | |
4 <title>Test Automation Following setValueCurveAtTime Automations</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 <script src="resources/audio-param.js"></script> | |
10 </head> | |
11 | |
12 <body> | |
13 <script> | |
14 description("Test Automation Following setValueCurveAtTime Automations"); | |
15 window.jsTestIsAsync = true; | |
16 | |
17 var sampleRate = 12800; | |
18 // Some short duration because we don't need to run the test for very long
. | |
19 var testDurationFrames = 256; | |
20 var testDurationSec = testDurationFrames / sampleRate; | |
21 var curveDuration = testDurationSec / 2; | |
22 | |
23 var audit = Audit.createTaskRunner(); | |
24 | |
25 // Configuration for each test. | |
26 // | |
27 // Required options: | |
28 // automation - Name of automation method to test | |
29 // time - Time for the automation method. | |
30 // Optional options: | |
31 // extraDuration - extra time for the duration of the setValueCurve | |
32 // duration. Default is 0. This should not be on a | |
33 // sample frame boundary. This is for testing that | |
34 // curves that don't end on a frame boundary are handled | |
35 // correctly. | |
36 // threshold - Error threshold for the test; default is 0. | |
37 var testConfigs = [{ | |
38 automation: "linearRampToValueAtTime", | |
39 time: testDurationSec, | |
40 threshold: 3.9737e-8 | |
41 }, { | |
42 automation: "linearRampToValueAtTime", | |
43 time: testDurationSec, | |
44 extraDuration: 0.5 / sampleRate, | |
45 threshold: 1.8141e-8 | |
46 }, { | |
47 automation: "exponentialRampToValueAtTime", | |
48 time: testDurationSec, | |
49 threshold: 3.9737e-8 | |
50 }, { | |
51 automation: "exponentialRampToValueAtTime", | |
52 time: testDurationSec, | |
53 extraDuration: 0.5 / sampleRate, | |
54 threshold: 2.0312e-8 | |
55 }, { | |
56 automation: "setTargetAtTime", | |
57 time: curveDuration, | |
58 threshold: 1.5895e-7 | |
59 }, { | |
60 automation: "setTargetAtTime", | |
61 time: curveDuration + 0.5 / sampleRate, | |
62 extraDuration: 0.5 / sampleRate, | |
63 threshold: 1.3278e-7 | |
64 }]; | |
65 | |
66 // Define tests from the configs | |
67 for (k in testConfigs) { | |
68 audit.defineTask(k + ": " + testConfigs[k].automation, (function (config
) { | |
69 return function (done) { | |
70 runTest(config).then(done); | |
71 }; | |
72 })(testConfigs[k])); | |
73 } | |
74 | |
75 audit.defineTask("finish", function (done) { | |
76 finishJSTest(); | |
77 done(); | |
78 }); | |
79 | |
80 audit.runTasks(); | |
81 | |
82 function runTest(options) { | |
83 // For the test, use a gain node with a constant input to test the | |
84 // automations. | |
85 var context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; | |
86 var source = context.createBufferSource(); | |
87 source.buffer = createConstantBuffer(context, 1, 1); | |
88 source.loop = true; | |
89 | |
90 var gain = context.createGain(); | |
91 | |
92 // Any valid curve is ok. We only use the last value for testing. | |
93 var curve = [0, 2, 0.3]; | |
94 var actualDuration = curveDuration + (options.extraDuration || 0); | |
95 gain.gain.setValueCurveAtTime(Float32Array.from(curve), 0, actualDuratio
n); | |
96 | |
97 // Run the desired test automation. The extra parameter (0.01) is only | |
98 // used for setTargetAtTime tests; it's ignored for other tests. | |
99 var automationValue = 2; | |
100 gain.gain[options.automation](automationValue, options.time, 0.01); | |
101 | |
102 source.connect(gain); | |
103 gain.connect(context.destination); | |
104 | |
105 source.start(); | |
106 | |
107 return context.startRendering().then(function (resultBuffer) { | |
108 var result = resultBuffer.getChannelData(0); | |
109 | |
110 // Only need to verify that the ramp started at the right | |
111 // value. Figure the nearest sample frame to the end curve. | |
112 var curveEndFrame = Math.ceil(actualDuration * sampleRate); | |
113 | |
114 var expectedResult = curve[curve.length - 1]; | |
115 | |
116 // Determine the expected value after the end of the setValueCurve eve
nt. | |
117 if (options.automation == "linearRampToValueAtTime") { | |
118 expectedResult = audioParamLinearRamp( | |
119 curveEndFrame / sampleRate, | |
120 curve[curve.length - 1], actualDuration, | |
121 automationValue, testDurationSec); | |
122 } else if (options.automation == "exponentialRampToValueAtTime") { | |
123 expectedResult = audioParamExponentialRamp( | |
124 curveEndFrame / sampleRate, | |
125 curve[curve.length - 1], actualDuration, | |
126 automationValue, testDurationSec); | |
127 } else if (options.automation == "setTargetAtTime") { | |
128 expectedResult = audioParamSetTarget( | |
129 curveEndFrame / sampleRate, | |
130 curve[curve.length - 1], actualDuration, | |
131 automationValue, 0.01); | |
132 } | |
133 | |
134 var message = "setValueCurve(..., " + 0 + ", " + actualDuration + | |
135 ")." + options.automation + | |
136 "(2, " + testDurationSec; | |
137 | |
138 if (options.automation == "setTargetAtTime") | |
139 message += ", 0.01"; | |
140 message += ")"; | |
141 | |
142 Should(message + ": value at time " + curveEndFrame / sampleRate, resu
lt[curveEndFrame]) | |
143 .beCloseTo(expectedResult, options.threshold || 0); | |
144 }); | |
145 } | |
146 | |
147 function linearRampValue(t, t0, v0, t1, v1) { | |
148 return v0 + (v1 - v0) * (t - t0) / (t1 - t0); | |
149 } | |
150 | |
151 function exponentialRampValue(t, t0, v0, t1, v1) { | |
152 return v0 * Math.pow(v1 / v0, (t - t0) / (t1 - t0)); | |
153 } | |
154 | |
155 function setTargetValue(t, t0, v0, v1, timeConstant) { | |
156 return v1 + (v0 - v1) * Math.exp(-(t - t0) / timeConstant) | |
157 } | |
158 </script> | |
159 </body> | |
160 </html> | |
OLD | NEW |