| <!DOCTYPE html> |
| <html> |
| <head> |
| <title> |
| Test Analyser getFloatFrequencyData and getByteFrequencyData, Smoothing |
| </title> |
| <script src="../../imported/w3c/web-platform-tests/resources/testharness.js"></script> |
| <script src="../../resources/testharnessreport.js"></script> |
| <script src="../resources/audit-util.js"></script> |
| <script src="../resources/audit.js"></script> |
| <script src="../resources/realtimeanalyser-testing.js"></script> |
| <script src="../resources/fft.js"></script> |
| </head> |
| <body> |
| <script id="layout-test-code"> |
| // Use a power of two to eliminate any round-off in the computation of the |
| // times for context.suspend(). |
| let sampleRate = 32768; |
| |
| // The largest FFT size for the analyser node is 32768. We want to render |
| // longer than this so that we have at least one complete buffer of data |
| // of 32768 samples. |
| let renderFrames = 2 * 32768; |
| let renderDuration = renderFrames / sampleRate; |
| |
| let audit = Audit.createTaskRunner(); |
| |
| // Do one basic test of smoothing of the FFT data. |
| audit.define('smoothing test', (task, should) => { |
| // Test only 512-point FFT. The size isn't too important as long as |
| // it's greater than 128 (a rendering quantum). |
| let options = {order: 9, smoothing: 0.5, floatRelError: 5.9207e-6}; |
| |
| let success = true; |
| |
| let graph = createGraph(options); |
| |
| context = graph.context; |
| analyser = graph.analyser; |
| |
| let smoothedFloatResult = new Float32Array(analyser.frequencyBinCount); |
| smoothedFloatResult.fill(0); |
| |
| // Stop after one analyser frame to get the initial FFT |
| let suspendFrame = analyser.fftSize; |
| context.suspend(suspendFrame / sampleRate) |
| .then(function() { |
| let timeData = new Float32Array(analyser.fftSize); |
| let freqData = new Float32Array(analyser.frequencyBinCount); |
| analyser.getFloatTimeDomainData(timeData); |
| analyser.getFloatFrequencyData(freqData); |
| |
| let expectedFreq = computeFFTMagnitude(timeData, options.order); |
| smoothFFT(smoothedFloatResult, expectedFreq, options.smoothing); |
| |
| let message = 'First ' + analyser.fftSize + |
| '-point FFT at frame ' + (context.currentTime * sampleRate); |
| let comparison = compareFloatFreq( |
| message, freqData, smoothedFloatResult.map(linearToDb), |
| should, options); |
| success = success && comparison.success; |
| |
| // Test the byte frequency data. |
| let byteFreqData = new Uint8Array(analyser.frequencyBinCount); |
| analyser.getByteFrequencyData(byteFreqData); |
| |
| // Convert the expected float frequency data to byte data. |
| let expectedByteData = convertFloatToByte( |
| smoothedFloatResult.map(linearToDb), analyser.minDecibels, |
| analyser.maxDecibels); |
| |
| should(byteFreqData, analyser.fftSize + '-point byte FFT') |
| .beCloseToArray(expectedByteData, 0); |
| |
| }) |
| .then(context.resume.bind(context)); |
| |
| // Skip an analyser frame and grab another to verify that the smoothing |
| // is done correctly. |
| suspendFrame += 2 * analyser.fftSize; |
| context.suspend(suspendFrame / sampleRate) |
| .then(function() { |
| let timeData = new Float32Array(analyser.fftSize); |
| let freqDataInDb = new Float32Array(analyser.frequencyBinCount); |
| |
| // Grab the time domain and frequency domain data |
| analyser.getFloatTimeDomainData(timeData); |
| analyser.getFloatFrequencyData(freqDataInDb); |
| |
| let newFreqData = computeFFTMagnitude(timeData, options.order); |
| // Smooth the data together |
| |
| smoothFFT(smoothedFloatResult, newFreqData, options.smoothing); |
| let message = 'Smoothed ' + analyser.fftSize + |
| '-point FFT at frame ' + (context.currentTime * sampleRate); |
| let comparison = compareFloatFreq( |
| message, freqDataInDb, smoothedFloatResult.map(linearToDb), |
| should, { |
| order: options.order, |
| smoothing: options.smoothing, |
| floatRelError: 2.5332e-5 |
| }); |
| success = success && comparison.success; |
| |
| // Test the byte frequency data. |
| let byteFreqData = new Uint8Array(analyser.frequencyBinCount); |
| analyser.getByteFrequencyData(byteFreqData); |
| |
| // Convert the expected float frequency data to byte data. |
| let expectedByteData = convertFloatToByte( |
| smoothedFloatResult.map(linearToDb), analyser.minDecibels, |
| analyser.maxDecibels); |
| |
| should(byteFreqData, analyser.fftSize + '-point byte FFT') |
| .beCloseToArray(expectedByteData, 0); |
| |
| }) |
| .then(context.resume.bind(context)); |
| |
| context.startRendering().then(() => task.done()); |
| }); |
| |
| audit.run(); |
| </script> |
| </body> |
| </html> |