| OLD | NEW |
| 1 <!doctype html> | 1 <!doctype html> |
| 2 <html> | 2 <html> |
| 3 <head> | 3 <head> |
| 4 <script src="../../resources/testharness.js"></script> | 4 <script src="../../resources/testharness.js"></script> |
| 5 <script src="../../resources/testharnessreport.js"></script> | 5 <script src="../../resources/testharnessreport.js"></script> |
| 6 <script src="../resources/audit-util.js"></script> | 6 <script src="../resources/audit-util.js"></script> |
| 7 <script src="../resources/audio-testing.js"></script> | 7 <script src="../resources/audit.js"></script> |
| 8 <title>Test Multiple Calls to getFloatFrequencyData</title> | 8 <title>Test Multiple Calls to getFloatFrequencyData</title> |
| 9 </head> | 9 </head> |
| 10 | 10 |
| 11 <body> | 11 <body> |
| 12 <script> | 12 <script> |
| 13 var sampleRate = 48000; | 13 var sampleRate = 48000; |
| 14 // Render enough data to run the test. | 14 // Render enough data to run the test. |
| 15 var renderFrames = 2*1024; | 15 var renderFrames = 2*1024; |
| 16 var renderDuration = renderFrames / sampleRate; | 16 var renderDuration = renderFrames / sampleRate; |
| 17 | 17 |
| 18 var audit = Audit.createTaskRunner(); | 18 var audit = Audit.createTaskRunner(); |
| 19 | 19 |
| 20 audit.defineTask("test", function (done) { | 20 audit.define("test", (task, should) => { |
| 21 | 21 |
| 22 var context = new OfflineAudioContext(1, renderFrames, sampleRate); | 22 var context = new OfflineAudioContext(1, renderFrames, sampleRate); |
| 23 | 23 |
| 24 // Use sawtooth oscillator as the source because it has quite a bit of h
armonic content. | 24 // Use sawtooth oscillator as the source because it has quite a bit of h
armonic content. |
| 25 // Otherwise, the type doesn't really matter. | 25 // Otherwise, the type doesn't really matter. |
| 26 var osc = context.createOscillator(); | 26 var osc = context.createOscillator(); |
| 27 osc.type = "sawtooth"; | 27 osc.type = "sawtooth"; |
| 28 | 28 |
| 29 // Create an analyser with 256-point FFT. The FFT size doesn't really m
atter much. | 29 // Create an analyser with 256-point FFT. The FFT size doesn't really m
atter much. |
| 30 var analyser = context.createAnalyser(); | 30 var analyser = context.createAnalyser(); |
| 31 analyser.fftSize = 256; | 31 analyser.fftSize = 256; |
| 32 | 32 |
| 33 osc.connect(analyser); | 33 osc.connect(analyser); |
| 34 analyser.connect(context.destination); | 34 analyser.connect(context.destination); |
| 35 | 35 |
| 36 var success = true; | 36 var success = true; |
| 37 | 37 |
| 38 // Suspend after getting a full analyser frame. (Not really necessary, b
ut it's nice that | 38 // Suspend after getting a full analyser frame. (Not really necessary, b
ut it's nice that |
| 39 // the frame doesn't include any initial zeroes. | 39 // the frame doesn't include any initial zeroes. |
| 40 var suspendFrame = analyser.fftSize; | 40 var suspendFrame = analyser.fftSize; |
| 41 context.suspend(suspendFrame / sampleRate).then(function () { | 41 context.suspend(suspendFrame / sampleRate).then(function () { |
| 42 // Test successive calls to getFloatFrequencyData in the same renderin
g quantum. | 42 // Test successive calls to getFloatFrequencyData in the same renderin
g quantum. |
| 43 var f1 = new Float32Array(analyser.frequencyBinCount); | 43 let f1 = new Float32Array(analyser.frequencyBinCount); |
| 44 var f2 = new Float32Array(analyser.frequencyBinCount); | 44 let f2 = new Float32Array(analyser.frequencyBinCount); |
| 45 | 45 |
| 46 analyser.getFloatFrequencyData(f1); | 46 analyser.getFloatFrequencyData(f1); |
| 47 analyser.getFloatFrequencyData(f2); | 47 analyser.getFloatFrequencyData(f2); |
| 48 | 48 should(f2, "Second call to getFloatFrequencyData") |
| 49 success = Should("Second call to getFloatFrequencyData", f2, { | 49 .beEqualToArray(f1); |
| 50 precision: 5 | |
| 51 }).beEqualToArray(f1) && success; | |
| 52 }).then(context.resume.bind(context)); | 50 }).then(context.resume.bind(context)); |
| 53 | 51 |
| 54 suspendFrame += 128; | 52 suspendFrame += 128; |
| 55 context.suspend(suspendFrame / sampleRate).then(function () { | 53 context.suspend(suspendFrame / sampleRate).then(function () { |
| 56 // Test successive calls to getByteFrequencyData in the same rendering
quantum. | 54 // Test successive calls to getByteFrequencyData in the same rendering
quantum. |
| 57 var f1 = new Uint8Array(analyser.frequencyBinCount); | 55 let f1 = new Uint8Array(analyser.frequencyBinCount); |
| 58 var f2 = new Uint8Array(analyser.frequencyBinCount); | 56 let f2 = new Uint8Array(analyser.frequencyBinCount); |
| 59 | 57 |
| 60 analyser.getByteFrequencyData(f1); | 58 analyser.getByteFrequencyData(f1); |
| 61 analyser.getByteFrequencyData(f2); | 59 analyser.getByteFrequencyData(f2); |
| 62 | 60 |
| 63 success = Should("Second call to getByteFrequencyData", f2) | 61 should(f2, "Second call to getByteFrequencyData") |
| 64 .beEqualToArray(f1) && success; | 62 .beEqualToArray(f1); |
| 65 }).then(context.resume.bind(context)); | 63 }).then(context.resume.bind(context)); |
| 66 | 64 |
| 67 suspendFrame += 128; | 65 suspendFrame += 128; |
| 68 context.suspend(suspendFrame / sampleRate).then(function () { | 66 context.suspend(suspendFrame / sampleRate).then(function () { |
| 69 // Test calls to getFloatFrequencyData followed by getByteFrequencyDat
a. The float data, | 67 // Test calls to getFloatFrequencyData followed by getByteFrequencyDat
a. The float data, |
| 70 // when converted to byte values should be identical to the result fro
m | 68 // when converted to byte values should be identical to the result fro
m |
| 71 // getByteFrequencyData. | 69 // getByteFrequencyData. |
| 72 var f1 = new Float32Array(analyser.frequencyBinCount); | 70 let f1 = new Float32Array(analyser.frequencyBinCount); |
| 73 var f2 = new Uint8Array(analyser.frequencyBinCount); | 71 let f2 = new Uint8Array(analyser.frequencyBinCount); |
| 74 | 72 |
| 75 analyser.getFloatFrequencyData(f1); | 73 analyser.getFloatFrequencyData(f1); |
| 76 analyser.getByteFrequencyData(f2); | 74 analyser.getByteFrequencyData(f2); |
| 77 | 75 |
| 78 var byteValuesFromFloat = convertFloatToByte(f1, analyser.minDecibels,
analyser.maxDecibels); | 76 var byteValuesFromFloat = convertFloatToByte(f1, analyser.minDecibels,
analyser.maxDecibels); |
| 79 success = Should("Output of getByteFrequencyData after getFloatFrequen
cyData", | 77 should(byteValuesFromFloat, "Output of getByteFrequencyData after getF
loatFrequencyData") |
| 80 byteValuesFromFloat) | 78 .beEqualToArray(f2); |
| 81 .beEqualToArray(f2) && success; | |
| 82 }).then(context.resume.bind(context)); | 79 }).then(context.resume.bind(context)); |
| 83 | 80 |
| 84 suspendFrame += 128; | 81 suspendFrame += 128; |
| 85 context.suspend(suspendFrame / sampleRate).then(function () { | 82 context.suspend(suspendFrame / sampleRate).then(function () { |
| 86 // Test calls to getByteFrequencyData followed by getFloatFrequencyDat
a. The float data, | 83 // Test calls to getByteFrequencyData followed by getFloatFrequencyDat
a. The float data, |
| 87 // when converted to byte values should be identical to the result fro
m | 84 // when converted to byte values should be identical to the result fro
m |
| 88 // getByteFrequencyData. | 85 // getByteFrequencyData. |
| 89 var f1 = new Uint8Array(analyser.frequencyBinCount); | 86 var f1 = new Uint8Array(analyser.frequencyBinCount); |
| 90 var f2 = new Float32Array(analyser.frequencyBinCount); | 87 var f2 = new Float32Array(analyser.frequencyBinCount); |
| 91 | 88 |
| 92 analyser.getByteFrequencyData(f1); | 89 analyser.getByteFrequencyData(f1); |
| 93 analyser.getFloatFrequencyData(f2); | 90 analyser.getFloatFrequencyData(f2); |
| 94 | 91 |
| 95 var byteValuesFromFloat = convertFloatToByte(f2, analyser.minDecibels,
analyser.maxDecibels); | 92 var byteValuesFromFloat = convertFloatToByte(f2, analyser.minDecibels,
analyser.maxDecibels); |
| 96 success = Should( | 93 should(f1, |
| 97 "Output of getFloatFrequenycData (converted to byte) after getByte
FrequencyData", | 94 "Output of getFloatFrequenycData (converted to byte) after getByte
FrequencyData") |
| 98 f1) | 95 .beEqualToArray(byteValuesFromFloat); |
| 99 .beEqualToArray(byteValuesFromFloat) && success; | |
| 100 }).then(context.resume.bind(context)); | 96 }).then(context.resume.bind(context)); |
| 101 | 97 |
| 102 osc.start(); | 98 osc.start(); |
| 103 context.startRendering().then(done); | 99 context.startRendering().then(() => task.done()); |
| 104 }); | 100 }); |
| 105 | 101 |
| 106 audit.defineTask("finish", function (done) { | 102 audit.run(); |
| 107 done(); | |
| 108 }); | |
| 109 | |
| 110 audit.runTasks(); | |
| 111 | 103 |
| 112 // Convert the float frequency data (in dB), |floatFreqData|, to byte valu
es using the dB | 104 // Convert the float frequency data (in dB), |floatFreqData|, to byte valu
es using the dB |
| 113 // limits |minDecibels| and |maxDecibels|. The new byte array is returned
. | 105 // limits |minDecibels| and |maxDecibels|. The new byte array is returned
. |
| 114 function convertFloatToByte(floatFreqData, minDecibels, maxDecibels) { | 106 function convertFloatToByte(floatFreqData, minDecibels, maxDecibels) { |
| 115 var scale = 255 / (maxDecibels - minDecibels); | 107 var scale = 255 / (maxDecibels - minDecibels); |
| 116 | 108 |
| 117 return floatFreqData.map(function (x) { | 109 return floatFreqData.map(function (x) { |
| 118 var value = Math.floor(scale * (x - minDecibels)); | 110 var value = Math.floor(scale * (x - minDecibels)); |
| 119 return Math.min(255, Math.max(0, value)); | 111 return Math.min(255, Math.max(0, value)); |
| 120 }); | 112 }); |
| 121 } | 113 } |
| 122 </script> | 114 </script> |
| 123 </body> | 115 </body> |
| 124 </html> | 116 </html> |
| OLD | NEW |