OLD | NEW |
1 <!doctype html> | 1 <!DOCTYPE html> |
2 <html> | 2 <html> |
| 3 <head> |
| 4 <title> |
| 5 AudioParam Initial Events |
| 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 = 48000; |
| 16 // Number of frames in a rendering quantum. |
| 17 let quantumFrames = 128; |
| 18 // Test doesn't need to run for very long. |
| 19 let renderDuration = 0.2; |
| 20 let renderFrames = renderDuration * sampleRate; |
| 21 let automationEndTime = 0.1; |
3 | 22 |
4 <head> | 23 let audit = Audit.createTaskRunner(); |
5 <script src="../../resources/testharness.js"></script> | |
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 <title>AudioParam Initial Events </title> | |
11 </head> | |
12 | 24 |
13 <body> | 25 // The following tests start a ramp automation without an initial event. |
14 <script> | 26 // This should cause an initial event to be added implicitly to give a |
15 | 27 // starting point. |
16 var sampleRate = 48000; | 28 audit.define('linear-ramp', (task, should) => { |
17 // Number of frames in a rendering quantum. | 29 runTest('Linear ramp', should, { |
18 var quantumFrames = 128; | 30 automationFunction: function(node, value, time) { |
19 // Test doesn't need to run for very long. | |
20 var renderDuration = 0.2; | |
21 var renderFrames = renderDuration * sampleRate; | |
22 var automationEndTime = 0.1; | |
23 | |
24 var audit = Audit.createTaskRunner(); | |
25 | |
26 // The following tests start a ramp automation without an initial event. Th
is should cause an | |
27 // initial event to be added implicitly to give a starting point. | |
28 audit.define("linear-ramp", (task, should) => { | |
29 runTest("Linear ramp", should, { | |
30 automationFunction: function (node, value, time) { | |
31 node.gain.linearRampToValueAtTime(value, time); | 31 node.gain.linearRampToValueAtTime(value, time); |
32 }, | 32 }, |
33 referenceFunction: linearRamp, | 33 referenceFunction: linearRamp, |
34 // Experimentally determined threshold | 34 // Experimentally determined threshold |
35 threshold: { absoluteThreshold: 6.0003e-8 }, | 35 threshold: {absoluteThreshold: 6.0003e-8}, |
36 // The starting value of the gain node | 36 // The starting value of the gain node |
37 v0: 0.5, | 37 v0: 0.5, |
38 // The target value of the automation | 38 // The target value of the automation |
39 v1: 0, | 39 v1: 0, |
40 }) | 40 }).then(() => task.done()); |
41 .then(() => task.done()); | 41 }); |
42 }); | |
43 | 42 |
44 audit.define("exponential-ramp", (task, should) => { | 43 audit.define('exponential-ramp', (task, should) => { |
45 runTest("Exponential ramp", should, { | 44 runTest('Exponential ramp', should, { |
46 automationFunction: function (node, value, time) { | 45 automationFunction: function(node, value, time) { |
47 node.gain.exponentialRampToValueAtTime(value, time); | 46 node.gain.exponentialRampToValueAtTime(value, time); |
48 }, | 47 }, |
49 referenceFunction: exponentialRamp, | 48 referenceFunction: exponentialRamp, |
50 threshold: { absoluteThreshold: 2.3842e-6 }, | 49 threshold: {absoluteThreshold: 2.3842e-6}, |
51 v0: 0.5, | 50 v0: 0.5, |
52 v1: 2, | 51 v1: 2, |
53 }) | 52 }).then(() => task.done()); |
54 .then(() => task.done()); | 53 }); |
55 }); | |
56 | 54 |
57 // Same tests as above, but we delay the call to the automation function. Th
is is to verify that | 55 // Same tests as above, but we delay the call to the automation function. |
58 // the we still do the right thing after the context has started. | 56 // This is to verify that the we still do the right thing after the |
59 audit.define("delayed-linear-ramp", (task, should) => { | 57 // context has started. |
60 runTest("Delayed linear ramp", should, { | 58 audit.define('delayed-linear-ramp', (task, should) => { |
61 automationFunction: function (node, value, time) { | 59 runTest('Delayed linear ramp', should, { |
| 60 automationFunction: function(node, value, time) { |
62 node.gain.linearRampToValueAtTime(value, time); | 61 node.gain.linearRampToValueAtTime(value, time); |
63 }, | 62 }, |
64 referenceFunction: linearRamp, | 63 referenceFunction: linearRamp, |
65 // Experimentally determined threshold | 64 // Experimentally determined threshold |
66 threshold: { absoluteThreshold: 9.87968e-8 }, | 65 threshold: {absoluteThreshold: 9.87968e-8}, |
67 // The starting value of the gain node | 66 // The starting value of the gain node |
68 v0: 0.5, | 67 v0: 0.5, |
69 // The target value of the automation | 68 // The target value of the automation |
70 v1: 0, | 69 v1: 0, |
71 delay: quantumFrames / sampleRate | 70 delay: quantumFrames / sampleRate |
72 }) | 71 }).then(() => task.done()); |
73 .then(() => task.done()); | 72 }); |
74 }); | |
75 | 73 |
76 audit.define("delayed-exponential-ramp", (task, should) => { | 74 audit.define('delayed-exponential-ramp', (task, should) => { |
77 runTest("Delayed exponential ramp", should, { | 75 runTest('Delayed exponential ramp', should, { |
78 automationFunction: function (node, value, time) { | 76 automationFunction: function(node, value, time) { |
79 node.gain.exponentialRampToValueAtTime(value, time); | 77 node.gain.exponentialRampToValueAtTime(value, time); |
80 }, | 78 }, |
81 referenceFunction: exponentialRamp, | 79 referenceFunction: exponentialRamp, |
82 // Experimentally determined threshold | 80 // Experimentally determined threshold |
83 threshold: { absoluteThreshold: 1.3948e-5 }, | 81 threshold: {absoluteThreshold: 1.3948e-5}, |
84 // The starting value of the gain node | 82 // The starting value of the gain node |
85 v0: 0.5, | 83 v0: 0.5, |
86 // The target value of the automation | 84 // The target value of the automation |
87 v1: 2, | 85 v1: 2, |
88 delay: quantumFrames / sampleRate | 86 delay: quantumFrames / sampleRate |
89 }) | 87 }).then(() => task.done()); |
90 .then(() => task.done()); | 88 }); |
91 }); | |
92 | 89 |
93 audit.run(); | 90 audit.run(); |
94 | 91 |
95 // Generate the expected waveform for a linear ramp starting from the value
|v0|, ramping to | 92 // Generate the expected waveform for a linear ramp starting from the |
96 // |v1| at time |endTime|. The time of |v0| is assumed to be 0. |nFrames|
is how many frames | 93 // value |v0|, ramping to |v1| at time |endTime|. The time of |v0| is |
97 // to generate. | 94 // assumed to be 0. |nFrames| is how many frames to generate. |
98 function linearRamp(v0, v1, startTime, endTime, nFrames) { | 95 function linearRamp(v0, v1, startTime, endTime, nFrames) { |
99 var expected = createLinearRampArray(startTime, endTime, v0, v1, sampleRat
e); | 96 let expected = |
100 var preFiller = new Array(Math.floor(startTime * sampleRate)); | 97 createLinearRampArray(startTime, endTime, v0, v1, sampleRate); |
101 var postFiller = new Array(nFrames - Math.ceil(endTime * sampleRate)); | 98 let preFiller = new Array(Math.floor(startTime * sampleRate)); |
102 preFiller.fill(v0); | 99 let postFiller = new Array(nFrames - Math.ceil(endTime * sampleRate)); |
103 return preFiller.concat(expected.concat(postFiller.fill(v1))); | 100 preFiller.fill(v0); |
104 } | 101 return preFiller.concat(expected.concat(postFiller.fill(v1))); |
105 | |
106 // Generate the expected waveform for an exponential ramp starting from the
value |v0|, | |
107 // ramping to |v1| at time |endTime|. The time of |v0| is assumed to be 0.
|nFrames| is how | |
108 // many frames to generate. | |
109 function exponentialRamp(v0, v1, startTime, endTime, nFrames) { | |
110 var expected = createExponentialRampArray(startTime, endTime, v0, v1, samp
leRate); | |
111 var preFiller = new Array(Math.floor(startTime * sampleRate)); | |
112 preFiller.fill(v0); | |
113 var postFiller = new Array(nFrames - Math.ceil(endTime * sampleRate)); | |
114 return preFiller.concat(expected.concat(postFiller.fill(v1))); | |
115 } | |
116 | |
117 // Run an automation test. |message| is the message to use for printing the
results. |options| | |
118 // is a property bag containing the configuration of the test including the
following: | |
119 // | |
120 // automationFunction - automation function to use, | |
121 // referenceFunction - function generating the expected result | |
122 // threshold - comparison threshold | |
123 // v0 - starting value | |
124 // v1 - end value for automation | |
125 function runTest(message, should, options) { | |
126 var automationFunction = options.automationFunction; | |
127 var referenceFunction = options.referenceFunction; | |
128 var threshold = options.threshold; | |
129 var v0 = options.v0; | |
130 var v1 = options.v1; | |
131 var delay = options.delay; | |
132 | |
133 var context = new OfflineAudioContext(1, renderFrames, sampleRate); | |
134 | |
135 // A constant source of amplitude 1. | |
136 var source = context.createBufferSource(); | |
137 source.buffer = createConstantBuffer(context, 1, 1); | |
138 source.loop = true; | |
139 | |
140 // Automation is applied to a gain node | |
141 var gain = context.createGain(); | |
142 gain.gain.value = v0; | |
143 | |
144 // Delay start of automation, if requested | |
145 if (delay) { | |
146 context.suspend(options.delay).then(function () { | |
147 automationFunction(gain, v1, automationEndTime); | |
148 context.resume(); | |
149 }); | |
150 } else { | |
151 automationFunction(gain, v1, automationEndTime); | |
152 } | 102 } |
153 | 103 |
154 source.connect(gain); | 104 // Generate the expected waveform for an exponential ramp starting from |
155 gain.connect(context.destination); | 105 // the value |v0|, ramping to |v1| at time |endTime|. The time of |v0| is |
| 106 // assumed to be 0. |nFrames| is how many frames to generate. |
| 107 function exponentialRamp(v0, v1, startTime, endTime, nFrames) { |
| 108 let expected = |
| 109 createExponentialRampArray(startTime, endTime, v0, v1, sampleRate); |
| 110 let preFiller = new Array(Math.floor(startTime * sampleRate)); |
| 111 preFiller.fill(v0); |
| 112 let postFiller = new Array(nFrames - Math.ceil(endTime * sampleRate)); |
| 113 return preFiller.concat(expected.concat(postFiller.fill(v1))); |
| 114 } |
156 | 115 |
157 source.start(); | 116 // Run an automation test. |message| is the message to use for printing |
| 117 // the results. |options| is a property bag containing the configuration |
| 118 // of the test including the following: |
| 119 // |
| 120 // automationFunction - automation function to use, |
| 121 // referenceFunction - function generating the expected result |
| 122 // threshold - comparison threshold |
| 123 // v0 - starting value |
| 124 // v1 - end value for automation |
| 125 function runTest(message, should, options) { |
| 126 let automationFunction = options.automationFunction; |
| 127 let referenceFunction = options.referenceFunction; |
| 128 let threshold = options.threshold; |
| 129 let v0 = options.v0; |
| 130 let v1 = options.v1; |
| 131 let delay = options.delay; |
158 | 132 |
159 return context.startRendering() | 133 let context = new OfflineAudioContext(1, renderFrames, sampleRate); |
160 .then(function (resultBuffer) { | 134 |
161 var result = resultBuffer.getChannelData(0); | 135 // A constant source of amplitude 1. |
162 var expected = referenceFunction(v0, v1, delay ? delay : 0, automation
EndTime, renderFrames); | 136 let source = context.createBufferSource(); |
| 137 source.buffer = createConstantBuffer(context, 1, 1); |
| 138 source.loop = true; |
| 139 |
| 140 // Automation is applied to a gain node |
| 141 let gain = context.createGain(); |
| 142 gain.gain.value = v0; |
| 143 |
| 144 // Delay start of automation, if requested |
| 145 if (delay) { |
| 146 context.suspend(options.delay).then(function() { |
| 147 automationFunction(gain, v1, automationEndTime); |
| 148 context.resume(); |
| 149 }); |
| 150 } else { |
| 151 automationFunction(gain, v1, automationEndTime); |
| 152 } |
| 153 |
| 154 source.connect(gain); |
| 155 gain.connect(context.destination); |
| 156 |
| 157 source.start(); |
| 158 |
| 159 return context.startRendering().then(function(resultBuffer) { |
| 160 let result = resultBuffer.getChannelData(0); |
| 161 let expected = referenceFunction( |
| 162 v0, v1, delay ? delay : 0, automationEndTime, renderFrames); |
163 should(result, message).beCloseToArray(expected, threshold); | 163 should(result, message).beCloseToArray(expected, threshold); |
164 }); | 164 }); |
165 } | 165 } |
166 </script> | 166 </script> |
167 </body> | 167 </body> |
168 | |
169 </html> | 168 </html> |
OLD | NEW |