| Index: LayoutTests/webaudio/realtimeanalyser-fft-scaling.html
|
| diff --git a/LayoutTests/webaudio/realtimeanalyser-fft-scaling.html b/LayoutTests/webaudio/realtimeanalyser-fft-scaling.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..711633d548f9632bebe73cb2f42f4f5d370ff1b3
|
| --- /dev/null
|
| +++ b/LayoutTests/webaudio/realtimeanalyser-fft-scaling.html
|
| @@ -0,0 +1,124 @@
|
| +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
| +<html>
|
| + <head>
|
| + <script src="../resources/js-test.js"></script>
|
| + <script src="resources/audio-testing.js"></script>
|
| + </head>
|
| +
|
| + <body>
|
| + <div id="description"></div>
|
| + <div id="console"></div>
|
| +
|
| + <script>
|
| + description("Test scaling of FFT data for AnalyserNode");
|
| +
|
| + // The number of analysers. We have analysers from size for each of the possible sizes of 32,
|
| + // 64, 128, 256, 512, 1024 and 2048.
|
| + var numberOfAnalysers = 7;
|
| + var sampleRate = 44100;
|
| + var context;
|
| + var osc;
|
| + var oscFrequency = sampleRate/32;
|
| + var analysers = new Array(7);
|
| + var peakValue = new Array(7);
|
| +
|
| + // 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.
|
| + var peakThreshold = [-8.41, -7.54, -7.54, -7.54, -7.54, -7.54, -7.54];
|
| +
|
| + function checkResult() {
|
| + var allTestsPassed = true;
|
| +
|
| + for (n = 0; n < analysers.length; ++n) {
|
| + // Grab the FFT data from each analyser.
|
| + var fftSize = analysers[n].fftSize;
|
| + var fftData = new Float32Array(fftSize);
|
| + analysers[n].getFloatFrequencyData(fftData);
|
| +
|
| + // Compute the frequency bin that should contain the peak.
|
| + var expectedBin = fftSize * (oscFrequency / sampleRate);
|
| +
|
| + // Find the actual bin by finding the bin containing the peak.
|
| + var actualBin = 0;
|
| + peakValue[n] = -1000;
|
| + for (k = 0; k < analysers[n].frequencyBinCount; ++k) {
|
| + if (fftData[k] > peakValue[n]) {
|
| + actualBin = k;
|
| + peakValue[n] = fftData[k];
|
| + }
|
| + }
|
| +
|
| + var success = true;
|
| +
|
| + if (actualBin == expectedBin) {
|
| + testPassed("Actual FFT peak in the expected position (" + expectedBin + ")");
|
| + } else {
|
| + success = false;
|
| + testFailed("Actual FFT peak (" + actualBin + ") differs from expected (" + expectedBin + ")");
|
| + }
|
| +
|
| + if (peakValue[n] >= peakThreshold[n]) {
|
| + testPassed("Peak value is near 0 dBFS as expected");
|
| + } else {
|
| + success = false;
|
| + testFailed("Peak value of " + peakValue[n]
|
| + + " is incorrect. (Expected approximately "
|
| + + peakThreshold[n] + ")");
|
| + }
|
| +
|
| + if (success) {
|
| + testPassed("Analyser correctly scaled FFT data of size " + fftSize);
|
| + } else {
|
| + testFailed("Analyser incorrectly scaled FFT data of size " + fftSize);
|
| + }
|
| + allTestsPassed = allTestsPassed && success;
|
| + }
|
| +
|
| + if (allTestsPassed) {
|
| + testPassed("All Analyser tests passed.");
|
| + } else {
|
| + testFailed("At least one Analyser test failed.");
|
| + }
|
| +
|
| + finishJSTest();
|
| + }
|
| +
|
| + function runTests() {
|
| + if (window.testRunner) {
|
| + testRunner.dumpAsText();
|
| + testRunner.waitUntilDone();
|
| + }
|
| +
|
| + window.jsTestIsAsync = true;
|
| +
|
| + context = new webkitOfflineAudioContext(1, 2048, sampleRate);
|
| +
|
| + // Use a sine wave oscillator as the reference source signal.
|
| + osc = context.createOscillator();
|
| + osc.type = "sine";
|
| + osc.frequency.value = oscFrequency;
|
| + osc.connect(context.destination);
|
| +
|
| + // Create an analyser node for each of the possible valid sizes.
|
| + for (order = 5; order < 12; ++order) {
|
| + analysers[order - 5] = context.createAnalyser();
|
| + // No smoothing so between frames to simplify testing.
|
| + analysers[order - 5].smoothingTimeConstant = 0;
|
| + analysers[order - 5].fftSize = 1 << order;
|
| + osc.connect(analysers[order - 5]);
|
| + }
|
| +
|
| + osc.start();
|
| + context.oncomplete = checkResult;
|
| + context.startRendering();
|
| + }
|
| +
|
| + runTests();
|
| + successfullyParsed = true;
|
| + </script>
|
| + </body>
|
| +</html>
|
|
|