OLD | NEW |
1 <!doctype html> | 1 <!DOCTYPE html> |
2 <html> | 2 <html> |
3 <head> | 3 <head> |
4 <title>Test Exceptions from setValueCurveAtTime</title> | 4 <title> |
| 5 Test Exceptions from setValueCurveAtTime |
| 6 </title> |
5 <script src="../../resources/testharness.js"></script> | 7 <script src="../../resources/testharness.js"></script> |
6 <script src="../../resources/testharnessreport.js"></script> | 8 <script src="../../resources/testharnessreport.js"></script> |
7 <script src="../resources/audit-util.js"></script> | 9 <script src="../resources/audit-util.js"></script> |
8 <script src="../resources/audit.js"></script> | 10 <script src="../resources/audit.js"></script> |
9 </head> | 11 </head> |
10 | |
11 <body> | 12 <body> |
12 <script> | 13 <script id="layout-test-code"> |
13 | |
14 let sampleRate = 48000; | 14 let sampleRate = 48000; |
15 // Some short duration because we don't need to run the test for very long
. | 15 // Some short duration because we don't need to run the test for very |
| 16 // long. |
16 let testDurationSec = 0.125; | 17 let testDurationSec = 0.125; |
17 let testDurationFrames = testDurationSec * sampleRate; | 18 let testDurationFrames = testDurationSec * sampleRate; |
18 | 19 |
19 let audit = Audit.createTaskRunner(); | 20 let audit = Audit.createTaskRunner(); |
20 | 21 |
21 audit.define("setValueCurve", (task, should) => { | 22 audit.define('setValueCurve', (task, should) => { |
22 let success = true; | 23 let success = true; |
23 let context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; | 24 let context = |
| 25 new OfflineAudioContext(1, testDurationFrames, sampleRate); |
24 let g = context.createGain(); | 26 let g = context.createGain(); |
25 let curve = new Float32Array(2); | 27 let curve = new Float32Array(2); |
26 | 28 |
27 // Start time and duration for setValueCurveAtTime | 29 // Start time and duration for setValueCurveAtTime |
28 let curveStartTime = 0.1 * testDurationSec; | 30 let curveStartTime = 0.1 * testDurationSec; |
29 let duration = 0.1 * testDurationSec; | 31 let duration = 0.1 * testDurationSec; |
30 | 32 |
31 // Some time that is known to during the setValueCurveTime interval. | 33 // Some time that is known to during the setValueCurveTime interval. |
32 let automationTime = curveStartTime + duration / 2; | 34 let automationTime = curveStartTime + duration / 2; |
33 | 35 |
34 should(() => { | 36 should( |
| 37 () => { |
35 g.gain.setValueCurveAtTime(curve, curveStartTime, duration); | 38 g.gain.setValueCurveAtTime(curve, curveStartTime, duration); |
36 }, | 39 }, |
37 "setValueCurveAtTime(curve, " + curveStartTime + ", " + duration + | 40 'setValueCurveAtTime(curve, ' + curveStartTime + ', ' + duration + |
38 ")") | 41 ')') |
39 .notThrow(); | 42 .notThrow(); |
40 | 43 |
41 should(function() { | 44 should( |
42 g.gain.setValueAtTime(1, automationTime); | 45 function() { |
43 }, "setValueAtTime(1, " + automationTime + ")") | 46 g.gain.setValueAtTime(1, automationTime); |
44 .throw("NotSupportedError"); | 47 }, |
| 48 'setValueAtTime(1, ' + automationTime + ')') |
| 49 .throw('NotSupportedError'); |
45 | 50 |
46 should(function() { | 51 should( |
47 g.gain.linearRampToValueAtTime(1, automationTime); | 52 function() { |
48 }, "linearRampToValueAtTime(1, " + automationTime + ")") | 53 g.gain.linearRampToValueAtTime(1, automationTime); |
49 .throw("NotSupportedError"); | 54 }, |
| 55 'linearRampToValueAtTime(1, ' + automationTime + ')') |
| 56 .throw('NotSupportedError'); |
50 | 57 |
51 should(function() { | 58 should( |
52 g.gain.exponentialRampToValueAtTime(1, automationTime); | 59 function() { |
53 }, "exponentialRampToValueAtTime(1, " + automationTime + ")") | 60 g.gain.exponentialRampToValueAtTime(1, automationTime); |
54 .throw("NotSupportedError"); | 61 }, |
| 62 'exponentialRampToValueAtTime(1, ' + automationTime + ')') |
| 63 .throw('NotSupportedError'); |
55 | 64 |
56 should(function() { | 65 should( |
57 g.gain.setTargetAtTime(1, automationTime, 1); | 66 function() { |
58 }, "setTargetAtTime(1, " + automationTime + ", 1)") | 67 g.gain.setTargetAtTime(1, automationTime, 1); |
59 .throw("NotSupportedError"); | 68 }, |
| 69 'setTargetAtTime(1, ' + automationTime + ', 1)') |
| 70 .throw('NotSupportedError'); |
60 | 71 |
61 should(function() { | 72 should( |
62 g.gain.setValueAtTime(1, curveStartTime + 1.1 * duration); | 73 function() { |
63 }, "setValueAtTime(1, " + (curveStartTime + 1.1 * duration) + ")") | 74 g.gain.setValueAtTime(1, curveStartTime + 1.1 * duration); |
64 .notThrow(); | 75 }, |
| 76 'setValueAtTime(1, ' + (curveStartTime + 1.1 * duration) + ')') |
| 77 .notThrow(); |
65 | 78 |
66 task.done(); | 79 task.done(); |
67 }); | 80 }); |
68 | 81 |
69 audit.define("automations", (task, should) => { | 82 audit.define('automations', (task, should) => { |
70 let context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; | 83 let context = |
| 84 new OfflineAudioContext(1, testDurationFrames, sampleRate); |
71 let g = context.createGain(); | 85 let g = context.createGain(); |
72 | 86 |
73 let curve = new Float32Array(2); | 87 let curve = new Float32Array(2); |
74 // Start time and duration for setValueCurveAtTime | 88 // Start time and duration for setValueCurveAtTime |
75 let startTime = 0; | 89 let startTime = 0; |
76 let timeInterval = testDurationSec / 10; | 90 let timeInterval = testDurationSec / 10; |
77 let time; | 91 let time; |
78 | 92 |
79 startTime += timeInterval; | 93 startTime += timeInterval; |
80 should(() => { | 94 should(() => { |
81 g.gain.linearRampToValueAtTime(1, startTime); | 95 g.gain.linearRampToValueAtTime(1, startTime); |
82 }, "linearRampToValueAtTime(1, " + startTime + ")").notThrow(); | 96 }, 'linearRampToValueAtTime(1, ' + startTime + ')').notThrow(); |
83 | 97 |
84 startTime += timeInterval; | 98 startTime += timeInterval; |
85 should(() => { | 99 should(() => { |
86 g.gain.exponentialRampToValueAtTime(1, startTime); | 100 g.gain.exponentialRampToValueAtTime(1, startTime); |
87 }, "exponentialRampToValueAtTime(1, " + startTime + ")").notThrow(); | 101 }, 'exponentialRampToValueAtTime(1, ' + startTime + ')').notThrow(); |
88 | 102 |
89 startTime += timeInterval; | 103 startTime += timeInterval; |
90 should(() => { | 104 should(() => { |
91 g.gain.setTargetAtTime(1, startTime, 0.1); | 105 g.gain.setTargetAtTime(1, startTime, 0.1); |
92 }, "setTargetAtTime(1, " + startTime + ", 0.1)").notThrow(); | 106 }, 'setTargetAtTime(1, ' + startTime + ', 0.1)').notThrow(); |
93 | 107 |
94 startTime += timeInterval; | 108 startTime += timeInterval; |
95 should(() => { | 109 should(() => { |
96 g.gain.setValueCurveAtTime(curve, startTime, 0.1); | 110 g.gain.setValueCurveAtTime(curve, startTime, 0.1); |
97 }, "setValueCurveAtTime(curve, " + startTime + ", 0.1)").notThrow(); | 111 }, 'setValueCurveAtTime(curve, ' + startTime + ', 0.1)').notThrow(); |
98 | 112 |
99 // Now try to setValueCurve that overlaps each of the above automations | 113 // Now try to setValueCurve that overlaps each of the above automations |
100 startTime = timeInterval / 2; | 114 startTime = timeInterval / 2; |
101 | 115 |
102 for (let k = 0; k < 4; ++k) { | 116 for (let k = 0; k < 4; ++k) { |
103 time = startTime + timeInterval * k; | 117 time = startTime + timeInterval * k; |
104 should(() => { | 118 should( |
| 119 () => { |
105 g.gain.setValueCurveAtTime(curve, time, 0.01); | 120 g.gain.setValueCurveAtTime(curve, time, 0.01); |
106 }, | 121 }, |
107 "setValueCurveAtTime(curve, " + time + ", 0.01)") | 122 'setValueCurveAtTime(curve, ' + time + ', 0.01)') |
108 .throw("NotSupportedError"); | 123 .throw('NotSupportedError'); |
109 } | 124 } |
110 | 125 |
111 // Elements of setValueCurve should be finite. | 126 // Elements of setValueCurve should be finite. |
112 should(() => { | 127 should( |
113 g.gain.setValueCurveAtTime(Float32Array.from([NaN, NaN]), time, | 128 () => { |
114 0.01); | 129 g.gain.setValueCurveAtTime( |
| 130 Float32Array.from([NaN, NaN]), time, 0.01); |
115 }, | 131 }, |
116 "setValueCurveAtTime([NaN, NaN], " + time + ", 0.01)") | 132 'setValueCurveAtTime([NaN, NaN], ' + time + ', 0.01)') |
117 .throw("TypeError"); | 133 .throw('TypeError'); |
118 | 134 |
119 should(() => { | 135 should( |
120 g.gain.setValueCurveAtTime(Float32Array.from([1, Infinity]), time, | 136 () => { |
121 0.01); | 137 g.gain.setValueCurveAtTime( |
| 138 Float32Array.from([1, Infinity]), time, 0.01); |
122 }, | 139 }, |
123 "setValueCurveAtTime([1, Infinity], " + time + ", 0.01)") | 140 'setValueCurveAtTime([1, Infinity], ' + time + ', 0.01)') |
124 .throw("TypeError"); | 141 .throw('TypeError'); |
125 | 142 |
126 let d = context.createDelay(); | 143 let d = context.createDelay(); |
127 // Check that we get warnings for out-of-range values and also throw for | 144 // Check that we get warnings for out-of-range values and also throw for |
128 // non-finite values. | 145 // non-finite values. |
129 should(() => { | 146 should( |
130 d.delayTime.setValueCurveAtTime(Float32Array.from([1, 5]), time, | 147 () => { |
131 0.01); | 148 d.delayTime.setValueCurveAtTime( |
| 149 Float32Array.from([1, 5]), time, 0.01); |
132 }, | 150 }, |
133 "delayTime.setValueCurveAtTime([1, 5], " + time + ", 0.01)") | 151 'delayTime.setValueCurveAtTime([1, 5], ' + time + ', 0.01)') |
134 .notThrow(); | 152 .notThrow(); |
135 | 153 |
136 should(() => { | 154 should( |
137 d.delayTime.setValueCurveAtTime(Float32Array.from([1, 5, Infinity]
), | 155 () => { |
138 time, 0.01); | 156 d.delayTime.setValueCurveAtTime( |
| 157 Float32Array.from([1, 5, Infinity]), time, 0.01); |
139 }, | 158 }, |
140 "delayTime.setValueCurveAtTime([1, 5, Infinity], " + time + | 159 'delayTime.setValueCurveAtTime([1, 5, Infinity], ' + time + |
141 ", 0.01)") | 160 ', 0.01)') |
142 .throw("TypeError"); | 161 .throw('TypeError'); |
143 | 162 |
144 // One last test that prints out lots of digits for the time. | 163 // One last test that prints out lots of digits for the time. |
145 time = Math.PI / 100; | 164 time = Math.PI / 100; |
146 should(() => { | 165 should( |
147 g.gain.setValueCurveAtTime(curve, time, 0.01); | 166 () => { |
148 }, "setValueCurveAtTime(curve, " + time + ", 0.01)").throw("NotSupported
Error"); | 167 g.gain.setValueCurveAtTime(curve, time, 0.01); |
| 168 }, |
| 169 'setValueCurveAtTime(curve, ' + time + ', 0.01)') |
| 170 .throw('NotSupportedError'); |
149 | 171 |
150 task.done(); | 172 task.done(); |
151 }); | 173 }); |
152 | 174 |
153 audit.define("catch-exception", (task, should) => { | 175 audit.define('catch-exception', (task, should) => { |
154 // Verify that the curve isn't inserted into the time line even if we ca
tch the exception. | 176 // Verify that the curve isn't inserted into the time line even if we |
| 177 // catch the exception. |
155 let success = true; | 178 let success = true; |
156 let context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; | 179 let context = |
| 180 new OfflineAudioContext(1, testDurationFrames, sampleRate); |
157 let gain = context.createGain(); | 181 let gain = context.createGain(); |
158 let source = context.createBufferSource(); | 182 let source = context.createBufferSource(); |
159 let buffer = context.createBuffer(1, 1, context.sampleRate); | 183 let buffer = context.createBuffer(1, 1, context.sampleRate); |
160 buffer.getChannelData(0)[0] = 1; | 184 buffer.getChannelData(0)[0] = 1; |
161 source.buffer = buffer; | 185 source.buffer = buffer; |
162 source.loop = true; | 186 source.loop = true; |
163 | 187 |
164 source.connect(gain); | 188 source.connect(gain); |
165 gain.connect(context.destination); | 189 gain.connect(context.destination); |
166 | 190 |
167 gain.gain.setValueAtTime(1, 0); | 191 gain.gain.setValueAtTime(1, 0); |
168 try { | 192 try { |
169 // The value curve has an invalid element. This automation shouldn't b
e inserted into the | 193 // The value curve has an invalid element. This automation shouldn't |
170 // timeline at all. | 194 // be inserted into the timeline at all. |
171 gain.gain.setValueCurveAtTime(Float32Array.from([0, NaN]), 128 / conte
xt.sampleRate, .5); | 195 gain.gain.setValueCurveAtTime( |
| 196 Float32Array.from([0, NaN]), 128 / context.sampleRate, .5); |
172 } catch (e) { | 197 } catch (e) { |
173 }; | 198 }; |
174 source.start(); | 199 source.start(); |
175 | 200 |
176 context.startRendering().then(function (resultBuffer) { | 201 context.startRendering() |
177 // Since the setValueCurve wasn't inserted, the output should be exact
ly 1 for the entire | 202 .then(function(resultBuffer) { |
178 // duration. | 203 // Since the setValueCurve wasn't inserted, the output should be |
179 should(resultBuffer.getChannelData(0), | 204 // exactly 1 for the entire duration. |
180 "Handled setValueCurve exception so output") | 205 should( |
181 .beConstantValueOf(1); | 206 resultBuffer.getChannelData(0), |
| 207 'Handled setValueCurve exception so output') |
| 208 .beConstantValueOf(1); |
182 | 209 |
183 }).then(() => task.done()); | 210 }) |
| 211 .then(() => task.done()); |
184 }); | 212 }); |
185 | 213 |
186 audit.define("start-end", (task, should) => { | 214 audit.define('start-end', (task, should) => { |
187 let context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; | 215 let context = |
| 216 new OfflineAudioContext(1, testDurationFrames, sampleRate); |
188 let g = context.createGain(); | 217 let g = context.createGain(); |
189 let curve = new Float32Array(2); | 218 let curve = new Float32Array(2); |
190 | 219 |
191 // Verify that a setValueCurve can start at the end of an automation. | 220 // Verify that a setValueCurve can start at the end of an automation. |
192 let time = 0; | 221 let time = 0; |
193 let timeInterval = testDurationSec / 50; | 222 let timeInterval = testDurationSec / 50; |
194 should(() => { | 223 should(() => { |
195 g.gain.setValueAtTime(1, time); | 224 g.gain.setValueAtTime(1, time); |
196 }, "setValueAtTime(1, " + time + ")").notThrow(); | 225 }, 'setValueAtTime(1, ' + time + ')').notThrow(); |
197 | 226 |
198 time += timeInterval; | 227 time += timeInterval; |
199 should(() => { | 228 should(() => { |
200 g.gain.linearRampToValueAtTime(0, time); | 229 g.gain.linearRampToValueAtTime(0, time); |
201 }, "linearRampToValueAtTime(0, " + time + ")").notThrow(); | 230 }, 'linearRampToValueAtTime(0, ' + time + ')').notThrow(); |
202 | 231 |
203 // setValueCurve starts at the end of the linear ramp. This should be fi
ne. | 232 // setValueCurve starts at the end of the linear ramp. This should be |
204 should(() => { | 233 // fine. |
| 234 should( |
| 235 () => { |
205 g.gain.setValueCurveAtTime(curve, time, timeInterval); | 236 g.gain.setValueCurveAtTime(curve, time, timeInterval); |
206 }, | 237 }, |
207 "setValueCurveAtTime(..., " + time + ", " + timeInterval + ")") | 238 'setValueCurveAtTime(..., ' + time + ', ' + timeInterval + ')') |
208 .notThrow(); | 239 .notThrow(); |
209 | 240 |
210 // exponentialRamp ending one interval past the setValueCurve should be
fine. | 241 // exponentialRamp ending one interval past the setValueCurve should be |
211 time += 2*timeInterval; | 242 // fine. |
| 243 time += 2 * timeInterval; |
212 should(() => { | 244 should(() => { |
213 g.gain.exponentialRampToValueAtTime(1, time); | 245 g.gain.exponentialRampToValueAtTime(1, time); |
214 }, "exponentialRampToValueAtTime(1, " + time + ")").notThrow(); | 246 }, 'exponentialRampToValueAtTime(1, ' + time + ')').notThrow(); |
215 | 247 |
216 // setValueCurve starts at the end of the exponential ramp. This should
be fine. | 248 // setValueCurve starts at the end of the exponential ramp. This should |
217 should(() => { | 249 // be fine. |
| 250 should( |
| 251 () => { |
218 g.gain.setValueCurveAtTime(curve, time, timeInterval); | 252 g.gain.setValueCurveAtTime(curve, time, timeInterval); |
219 }, | 253 }, |
220 "setValueCurveAtTime(..., " + time + ", " + timeInterval + ")") | 254 'setValueCurveAtTime(..., ' + time + ', ' + timeInterval + ')') |
221 .notThrow(); | 255 .notThrow(); |
222 | 256 |
223 // setValueCurve at the end of the setValueCurve should be fine. | 257 // setValueCurve at the end of the setValueCurve should be fine. |
224 time += timeInterval; | 258 time += timeInterval; |
225 should(() => { | 259 should( |
| 260 () => { |
226 g.gain.setValueCurveAtTime(curve, time, timeInterval); | 261 g.gain.setValueCurveAtTime(curve, time, timeInterval); |
227 }, | 262 }, |
228 "setValueCurveAtTime(..., " + time + ", " + timeInterval + ")") | 263 'setValueCurveAtTime(..., ' + time + ', ' + timeInterval + ')') |
229 .notThrow(); | 264 .notThrow(); |
230 | 265 |
231 // setValueAtTime at the end of setValueCurve should be fine. | 266 // setValueAtTime at the end of setValueCurve should be fine. |
232 time += timeInterval; | 267 time += timeInterval; |
233 should(() => { | 268 should(() => { |
234 g.gain.setValueAtTime(0, time); | 269 g.gain.setValueAtTime(0, time); |
235 }, "setValueAtTime(0, " + time + ")").notThrow(); | 270 }, 'setValueAtTime(0, ' + time + ')').notThrow(); |
236 | 271 |
237 // setValueCurve at the end of setValueAtTime should be fine. | 272 // setValueCurve at the end of setValueAtTime should be fine. |
238 should(() => { | 273 should( |
| 274 () => { |
239 g.gain.setValueCurveAtTime(curve, time, timeInterval); | 275 g.gain.setValueCurveAtTime(curve, time, timeInterval); |
240 }, | 276 }, |
241 "setValueCurveAtTime(..., " + time + ", " + timeInterval + ")") | 277 'setValueCurveAtTime(..., ' + time + ', ' + timeInterval + ')') |
242 .notThrow(); | 278 .notThrow(); |
243 | 279 |
244 // setTarget starting at the end of setValueCurve should be fine. | 280 // setTarget starting at the end of setValueCurve should be fine. |
245 time += timeInterval; | 281 time += timeInterval; |
246 should(() => { | 282 should(() => { |
247 g.gain.setTargetAtTime(1, time, 1); | 283 g.gain.setTargetAtTime(1, time, 1); |
248 }, "setTargetAtTime(1, " + time + ", 1)").notThrow(); | 284 }, 'setTargetAtTime(1, ' + time + ', 1)').notThrow(); |
249 | 285 |
250 task.done(); | 286 task.done(); |
251 }); | 287 }); |
252 | 288 |
253 audit.define("curve lengths", (task, should) => { | 289 audit.define('curve lengths', (task, should) => { |
254 let context = new OfflineAudioContext(1, testDurationFrames, sampleRate)
; | 290 let context = |
| 291 new OfflineAudioContext(1, testDurationFrames, sampleRate); |
255 let g = context.createGain(); | 292 let g = context.createGain(); |
256 let time = 0; | 293 let time = 0; |
257 | 294 |
258 // Check for invalid curve lengths | 295 // Check for invalid curve lengths |
259 should(() => { | 296 should( |
| 297 () => { |
260 g.gain.setValueCurveAtTime(Float32Array.from([]), time, 0.01); | 298 g.gain.setValueCurveAtTime(Float32Array.from([]), time, 0.01); |
261 }, | 299 }, |
262 "setValueCurveAtTime([], " + time + ", 0.01)") | 300 'setValueCurveAtTime([], ' + time + ', 0.01)') |
263 .throw("InvalidStateError"); | 301 .throw('InvalidStateError'); |
| 302 |
| 303 should( |
| 304 () => { |
| 305 g.gain.setValueCurveAtTime(Float32Array.from([1]), time, 0.01); |
| 306 }, |
| 307 'setValueCurveAtTime([1], ' + time + ', 0.01)') |
| 308 .throw('InvalidStateError'); |
264 | 309 |
265 should(() => { | 310 should(() => { |
266 g.gain.setValueCurveAtTime(Float32Array.from([1]), time, 0.01); | 311 g.gain.setValueCurveAtTime(Float32Array.from([1, 2]), time, 0.01); |
267 }, | 312 }, 'setValueCurveAtTime([1,2], ' + time + ', 0.01)').notThrow(); |
268 "setValueCurveAtTime([1], " + time + ", 0.01)") | |
269 .throw("InvalidStateError"); | |
270 | |
271 should(() => { | |
272 g.gain.setValueCurveAtTime(Float32Array.from([1,2]), time, 0.01); | |
273 }, "setValueCurveAtTime([1,2], " + time + ", 0.01)").notThrow(); | |
274 | 313 |
275 task.done(); | 314 task.done(); |
276 }); | 315 }); |
277 | 316 |
278 audit.run(); | 317 audit.run(); |
279 </script> | 318 </script> |
280 </body> | 319 </body> |
281 </html> | 320 </html> |
282 | |
283 | |
284 | |
285 | |
286 | |
287 | |
288 | |
289 | |
290 | |
OLD | NEW |