| Index: third_party/WebKit/LayoutTests/webaudio/realtimeanalyser-fftsize-reset.html
|
| diff --git a/third_party/WebKit/LayoutTests/webaudio/realtimeanalyser-fftsize-reset.html b/third_party/WebKit/LayoutTests/webaudio/realtimeanalyser-fftsize-reset.html
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..0f7666e5d95f4889a0e3a69db29db1dd353f0586
|
| --- /dev/null
|
| +++ b/third_party/WebKit/LayoutTests/webaudio/realtimeanalyser-fftsize-reset.html
|
| @@ -0,0 +1,132 @@
|
| +<!doctype html>
|
| +<html>
|
| + <head>
|
| + <title>Test fftSize Changes Resetting AnalyserNode State </title>
|
| + <script src="../resources/testharness.js"></script>
|
| + <script src="../resources/testharnessreport.js"></script>
|
| + <script src="resources/audio-testing.js"></script>
|
| + </head>
|
| +
|
| + <body>
|
| + <script>
|
| + // Fairly arbitrary sample rate.
|
| + var sampleRate = 24000;
|
| +
|
| + var audit = Audit.createTaskRunner();
|
| +
|
| + // Verify that setting the fftSize resets the memory for the FFT smoothing
|
| + // operation. Only a few of the possible variations are tested.
|
| +
|
| + audit.defineTask("128->1024", function (taskDone) {
|
| + testFFTSize({
|
| + initialFFTSize: 128,
|
| + finalFFTSize: 1024,
|
| + errorThreshold: {
|
| + relativeThreshold: 1.9095e-6
|
| + }
|
| + }).then(taskDone);
|
| + });
|
| +
|
| + audit.defineTask("512->256", function (taskDone) {
|
| + testFFTSize({
|
| + initialFFTSize: 512,
|
| + finalFFTSize: 256,
|
| + errorThreshold: {
|
| + relativeThreshold: 1.8166e-6
|
| + }
|
| + }).then(taskDone);
|
| + });
|
| +
|
| + function testFFTSize(options) {
|
| + var {
|
| + initialFFTSize, finalFFTSize, errorThreshold
|
| + } = options;
|
| +
|
| + // The duration is fairly arbitrary as long as it's long enough for the
|
| + // FFT test.
|
| + var context = new OfflineAudioContext(1, sampleRate, sampleRate);
|
| +
|
| + // Actual source doesn't matter but a sawtooth is a nice waveform with
|
| + // lots of harmonic content.
|
| + var osc = context.createOscillator();
|
| + osc.type = "sawtooth";
|
| +
|
| + // The analyser under test.
|
| + var testAnalyser = context.createAnalyser();
|
| + testAnalyser.fftSize = initialFFTSize;
|
| +
|
| + // The reference analyser. The fftSize is fixed to the desired value,
|
| + // and we turn off smoothing so that we get the FFT of the current time
|
| + // data.
|
| + var refAnalyser = context.createAnalyser();
|
| + refAnalyser.fftSize = finalFFTSize;
|
| + refAnalyser.smoothingTimeConstant = 0;
|
| +
|
| + // Setup the graph and start the oscillator.
|
| + osc.connect(testAnalyser)
|
| + .connect(context.destination);
|
| + osc.connect(refAnalyser)
|
| + .connect(context.destination);
|
| +
|
| + osc.start();
|
| +
|
| + // Let the analyser smooth a few FFTs (rather arbitrary, but should be
|
| + // more than one), then switch the size.
|
| +
|
| + var suspendFrame = 4 * initialFFTSize;
|
| + context.suspend(suspendFrame / context.sampleRate)
|
| + .then(function () {
|
| + testAnalyser.fftSize = finalFFTSize;
|
| + })
|
| + .then(context.resume.bind(context));
|
| +
|
| + // Wait some frames and grab the FFT data. This is fairly arbitrary
|
| + // too, and can be independent of the FFT sizes.
|
| + suspendFrame += 1024;
|
| + context.suspend(suspendFrame / context.sampleRate)
|
| + .then(function () {
|
| + var testFFT = new Float32Array(testAnalyser.frequencyBinCount);
|
| + var refFFT = new Float32Array(refAnalyser.frequencyBinCount)
|
| + var testSignal = new Float32Array(testAnalyser.fftSize);
|
| + var refSignal = new Float32Array(refAnalyser.fftSize);
|
| +
|
| + testAnalyser.getFloatTimeDomainData(testSignal);
|
| + refAnalyser.getFloatTimeDomainData(refSignal);
|
| +
|
| + testAnalyser.getFloatFrequencyData(testFFT);
|
| + refAnalyser.getFloatFrequencyData(refFFT);
|
| +
|
| + // Convert the FFT data from dB to linear
|
| + testFFT = testFFT.map(x => Math.pow(10, x / 20));
|
| + refFFT = refFFT.map(x => Math.pow(10, x / 20));
|
| +
|
| + // The test data has smoothing applied, but the reference doesn't.
|
| + // Apply the smoothing factor to the reference data.
|
| + var smoothing = 1 - testAnalyser.smoothingTimeConstant;
|
| + refFFT = refFFT.map(x => x * smoothing);
|
| +
|
| + var success = true;
|
| +
|
| + // First a basic sanity check that the time domain signals are
|
| + // exactly the same for both analysers.
|
| + success = Should("Time data", testSignal)
|
| + .beCloseToArray(refSignal, 0) && success;
|
| +
|
| + success = Should("Linear FFT data after setting fftSize = " + testAnalyser.fftSize,
|
| + testFFT)
|
| + .beCloseToArray(refFFT, errorThreshold) && success;
|
| +
|
| + Should("*** Changing fftSize from " + initialFFTSize + " to " + finalFFTSize, success)
|
| + .summarize(
|
| + "correctly reset the smoothing state",
|
| + "did not correctly reset the smoothing state");
|
| + })
|
| + .then(context.resume.bind(context));
|
| +
|
| + return context.startRendering();
|
| + }
|
| +
|
| + audit.runTasks();
|
| + </script>
|
| + </body>
|
| +</html>
|
|
|