| 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 |