OLD | NEW |
| (Empty) |
1 <!doctype html> | |
2 <html> | |
3 <head> | |
4 <title>Test PeriodicWave Normalization</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 </head> | |
10 | |
11 <body> | |
12 <script> | |
13 description("Test PeriodicWave Normalization"); | |
14 window.jsTestIsAsync = true; | |
15 | |
16 var sampleRate = 48000; | |
17 var renderFrames = 6000; | |
18 var context; | |
19 var audit = Audit.createTaskRunner(); | |
20 | |
21 var testSet = [ | |
22 // Test the default case where the two-arg createPeriodicWave is called.
The waveform | |
23 // should be normalized. | |
24 { | |
25 name: "option-default/normalized", | |
26 // This option is treated specially; it means that the two-arg functio
n is called. | |
27 option: "NONE", | |
28 // Somewhat arbitrary except that resulting waveform should have ampli
tude greater than | |
29 // 1. And we don't want a simple sine wave because that always has ma
x amplitude of 1. | |
30 realCoef: [0, -1, 1], | |
31 threshold: 1e-5, | |
32 expectedMax: 1 | |
33 }, | |
34 | |
35 { | |
36 name: "option-null/normalized", | |
37 option: null, | |
38 // Somewhat arbitrary except that resulting waveform should have ampli
tude greater than | |
39 // 1. And we don't want a simple sine wave because that always has ma
x amplitude of 1. | |
40 realCoef: [0, -1, 1], | |
41 threshold: 1e-5, | |
42 expectedMax: 1 | |
43 }, | |
44 | |
45 // Explicitly set to false. Waveform should be normalized. | |
46 { | |
47 name: "false/normalized", | |
48 option: { | |
49 disableNormalization: false | |
50 }, | |
51 realCoef: [0, -1, 1], | |
52 threshold: 1e-5, | |
53 expectedMax: 1 | |
54 }, | |
55 | |
56 // Explicitly disable normalization. Waveform is not normalized. | |
57 { | |
58 name: "true/unnormalized", | |
59 option: { | |
60 disableNormalization: true | |
61 }, | |
62 // Somewhat arbitrary except that resulting waveform should have ampli
tude very clearly | |
63 // greater than 1. | |
64 realCoef: [0, 10], | |
65 threshold: 1e-5, | |
66 expectedMax: 10 | |
67 }, | |
68 | |
69 // Explicitly set to some value that is not false. Waveform should NOT
be normalized. | |
70 { | |
71 name: "foo/unnormalized", | |
72 option: { | |
73 disableNormalization: "foo" | |
74 }, | |
75 realCoef: [0, 10], | |
76 threshold: 1e-5, | |
77 expectedMax: 10 | |
78 }, | |
79 | |
80 // Explicitly set to null, which is the same as false. Waveform is norm
alized. | |
81 { | |
82 name: "null/unnormalized", | |
83 option: { | |
84 disableNormalization: null | |
85 }, | |
86 realCoef: [0, 1, -1], | |
87 threshold: 1e-5, | |
88 expectedMax: 1 | |
89 }, | |
90 | |
91 // Pass in a random dictionary not using our key. Waveform should be no
rmalized. | |
92 { | |
93 name: "random-key-value/normalized", | |
94 option: { | |
95 randomKey: true | |
96 }, | |
97 realCoef: [0, -1, 1], | |
98 threshold: 1e-5, | |
99 expectedMax: 1 | |
100 }, | |
101 | |
102 // Set options to several random keys. Waveform must be normalized. | |
103 { | |
104 name: "more-random-keys/normalized", | |
105 option: { | |
106 key1: "value1", | |
107 key2: 42 | |
108 }, | |
109 realCoef: [0, 1, -1], | |
110 threshold: 1e-5, | |
111 expectedMax: 1 | |
112 }, | |
113 | |
114 // Set option to include our key (set to true) amongst a bunch of others
. Waveform is NOT normalized. | |
115 { | |
116 name: "true-with-random-keys/unnormalized", | |
117 option: { | |
118 key1: "value1", | |
119 disableNormalization: true | |
120 }, | |
121 realCoef: [0, 10], | |
122 threshold: 1e-5, | |
123 expectedMax: 10 | |
124 }, | |
125 | |
126 // Set option to include our key (set to false) amongst a bunch of other
s. Waveform is normalized. | |
127 { | |
128 name: "false-with-random-keys/normalized", | |
129 option: { | |
130 key1: "value1", | |
131 disableNormalization: false | |
132 }, | |
133 realCoef: [0, 10], | |
134 threshold: 1e-5, | |
135 expectedMax: 1 | |
136 }, | |
137 | |
138 // Set option to a non-dictionary. Waveform is normalized. | |
139 { | |
140 name: "non-dict/normalized", | |
141 option : [1, 2, 3], | |
142 realCoef: [0, 1, -1], | |
143 threshold: 1e-5, | |
144 expectedMax: 1 | |
145 }, | |
146 ]; | |
147 | |
148 function arrayMax(array) { | |
149 return array.reduce(function (reducedValue, currentValue) { | |
150 return Math.max(reducedValue, Math.abs(currentValue)); | |
151 }, -1); | |
152 } | |
153 | |
154 function createAndRunAudioGraph(options, realCoef, imagCoef, verify) { | |
155 context = new OfflineAudioContext(1, renderFrames, sampleRate); | |
156 var osc = context.createOscillator(); | |
157 | |
158 var r = new Float32Array(realCoef); | |
159 var i = new Float32Array(imagCoef); | |
160 | |
161 var wave; | |
162 | |
163 // If options is "NONE", we want to be sure to call the two-arg createPe
riodicWave to make | |
164 // sure the default method works as expected. | |
165 if (options === "NONE") { | |
166 //console.log("2-arg: " + options); | |
167 wave = context.createPeriodicWave(r, i); | |
168 } else { | |
169 //console.log("3-arg: " + options); | |
170 wave = context.createPeriodicWave(r, i, options); | |
171 } | |
172 | |
173 osc.setPeriodicWave(wave); | |
174 osc.connect(context.destination); | |
175 osc.start(); | |
176 | |
177 return context.startRendering().then(verify); | |
178 } | |
179 | |
180 // Define a test function from the given test parameter. This is used as
the Audit.defineTask | |
181 // task function. | |
182 function defineTest(test) { | |
183 return function (done) { | |
184 var imagCoef = new Float32Array(test.realCoef.length); | |
185 createAndRunAudioGraph(test.option, test.realCoef, imagCoef, function
(result) { | |
186 var prefix; | |
187 | |
188 // Try to print out the test.option in a reasonably nice but explici
t way. | |
189 if (test.option === "NONE") { | |
190 prefix = ""; | |
191 } else if (Array.isArray(test.option)) { | |
192 prefix = "[" + test.option + "]: "; | |
193 } else { | |
194 prefix = JSON.stringify(test.option) + ": "; | |
195 } | |
196 | |
197 Should(prefix + "amplitude", arrayMax(result.getChannelData(0))) | |
198 .beCloseTo(test.expectedMax, test.threshold); | |
199 }).then(done); | |
200 }; | |
201 } | |
202 | |
203 // Ensure the actual Audit test name is unique by prepending an index to t
he provided test | |
204 // name. | |
205 function actualTestName(name, index) { | |
206 return index + ":" + name; | |
207 } | |
208 | |
209 function defineTasks() { | |
210 for (var k = 0; k < testSet.length; ++k) { | |
211 var test = testSet[k]; | |
212 audit.defineTask(actualTestName(test.name, k), defineTest(test)); | |
213 } | |
214 | |
215 // Explicitly define the last test to finish up everything. | |
216 audit.defineTask(actualTestName("finish-tests", testSet.length), functio
n (done) { | |
217 finishJSTest(); | |
218 done(); | |
219 }); | |
220 } | |
221 | |
222 // Run all of the tests defined in testSet. | |
223 function runAuditTests() { | |
224 var tests = testSet.map(function (value, index) { | |
225 return actualTestName(value.name, index); | |
226 }).concat(actualTestName("finish-tests", testSet.length)); | |
227 audit.runTasks.apply(audit, tests); | |
228 }; | |
229 | |
230 defineTasks(); | |
231 runAuditTests(); | |
232 | |
233 successfullyParsed = true; | |
234 </script> | |
235 </body> | |
236 </html> | |
OLD | NEW |