Title: [172816] trunk
- Revision
- 172816
- Author
- [email protected]
- Date
- 2014-08-20 15:39:44 -0700 (Wed, 20 Aug 2014)
Log Message
WebAudio FFT analysis uses incorrect scaling
https://bugs.webkit.org/show_bug.cgi?id=136120
Reviewed by Tim Horton.
Source/WebCore:
This is a port of Blink r166687 (author rtoy)
https://codereview.chromium.org/156993002
Currently, for a fixed sine-wave input, the peak FFT amplitude changes
depending on the selected FFT size. This is incorrect; the FFT amplitude
should not appreciably change when the FFT size changes.
Layout test added to verify the FFT result stays approximately constant,
independent of the FFT size used.
When this test is run using an older version of WebKit, the peak varies
from about -44 dB (FFT size 32) to -7 dB (FFT size 2048). With this CL,
the peak is about -7 dB. (It's not 0 dB because of the Blackman window that is applied.)
Note: this change may break existing applications that depended on this strange scaling effect.
Test: webaudio/realtimeanalyser-fft-scaling.html
* Modules/webaudio/RealtimeAnalyser.cpp:
(WebCore::RealtimeAnalyser::doFFTAnalysis):
LayoutTests:
Test from Blink r166687.
* webaudio/realtimeanalyser-fft-scaling.html: Added.
* webaudio/realtimeanalyser-fft-scaling-expected.txt: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (172815 => 172816)
--- trunk/LayoutTests/ChangeLog 2014-08-20 22:08:45 UTC (rev 172815)
+++ trunk/LayoutTests/ChangeLog 2014-08-20 22:39:44 UTC (rev 172816)
@@ -1,3 +1,15 @@
+2014-08-20 Dean Jackson <[email protected]>
+
+ WebAudio FFT analysis uses incorrect scaling
+ https://bugs.webkit.org/show_bug.cgi?id=136120
+
+ Reviewed by Tim Horton.
+
+ Test from Blink r166687.
+
+ * webaudio/realtimeanalyser-fft-scaling.html: Added.
+ * webaudio/realtimeanalyser-fft-scaling-expected.txt: Added.
+
2014-08-20 Alexey Proskuryakov <[email protected]>
fast/multicol/mixed-opacity-fixed-test.html fails in compositing mode
Added: trunk/LayoutTests/webaudio/realtimeanalyser-fft-scaling-expected.txt (0 => 172816)
--- trunk/LayoutTests/webaudio/realtimeanalyser-fft-scaling-expected.txt (rev 0)
+++ trunk/LayoutTests/webaudio/realtimeanalyser-fft-scaling-expected.txt 2014-08-20 22:39:44 UTC (rev 172816)
@@ -0,0 +1,30 @@
+Test scaling of FFT data for AnalyserNode
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS Actual FFT peak in the expected position (1)
+PASS Peak value is near 0 dBFS as expected
+PASS Analyser correctly scaled FFT data of size 32
+PASS Actual FFT peak in the expected position (2)
+PASS Peak value is near 0 dBFS as expected
+PASS Analyser correctly scaled FFT data of size 64
+PASS Actual FFT peak in the expected position (4)
+PASS Peak value is near 0 dBFS as expected
+PASS Analyser correctly scaled FFT data of size 128
+PASS Actual FFT peak in the expected position (8)
+PASS Peak value is near 0 dBFS as expected
+PASS Analyser correctly scaled FFT data of size 256
+PASS Actual FFT peak in the expected position (16)
+PASS Peak value is near 0 dBFS as expected
+PASS Analyser correctly scaled FFT data of size 512
+PASS Actual FFT peak in the expected position (32)
+PASS Peak value is near 0 dBFS as expected
+PASS Analyser correctly scaled FFT data of size 1024
+PASS Actual FFT peak in the expected position (64)
+PASS Peak value is near 0 dBFS as expected
+PASS Analyser correctly scaled FFT data of size 2048
+PASS All Analyser tests passed.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Property changes on: trunk/LayoutTests/webaudio/realtimeanalyser-fft-scaling-expected.txt
___________________________________________________________________
Added: svn:mime-type
Added: svn:keywords
Added: svn:eol-style
Added: trunk/LayoutTests/webaudio/realtimeanalyser-fft-scaling.html (0 => 172816)
--- trunk/LayoutTests/webaudio/realtimeanalyser-fft-scaling.html (rev 0)
+++ trunk/LayoutTests/webaudio/realtimeanalyser-fft-scaling.html 2014-08-20 22:39:44 UTC (rev 172816)
@@ -0,0 +1,124 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <script src=""
+ <script src=""
+ </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 (var 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 (var 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(0);
+ context._oncomplete_ = checkResult;
+ context.startRendering();
+}
+
+runTests();
+successfullyParsed = true;
+ </script>
+ </body>
+</html>
Property changes on: trunk/LayoutTests/webaudio/realtimeanalyser-fft-scaling.html
___________________________________________________________________
Added: svn:mime-type
Added: svn:keywords
Added: svn:eol-style
Modified: trunk/Source/WebCore/ChangeLog (172815 => 172816)
--- trunk/Source/WebCore/ChangeLog 2014-08-20 22:08:45 UTC (rev 172815)
+++ trunk/Source/WebCore/ChangeLog 2014-08-20 22:39:44 UTC (rev 172816)
@@ -1,3 +1,31 @@
+2014-08-20 Dean Jackson <[email protected]>
+
+ WebAudio FFT analysis uses incorrect scaling
+ https://bugs.webkit.org/show_bug.cgi?id=136120
+
+ Reviewed by Tim Horton.
+
+ This is a port of Blink r166687 (author rtoy)
+ https://codereview.chromium.org/156993002
+
+ Currently, for a fixed sine-wave input, the peak FFT amplitude changes
+ depending on the selected FFT size. This is incorrect; the FFT amplitude
+ should not appreciably change when the FFT size changes.
+
+ Layout test added to verify the FFT result stays approximately constant,
+ independent of the FFT size used.
+
+ When this test is run using an older version of WebKit, the peak varies
+ from about -44 dB (FFT size 32) to -7 dB (FFT size 2048). With this CL,
+ the peak is about -7 dB. (It's not 0 dB because of the Blackman window that is applied.)
+
+ Note: this change may break existing applications that depended on this strange scaling effect.
+
+ Test: webaudio/realtimeanalyser-fft-scaling.html
+
+ * Modules/webaudio/RealtimeAnalyser.cpp:
+ (WebCore::RealtimeAnalyser::doFFTAnalysis):
+
2014-08-20 Alex Christensen <[email protected]>
Introducing WEBCORE_EXPORT macro.
Modified: trunk/Source/WebCore/Modules/webaudio/RealtimeAnalyser.cpp (172815 => 172816)
--- trunk/Source/WebCore/Modules/webaudio/RealtimeAnalyser.cpp 2014-08-20 22:08:45 UTC (rev 172815)
+++ trunk/Source/WebCore/Modules/webaudio/RealtimeAnalyser.cpp 2014-08-20 22:39:44 UTC (rev 172816)
@@ -185,7 +185,7 @@
imagP[0] = 0;
// Normalize so than an input sine wave at 0dBfs registers as 0dBfs (undo FFT scaling factor).
- const double magnitudeScale = 1.0 / DefaultFFTSize;
+ const double magnitudeScale = 1.0 / fftSize;
// A value of 0 does no averaging with the previous result. Larger values produce slower, but smoother changes.
double k = m_smoothingTimeConstant;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes