OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <html> | 2 <html> |
| 3 <head> |
| 4 <title> |
| 5 audioparam-method-chaining.html |
| 6 </title> |
| 7 <script src="../../resources/testharness.js"></script> |
| 8 <script src="../../resources/testharnessreport.js"></script> |
| 9 <script src="../resources/audit-util.js"></script> |
| 10 <script src="../resources/audit.js"></script> |
| 11 <script src="../resources/audioparam-testing.js"></script> |
| 12 </head> |
| 13 <body> |
| 14 <script id="layout-test-code"> |
| 15 let sampleRate = 8000; |
3 | 16 |
4 <head> | 17 // Create a dummy array for setValueCurveAtTime method. |
5 <script src="../../resources/testharness.js"></script> | 18 let curveArray = new Float32Array([5.0, 6.0]); |
6 <script src="../../resources/testharnessreport.js"></script> | |
7 <script src="../resources/audit-util.js"></script> | |
8 <script src="../resources/audit.js"></script> | |
9 <script src="../resources/audioparam-testing.js"></script> | |
10 </head> | |
11 | 19 |
12 <body> | 20 // AudioNode dictionary with associated dummy arguments. |
13 <script> | 21 let methodDictionary = [ |
| 22 {name: 'setValueAtTime', args: [1.0, 0.0]}, |
| 23 {name: 'linearRampToValueAtTime', args: [2.0, 1.0]}, |
| 24 {name: 'exponentialRampToValueAtTime', args: [3.0, 2.0]}, |
| 25 {name: 'setTargetAtTime', args: [4.0, 2.0, 0.5]}, |
| 26 {name: 'setValueCurveAtTime', args: [curveArray, 5.0, 1.0]}, |
| 27 {name: 'cancelScheduledValues', args: [6.0]} |
| 28 ]; |
14 | 29 |
15 var sampleRate = 8000; | 30 let audit = Audit.createTaskRunner(); |
16 | 31 |
17 // Create a dummy array for setValueCurveAtTime method. | 32 // Task: testing entries from the dictionary. |
18 var curveArray = new Float32Array([5.0, 6.0]); | 33 audit.define('from-dictionary', (task, should) => { |
| 34 let context = new AudioContext(); |
19 | 35 |
20 // AudioNode dictionary with associated dummy arguments. | 36 methodDictionary.forEach(function(method) { |
21 var methodDictionary = [ | 37 let sourceParam = context.createGain().gain; |
22 { name: 'setValueAtTime', args: [1.0, 0.0] }, | 38 should( |
23 { name: 'linearRampToValueAtTime', args: [2.0, 1.0] }, | 39 sourceParam === sourceParam[method.name](...method.args), |
24 { name: 'exponentialRampToValueAtTime', args: [3.0, 2.0] }, | 40 'The return value of ' + sourceParam.constructor.name + '.' + |
25 { name: 'setTargetAtTime', args: [4.0, 2.0, 0.5] }, | 41 method.name + '()' + |
26 { name: 'setValueCurveAtTime', args: [curveArray, 5.0, 1.0] }, | 42 ' matches the source AudioParam') |
27 { name: 'cancelScheduledValues', args: [6.0] } | 43 .beEqualTo(true); |
28 ]; | |
29 | 44 |
30 var audit = Audit.createTaskRunner(); | 45 }); |
31 | 46 |
32 // Task: testing entries from the dictionary. | 47 task.done(); |
33 audit.define('from-dictionary', (task, should) => { | |
34 var context = new AudioContext(); | |
35 | |
36 methodDictionary.forEach(function (method) { | |
37 var sourceParam = context.createGain().gain; | |
38 should(sourceParam === sourceParam[method.name](...method.args), | |
39 'The return value of ' + sourceParam.constructor.name + '.' + | |
40 method.name + '()' + ' matches the source AudioParam') | |
41 .beEqualTo(true); | |
42 | |
43 }); | 48 }); |
44 | 49 |
45 task.done(); | 50 // Task: test method chaining with invalid operation. |
46 }); | 51 audit.define('invalid-operation', (task, should) => { |
| 52 let context = new OfflineAudioContext(1, sampleRate, sampleRate); |
| 53 let osc = context.createOscillator(); |
| 54 let amp1 = context.createGain(); |
| 55 let amp2 = context.createGain(); |
47 | 56 |
48 // Task: test method chaining with invalid operation. | 57 osc.connect(amp1); |
49 audit.define('invalid-operation', (task, should) => { | 58 osc.connect(amp2); |
50 var context = new OfflineAudioContext(1, sampleRate, sampleRate); | 59 amp1.connect(context.destination); |
51 var osc = context.createOscillator(); | 60 amp2.connect(context.destination); |
52 var amp1 = context.createGain(); | |
53 var amp2 = context.createGain(); | |
54 | |
55 osc.connect(amp1); | |
56 osc.connect(amp2); | |
57 amp1.connect(context.destination); | |
58 amp2.connect(context.destination); | |
59 | 61 |
60 // The first operation fails with an exception, thus the second one | 62 // The first operation fails with an exception, thus the second one |
61 // should not have effect on the parameter value. Instead, it should | 63 // should not have effect on the parameter value. Instead, it should |
62 // maintain the default value of 1.0. | 64 // maintain the default value of 1.0. |
63 should(function () { | 65 should( |
64 amp1.gain | 66 function() { |
65 .setValueAtTime(0.25, -1.0) | 67 amp1.gain.setValueAtTime(0.25, -1.0) |
66 .linearRampToValueAtTime(2.0, 1.0); | 68 .linearRampToValueAtTime(2.0, 1.0); |
67 }, | 69 }, |
68 'Calling setValueAtTime() with a negative end time') | 70 'Calling setValueAtTime() with a negative end time') |
69 .throw('InvalidAccessError'); | 71 .throw('InvalidAccessError'); |
70 | 72 |
71 // The first operation succeeds but the second fails due to zero target | 73 // The first operation succeeds but the second fails due to zero target |
72 // value for the exponential ramp. Thus only the first should have effect | 74 // value for the exponential ramp. Thus only the first should have |
73 // on the parameter value, setting the value to 0.5. | 75 // effect on the parameter value, setting the value to 0.5. |
74 should(function () { | 76 should( |
75 amp2.gain | 77 function() { |
76 .setValueAtTime(0.5, 0.0) | 78 amp2.gain.setValueAtTime(0.5, 0.0).exponentialRampToValueAtTime( |
77 .exponentialRampToValueAtTime(0.0, 1.0); | 79 0.0, 1.0); |
78 }, | 80 }, |
79 'Calling exponentialRampToValueAtTime() with a zero target value') | 81 'Calling exponentialRampToValueAtTime() with a zero target value') |
80 .throw('InvalidAccessError'); | 82 .throw('InvalidAccessError'); |
81 | 83 |
82 osc.start(); | 84 osc.start(); |
83 osc.stop(1.0); | 85 osc.stop(1.0); |
84 | 86 |
85 context.startRendering().then(function (buffer) { | 87 context.startRendering() |
86 should(amp1.gain.value, 'The gain value of the first gain node').beEqual
To(1.0); | 88 .then(function(buffer) { |
87 should(amp2.gain.value, 'The gain value of the second gain node').beEqua
lTo(0.5); | 89 should(amp1.gain.value, 'The gain value of the first gain node') |
88 }).then(() => task.done()); | 90 .beEqualTo(1.0); |
89 }); | 91 should(amp2.gain.value, 'The gain value of the second gain node') |
| 92 .beEqualTo(0.5); |
| 93 }) |
| 94 .then(() => task.done()); |
| 95 }); |
90 | 96 |
91 // Task: verify if the method chaining actually works. Create an arbitrary | 97 // Task: verify if the method chaining actually works. Create an arbitrary |
92 // envelope and compare the result with the expected one created by JS code. | 98 // envelope and compare the result with the expected one created by JS |
93 audit.define('verification', (task, should) => { | 99 // code. |
94 var context = new OfflineAudioContext(1, sampleRate * 4, sampleRate); | 100 audit.define('verification', (task, should) => { |
95 var constantBuffer = createConstantBuffer(context, 1, 1.0); | 101 let context = new OfflineAudioContext(1, sampleRate * 4, sampleRate); |
| 102 let constantBuffer = createConstantBuffer(context, 1, 1.0); |
96 | 103 |
97 var source = context.createBufferSource(); | 104 let source = context.createBufferSource(); |
98 source.buffer = constantBuffer; | 105 source.buffer = constantBuffer; |
99 source.loop = true; | 106 source.loop = true; |
100 | 107 |
101 var envelope = context.createGain(); | 108 let envelope = context.createGain(); |
102 | 109 |
103 source.connect(envelope); | 110 source.connect(envelope); |
104 envelope.connect(context.destination); | 111 envelope.connect(context.destination); |
105 | 112 |
106 envelope.gain | 113 envelope.gain.setValueAtTime(0.0, 0.0) |
107 .setValueAtTime(0.0, 0.0) | 114 .linearRampToValueAtTime(1.0, 1.0) |
108 .linearRampToValueAtTime(1.0, 1.0) | 115 .exponentialRampToValueAtTime(0.5, 2.0) |
109 .exponentialRampToValueAtTime(0.5, 2.0) | 116 .setTargetAtTime(0.001, 2.0, 0.5); |
110 .setTargetAtTime(0.001, 2.0, 0.5); | |
111 | 117 |
112 source.start(); | 118 source.start(); |
113 | 119 |
114 context.startRendering().then(function (buffer) { | 120 context.startRendering() |
115 var expectedEnvelope = createLinearRampArray(0.0, 1.0, 0.0, 1.0, sampleR
ate); | 121 .then(function(buffer) { |
116 expectedEnvelope.push(...createExponentialRampArray(1.0, 2.0, 1.0, 0.5,
sampleRate)); | 122 let expectedEnvelope = |
117 expectedEnvelope.push(...createExponentialApproachArray(2.0, 4.0, 0.5, 0
.001, sampleRate, 0.5)); | 123 createLinearRampArray(0.0, 1.0, 0.0, 1.0, sampleRate); |
| 124 expectedEnvelope.push(...createExponentialRampArray( |
| 125 1.0, 2.0, 1.0, 0.5, sampleRate)); |
| 126 expectedEnvelope.push(...createExponentialApproachArray( |
| 127 2.0, 4.0, 0.5, 0.001, sampleRate, 0.5)); |
118 | 128 |
119 // There are slight differences between JS implementation of AudioParam | 129 // There are slight differences between JS implementation of |
120 // envelope and the internal implementation. (i.e. double/float and | 130 // AudioParam envelope and the internal implementation. (i.e. |
121 // rounding up) The error threshold is adjusted empirically through | 131 // double/float and rounding up) The error threshold is adjusted |
122 // the local testing. | 132 // empirically through the local testing. |
123 should(buffer.getChannelData(0), 'The rendered envelope') | 133 should(buffer.getChannelData(0), 'The rendered envelope') |
124 .beCloseToArray(expectedEnvelope, {absoluteThreshold: 4.0532e-6}); | 134 .beCloseToArray( |
125 }).then(() => task.done()); | 135 expectedEnvelope, {absoluteThreshold: 4.0532e-6}); |
126 }); | 136 }) |
| 137 .then(() => task.done()); |
| 138 }); |
127 | 139 |
128 audit.run(); | 140 audit.run(); |
129 </script> | 141 </script> |
130 </body> | 142 </body> |
131 | |
132 </html> | 143 </html> |
OLD | NEW |