diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html')
-rw-r--r-- | testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html new file mode 100644 index 0000000000..043bd5890a --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/realtimeanalyser-fft-scaling.html @@ -0,0 +1,111 @@ +<!DOCTYPE html> +<html> + <head> + <title> + realtimeanalyser-fft-scaling.html + </title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/webaudio/resources/audit-util.js"></script> + <script src="/webaudio/resources/audit.js"></script> + </head> + <body> + <div id="description"></div> + <div id="console"></div> + <script id="layout-test-code"> + let audit = Audit.createTaskRunner(); + + // The number of analysers. We have analysers from size for each of the + // possible sizes of 2^5 to 2^15 for a total of 11. + let numberOfAnalysers = 11; + let sampleRate = 44100; + let nyquistFrequency = sampleRate / 2; + + // Frequency of the sine wave test signal. Should be high enough so that + // we get at least one full cycle for the 32-point FFT. This should also + // be such that the frequency should be exactly in one of the FFT bins for + // each of the possible FFT sizes. + let oscFrequency = nyquistFrequency / 16; + + // The actual peak values from each analyser. Useful for examining the + // actual peak values. + let peakValue = new Array(numberOfAnalysers); + + // For a 0dBFS sine wave, we would expect the FFT magnitude to be 0dB as + // well, but the analyzer node applies a Blackman window (to smooth the + // estimate). This reduces the energy of the signal so the FFT peak is + // less than 0dB. The threshold value given here was determined + // experimentally. + // + // See https://code.google.com/p/chromium/issues/detail?id=341596. + let peakThreshold = [ + -14.43, -13.56, -13.56, -13.56, -13.56, -13.56, -13.56, -13.56, -13.56, + -13.56, -13.56 + ]; + + function checkResult(order, analyser, should) { + return function() { + let index = order - 5; + let fftSize = 1 << order; + let fftData = new Float32Array(fftSize); + analyser.getFloatFrequencyData(fftData); + + // Compute the frequency bin that should contain the peak. + let expectedBin = + analyser.frequencyBinCount * (oscFrequency / nyquistFrequency); + + // Find the actual bin by finding the bin containing the peak. + let actualBin = 0; + peakValue[index] = -1000; + for (k = 0; k < analyser.frequencyBinCount; ++k) { + if (fftData[k] > peakValue[index]) { + actualBin = k; + peakValue[index] = fftData[k]; + } + } + + should(actualBin, (1 << order) + '-point FFT peak position') + .beEqualTo(expectedBin); + + should( + peakValue[index], (1 << order) + '-point FFT peak value in dBFS') + .beGreaterThanOrEqualTo(peakThreshold[index]); + } + } + + audit.define( + { + label: 'FFT scaling tests', + description: 'Test Scaling of FFT in AnalyserNode' + }, + async function(task, should) { + let tests = []; + for (let k = 5; k <= 15; ++k) + await runTest(k, should); + task.done(); + }); + + function runTest(order, should) { + let context = new OfflineAudioContext(1, 1 << order, sampleRate); + // Use a sine wave oscillator as the reference source signal. + let osc = context.createOscillator(); + osc.type = 'sine'; + osc.frequency.value = oscFrequency; + osc.connect(context.destination); + + let analyser = context.createAnalyser(); + // No smoothing to simplify the analysis of the result. + analyser.smoothingTimeConstant = 0; + analyser.fftSize = 1 << order; + osc.connect(analyser); + + osc.start(); + return context.startRendering().then(() => { + checkResult(order, analyser, should)(); + }); + } + + audit.run(); + </script> + </body> +</html> |