| 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 <script src="../resources/realtimeanalyser-testing.js"></script> | 8 <script src="../resources/realtimeanalyser-testing.js"></script> |
| 9 <script src="../resources/fft.js"></script> | 9 <script src="../resources/fft.js"></script> |
| 10 <title>Test Analyser getFloatFrequencyData and getByteFrequencyData, Smoothi
ng</title> | 10 <title>Test Analyser getFloatFrequencyData and getByteFrequencyData, Smoothi
ng</title> |
| 11 | 11 |
| 12 </head> | 12 </head> |
| 13 | 13 |
| 14 <body> | 14 <body> |
| 15 <script> | 15 <script> |
| 16 // Use a power of two to eliminate any round-off in the computation of the
times for | 16 // Use a power of two to eliminate any round-off in the computation of the
times for |
| 17 // context.suspend(). | 17 // context.suspend(). |
| 18 var sampleRate = 32768; | 18 var sampleRate = 32768; |
| 19 | 19 |
| 20 // The largest FFT size for the analyser node is 32768. We want to render
longer than this so | 20 // The largest FFT size for the analyser node is 32768. We want to render
longer than this so |
| 21 // that we have at least one complete buffer of data of 32768 samples. | 21 // that we have at least one complete buffer of data of 32768 samples. |
| 22 var renderFrames = 2 * 32768; | 22 var renderFrames = 2 * 32768; |
| 23 var renderDuration = renderFrames / sampleRate; | 23 var renderDuration = renderFrames / sampleRate; |
| 24 | 24 |
| 25 var audit = Audit.createTaskRunner(); | 25 var audit = Audit.createTaskRunner(); |
| 26 | 26 |
| 27 // Do one basic test of smoothing of the FFT data. | 27 // Do one basic test of smoothing of the FFT data. |
| 28 audit.defineTask("smoothing test", function (done) { | 28 audit.define("smoothing test", (task, should) => { |
| 29 // Test only 512-point FFT. The size isn't too important as long as it'
s greater than 128 | 29 // Test only 512-point FFT. The size isn't too important as long as it'
s greater than 128 |
| 30 // (a rendering quantum). | 30 // (a rendering quantum). |
| 31 var options = { | 31 var options = { |
| 32 order: 9, | 32 order: 9, |
| 33 smoothing: 0.5, | 33 smoothing: 0.5, |
| 34 floatRelError: 5.9207e-6 | 34 floatRelError: 5.9207e-6 |
| 35 }; | 35 }; |
| 36 | 36 |
| 37 var success = true; | 37 var success = true; |
| 38 | 38 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 51 var freqData = new Float32Array(analyser.frequencyBinCount); | 51 var freqData = new Float32Array(analyser.frequencyBinCount); |
| 52 analyser.getFloatTimeDomainData(timeData); | 52 analyser.getFloatTimeDomainData(timeData); |
| 53 analyser.getFloatFrequencyData(freqData); | 53 analyser.getFloatFrequencyData(freqData); |
| 54 | 54 |
| 55 var expectedFreq = computeFFTMagnitude(timeData, options.order); | 55 var expectedFreq = computeFFTMagnitude(timeData, options.order); |
| 56 smoothFFT(smoothedFloatResult, expectedFreq, options.smoothing); | 56 smoothFFT(smoothedFloatResult, expectedFreq, options.smoothing); |
| 57 | 57 |
| 58 var message = "First " + analyser.fftSize + "-point FFT at frame " + (
context.currentTime * | 58 var message = "First " + analyser.fftSize + "-point FFT at frame " + (
context.currentTime * |
| 59 sampleRate); | 59 sampleRate); |
| 60 var comparison = compareFloatFreq(message, freqData, smoothedFloatResu
lt.map( | 60 var comparison = compareFloatFreq(message, freqData, smoothedFloatResu
lt.map( |
| 61 linearToDb), options); | 61 linearToDb), should, options); |
| 62 success = success && comparison.success; | 62 success = success && comparison.success; |
| 63 | 63 |
| 64 // Test the byte frequency data. | 64 // Test the byte frequency data. |
| 65 var byteFreqData = new Uint8Array(analyser.frequencyBinCount); | 65 var byteFreqData = new Uint8Array(analyser.frequencyBinCount); |
| 66 var expectedByteData = new Float32Array(analyser.frequencyBinCount); | 66 var expectedByteData = new Float32Array(analyser.frequencyBinCount); |
| 67 analyser.getByteFrequencyData(byteFreqData); | 67 analyser.getByteFrequencyData(byteFreqData); |
| 68 | 68 |
| 69 // Convert the expected float frequency data to byte data. | 69 // Convert the expected float frequency data to byte data. |
| 70 var expectedByteData = convertFloatToByte(smoothedFloatResult.map(line
arToDb), | 70 var expectedByteData = convertFloatToByte(smoothedFloatResult.map(line
arToDb), |
| 71 analyser.minDecibels, analyser.maxDecibels); | 71 analyser.minDecibels, analyser.maxDecibels); |
| 72 | 72 |
| 73 success = Should(analyser.fftSize + "-point byte FFT", byteFreqData) | 73 should(byteFreqData, analyser.fftSize + "-point byte FFT") |
| 74 .beCloseToArray(expectedByteData, 0) && success; | 74 .beCloseToArray(expectedByteData, 0); |
| 75 | 75 |
| 76 }).then(context.resume.bind(context)); | 76 }).then(context.resume.bind(context)); |
| 77 | 77 |
| 78 // Skip an analyser frame and grab another to verify that the smoothing
is done correctly. | 78 // Skip an analyser frame and grab another to verify that the smoothing
is done correctly. |
| 79 suspendFrame += 2 * analyser.fftSize; | 79 suspendFrame += 2 * analyser.fftSize; |
| 80 context.suspend(suspendFrame / sampleRate).then(function () { | 80 context.suspend(suspendFrame / sampleRate).then(function () { |
| 81 var timeData = new Float32Array(analyser.fftSize); | 81 var timeData = new Float32Array(analyser.fftSize); |
| 82 var freqDataInDb = new Float32Array(analyser.frequencyBinCount); | 82 var freqDataInDb = new Float32Array(analyser.frequencyBinCount); |
| 83 | 83 |
| 84 // Grab the time domain and frequency domain data | 84 // Grab the time domain and frequency domain data |
| 85 analyser.getFloatTimeDomainData(timeData); | 85 analyser.getFloatTimeDomainData(timeData); |
| 86 analyser.getFloatFrequencyData(freqDataInDb); | 86 analyser.getFloatFrequencyData(freqDataInDb); |
| 87 | 87 |
| 88 var newFreqData = computeFFTMagnitude(timeData, options.order); | 88 var newFreqData = computeFFTMagnitude(timeData, options.order); |
| 89 // Smooth the data together | 89 // Smooth the data together |
| 90 | 90 |
| 91 smoothFFT(smoothedFloatResult, newFreqData, options.smoothing); | 91 smoothFFT(smoothedFloatResult, newFreqData, options.smoothing); |
| 92 var message = "Smoothed " + analyser.fftSize + "-point FFT at frame "
+ | 92 var message = "Smoothed " + analyser.fftSize + "-point FFT at frame "
+ |
| 93 (context.currentTime * sampleRate); | 93 (context.currentTime * sampleRate); |
| 94 var comparison = compareFloatFreq(message, | 94 var comparison = compareFloatFreq(message, |
| 95 freqDataInDb, smoothedFloatResult.map(linearToDb), { | 95 freqDataInDb, smoothedFloatResult.map(linearToDb), should, { |
| 96 order: options.order, | 96 order: options.order, |
| 97 smoothing: options.smoothing, | 97 smoothing: options.smoothing, |
| 98 floatRelError: 2.5332e-5 | 98 floatRelError: 2.5332e-5 |
| 99 }); | 99 }); |
| 100 success = success && comparison.success; | 100 success = success && comparison.success; |
| 101 | 101 |
| 102 // Test the byte frequency data. | 102 // Test the byte frequency data. |
| 103 var byteFreqData = new Uint8Array(analyser.frequencyBinCount); | 103 var byteFreqData = new Uint8Array(analyser.frequencyBinCount); |
| 104 var expectedByteData = new Float32Array(analyser.frequencyBinCount); | 104 var expectedByteData = new Float32Array(analyser.frequencyBinCount); |
| 105 analyser.getByteFrequencyData(byteFreqData); | 105 analyser.getByteFrequencyData(byteFreqData); |
| 106 | 106 |
| 107 // Convert the expected float frequency data to byte data. | 107 // Convert the expected float frequency data to byte data. |
| 108 var expectedByteData = convertFloatToByte(smoothedFloatResult.map(line
arToDb), | 108 var expectedByteData = convertFloatToByte(smoothedFloatResult.map(line
arToDb), |
| 109 analyser.minDecibels, analyser.maxDecibels); | 109 analyser.minDecibels, analyser.maxDecibels); |
| 110 | 110 |
| 111 success = Should(analyser.fftSize + "-point byte FFT", byteFreqData) | 111 should(byteFreqData, analyser.fftSize + "-point byte FFT") |
| 112 .beCloseToArray(expectedByteData, 0) && success; | 112 .beCloseToArray(expectedByteData, 0); |
| 113 | 113 |
| 114 }).then(context.resume.bind(context)); | 114 }).then(context.resume.bind(context)); |
| 115 | 115 |
| 116 context.startRendering().then(function (buffer) { | 116 context.startRendering().then(() => task.done()); |
| 117 var prefix = "FFT smoothing performed"; | |
| 118 var suffix = " with smoothing constant " + analyser.smoothingTimeConst
ant; | |
| 119 | |
| 120 Should(prefix, success) | |
| 121 .summarize("correctly" + suffix, | |
| 122 "incorrectly" + suffix); | |
| 123 }).then(done); | |
| 124 }); | 117 }); |
| 125 | 118 |
| 126 audit.defineTask("finish", function (done) { | 119 audit.run(); |
| 127 done(); | |
| 128 }); | |
| 129 | |
| 130 audit.runTasks(); | |
| 131 | 120 |
| 132 </script> | 121 </script> |
| 133 </body> | 122 </body> |
| 134 </html> | 123 </html> |
| OLD | NEW |