| OLD | NEW |
| 1 <!doctype html> | 1 <!DOCTYPE html> |
| 2 <html> | 2 <html> |
| 3 <head> | 3 <head> |
| 4 <title> |
| 5 Test Analyser getFloatFrequencyData and getByteFrequencyData, Smoothing |
| 6 </title> |
| 4 <script src="../../resources/testharness.js"></script> | 7 <script src="../../resources/testharness.js"></script> |
| 5 <script src="../../resources/testharnessreport.js"></script> | 8 <script src="../../resources/testharnessreport.js"></script> |
| 6 <script src="../resources/audit-util.js"></script> | 9 <script src="../resources/audit-util.js"></script> |
| 7 <script src="../resources/audit.js"></script> | 10 <script src="../resources/audit.js"></script> |
| 8 <script src="../resources/realtimeanalyser-testing.js"></script> | 11 <script src="../resources/realtimeanalyser-testing.js"></script> |
| 9 <script src="../resources/fft.js"></script> | 12 <script src="../resources/fft.js"></script> |
| 10 <title>Test Analyser getFloatFrequencyData and getByteFrequencyData, Smoothi
ng</title> | |
| 11 | |
| 12 </head> | 13 </head> |
| 13 | |
| 14 <body> | 14 <body> |
| 15 <script> | 15 <script id="layout-test-code"> |
| 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 |
| 17 // context.suspend(). | 17 // times for context.suspend(). |
| 18 let sampleRate = 32768; | 18 let 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 |
| 21 // that we have at least one complete buffer of data of 32768 samples. | 21 // longer than this so that we have at least one complete buffer of data |
| 22 // of 32768 samples. |
| 22 let renderFrames = 2 * 32768; | 23 let renderFrames = 2 * 32768; |
| 23 let renderDuration = renderFrames / sampleRate; | 24 let renderDuration = renderFrames / sampleRate; |
| 24 | 25 |
| 25 let audit = Audit.createTaskRunner(); | 26 let audit = Audit.createTaskRunner(); |
| 26 | 27 |
| 27 // Do one basic test of smoothing of the FFT data. | 28 // Do one basic test of smoothing of the FFT data. |
| 28 audit.define("smoothing test", (task, should) => { | 29 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 | 30 // Test only 512-point FFT. The size isn't too important as long as |
| 30 // (a rendering quantum). | 31 // it's greater than 128 (a rendering quantum). |
| 31 let options = { | 32 let options = {order: 9, smoothing: 0.5, floatRelError: 5.9207e-6}; |
| 32 order: 9, | |
| 33 smoothing: 0.5, | |
| 34 floatRelError: 5.9207e-6 | |
| 35 }; | |
| 36 | 33 |
| 37 let success = true; | 34 let success = true; |
| 38 | 35 |
| 39 let graph = createGraph(options); | 36 let graph = createGraph(options); |
| 40 | 37 |
| 41 context = graph.context; | 38 context = graph.context; |
| 42 analyser = graph.analyser; | 39 analyser = graph.analyser; |
| 43 | 40 |
| 44 let smoothedFloatResult = new Float32Array(analyser.frequencyBinCount); | 41 let smoothedFloatResult = new Float32Array(analyser.frequencyBinCount); |
| 45 smoothedFloatResult.fill(0); | 42 smoothedFloatResult.fill(0); |
| 46 | 43 |
| 47 // Stop after one analyser frame to get the initial FFT | 44 // Stop after one analyser frame to get the initial FFT |
| 48 let suspendFrame = analyser.fftSize; | 45 let suspendFrame = analyser.fftSize; |
| 49 context.suspend(suspendFrame / sampleRate).then(function () { | 46 context.suspend(suspendFrame / sampleRate) |
| 50 let timeData = new Float32Array(analyser.fftSize); | 47 .then(function() { |
| 51 let freqData = new Float32Array(analyser.frequencyBinCount); | 48 let timeData = new Float32Array(analyser.fftSize); |
| 52 analyser.getFloatTimeDomainData(timeData); | 49 let freqData = new Float32Array(analyser.frequencyBinCount); |
| 53 analyser.getFloatFrequencyData(freqData); | 50 analyser.getFloatTimeDomainData(timeData); |
| 51 analyser.getFloatFrequencyData(freqData); |
| 54 | 52 |
| 55 let expectedFreq = computeFFTMagnitude(timeData, options.order); | 53 let expectedFreq = computeFFTMagnitude(timeData, options.order); |
| 56 smoothFFT(smoothedFloatResult, expectedFreq, options.smoothing); | 54 smoothFFT(smoothedFloatResult, expectedFreq, options.smoothing); |
| 57 | 55 |
| 58 let message = "First " + analyser.fftSize + "-point FFT at frame " + (
context.currentTime * | 56 let message = 'First ' + analyser.fftSize + |
| 59 sampleRate); | 57 '-point FFT at frame ' + (context.currentTime * sampleRate); |
| 60 let comparison = compareFloatFreq(message, freqData, smoothedFloatResu
lt.map( | 58 let comparison = compareFloatFreq( |
| 61 linearToDb), should, options); | 59 message, freqData, smoothedFloatResult.map(linearToDb), |
| 62 success = success && comparison.success; | 60 should, options); |
| 61 success = success && comparison.success; |
| 63 | 62 |
| 64 // Test the byte frequency data. | 63 // Test the byte frequency data. |
| 65 let byteFreqData = new Uint8Array(analyser.frequencyBinCount); | 64 let byteFreqData = new Uint8Array(analyser.frequencyBinCount); |
| 66 analyser.getByteFrequencyData(byteFreqData); | 65 analyser.getByteFrequencyData(byteFreqData); |
| 67 | 66 |
| 68 // Convert the expected float frequency data to byte data. | 67 // Convert the expected float frequency data to byte data. |
| 69 let expectedByteData = convertFloatToByte(smoothedFloatResult.map(line
arToDb), | 68 let expectedByteData = convertFloatToByte( |
| 70 analyser.minDecibels, analyser.maxDecibels); | 69 smoothedFloatResult.map(linearToDb), analyser.minDecibels, |
| 70 analyser.maxDecibels); |
| 71 | 71 |
| 72 should(byteFreqData, analyser.fftSize + "-point byte FFT") | 72 should(byteFreqData, analyser.fftSize + '-point byte FFT') |
| 73 .beCloseToArray(expectedByteData, 0); | 73 .beCloseToArray(expectedByteData, 0); |
| 74 | 74 |
| 75 }).then(context.resume.bind(context)); | 75 }) |
| 76 .then(context.resume.bind(context)); |
| 76 | 77 |
| 77 // 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 |
| 79 // is done correctly. |
| 78 suspendFrame += 2 * analyser.fftSize; | 80 suspendFrame += 2 * analyser.fftSize; |
| 79 context.suspend(suspendFrame / sampleRate).then(function () { | 81 context.suspend(suspendFrame / sampleRate) |
| 80 let timeData = new Float32Array(analyser.fftSize); | 82 .then(function() { |
| 81 let freqDataInDb = new Float32Array(analyser.frequencyBinCount); | 83 let timeData = new Float32Array(analyser.fftSize); |
| 84 let freqDataInDb = new Float32Array(analyser.frequencyBinCount); |
| 82 | 85 |
| 83 // Grab the time domain and frequency domain data | 86 // Grab the time domain and frequency domain data |
| 84 analyser.getFloatTimeDomainData(timeData); | 87 analyser.getFloatTimeDomainData(timeData); |
| 85 analyser.getFloatFrequencyData(freqDataInDb); | 88 analyser.getFloatFrequencyData(freqDataInDb); |
| 86 | 89 |
| 87 let newFreqData = computeFFTMagnitude(timeData, options.order); | 90 let newFreqData = computeFFTMagnitude(timeData, options.order); |
| 88 // Smooth the data together | 91 // Smooth the data together |
| 89 | 92 |
| 90 smoothFFT(smoothedFloatResult, newFreqData, options.smoothing); | 93 smoothFFT(smoothedFloatResult, newFreqData, options.smoothing); |
| 91 let message = "Smoothed " + analyser.fftSize + "-point FFT at frame "
+ | 94 let message = 'Smoothed ' + analyser.fftSize + |
| 92 (context.currentTime * sampleRate); | 95 '-point FFT at frame ' + (context.currentTime * sampleRate); |
| 93 let comparison = compareFloatFreq(message, | 96 let comparison = compareFloatFreq( |
| 94 freqDataInDb, smoothedFloatResult.map(linearToDb), should, { | 97 message, freqDataInDb, smoothedFloatResult.map(linearToDb), |
| 95 order: options.order, | 98 should, { |
| 96 smoothing: options.smoothing, | 99 order: options.order, |
| 97 floatRelError: 2.5332e-5 | 100 smoothing: options.smoothing, |
| 98 }); | 101 floatRelError: 2.5332e-5 |
| 99 success = success && comparison.success; | 102 }); |
| 103 success = success && comparison.success; |
| 100 | 104 |
| 101 // Test the byte frequency data. | 105 // Test the byte frequency data. |
| 102 let byteFreqData = new Uint8Array(analyser.frequencyBinCount); | 106 let byteFreqData = new Uint8Array(analyser.frequencyBinCount); |
| 103 analyser.getByteFrequencyData(byteFreqData); | 107 analyser.getByteFrequencyData(byteFreqData); |
| 104 | 108 |
| 105 // Convert the expected float frequency data to byte data. | 109 // Convert the expected float frequency data to byte data. |
| 106 let expectedByteData = convertFloatToByte(smoothedFloatResult.map(line
arToDb), | 110 let expectedByteData = convertFloatToByte( |
| 107 analyser.minDecibels, analyser.maxDecibels); | 111 smoothedFloatResult.map(linearToDb), analyser.minDecibels, |
| 112 analyser.maxDecibels); |
| 108 | 113 |
| 109 should(byteFreqData, analyser.fftSize + "-point byte FFT") | 114 should(byteFreqData, analyser.fftSize + '-point byte FFT') |
| 110 .beCloseToArray(expectedByteData, 0); | 115 .beCloseToArray(expectedByteData, 0); |
| 111 | 116 |
| 112 }).then(context.resume.bind(context)); | 117 }) |
| 118 .then(context.resume.bind(context)); |
| 113 | 119 |
| 114 context.startRendering().then(() => task.done()); | 120 context.startRendering().then(() => task.done()); |
| 115 }); | 121 }); |
| 116 | 122 |
| 117 audit.run(); | 123 audit.run(); |
| 118 | |
| 119 </script> | 124 </script> |
| 120 </body> | 125 </body> |
| 121 </html> | 126 </html> |
| OLD | NEW |