[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198
kbr at google.com
kbr at google.com
Sun Feb 20 23:46:22 UTC 2011
The following commit has been merged in the webkit-1.3 branch:
commit 3b66f107a6eea950aa59b012fa6a564e1524d72b
Author: kbr at google.com <kbr at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Tue Jan 25 02:39:50 2011 +0000
2011-01-24 Kenneth Russell <kbr at google.com>
Reviewed by James Robinson.
Web Audio API: port FFTFrame to FFTW
https://bugs.webkit.org/show_bug.cgi?id=52989
Ported FFTFrame class to the open-source FFTW library. Tested with
unit tests from Chris Rogers. Made preliminary changes to GYP
files for conditional compilation of these files; will need to be
adjusted once FFTW is integrated as third-party source.
* WebCore.gyp/WebCore.gyp:
* WebCore.gypi:
* platform/audio/FFTFrame.h:
* platform/audio/fftw: Added.
* platform/audio/fftw/FFTFrameFFTW.cpp: Added.
(WebCore::FFTFrame::FFTFrame):
(WebCore::FFTFrame::~FFTFrame):
(WebCore::FFTFrame::multiply):
(WebCore::FFTFrame::doFFT):
(WebCore::FFTFrame::doInverseFFT):
(WebCore::FFTFrame::cleanup):
(WebCore::FFTFrame::realData):
(WebCore::FFTFrame::imagData):
(WebCore::FFTFrame::fftwPlanForSize):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@76562 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 5de637b..053094c 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,30 @@
+2011-01-24 Kenneth Russell <kbr at google.com>
+
+ Reviewed by James Robinson.
+
+ Web Audio API: port FFTFrame to FFTW
+ https://bugs.webkit.org/show_bug.cgi?id=52989
+
+ Ported FFTFrame class to the open-source FFTW library. Tested with
+ unit tests from Chris Rogers. Made preliminary changes to GYP
+ files for conditional compilation of these files; will need to be
+ adjusted once FFTW is integrated as third-party source.
+
+ * WebCore.gyp/WebCore.gyp:
+ * WebCore.gypi:
+ * platform/audio/FFTFrame.h:
+ * platform/audio/fftw: Added.
+ * platform/audio/fftw/FFTFrameFFTW.cpp: Added.
+ (WebCore::FFTFrame::FFTFrame):
+ (WebCore::FFTFrame::~FFTFrame):
+ (WebCore::FFTFrame::multiply):
+ (WebCore::FFTFrame::doFFT):
+ (WebCore::FFTFrame::doInverseFFT):
+ (WebCore::FFTFrame::cleanup):
+ (WebCore::FFTFrame::realData):
+ (WebCore::FFTFrame::imagData):
+ (WebCore::FFTFrame::fftwPlanForSize):
+
2011-01-24 Anders Carlsson <andersca at apple.com>
Reviewed by Dan Bernstein.
diff --git a/Source/WebCore/WebCore.gyp/WebCore.gyp b/Source/WebCore/WebCore.gyp/WebCore.gyp
index f96753c..2594d29 100644
--- a/Source/WebCore/WebCore.gyp/WebCore.gyp
+++ b/Source/WebCore/WebCore.gyp/WebCore.gyp
@@ -852,12 +852,17 @@
},
}],
# FIXME: (kbr) ideally this target should just depend on webcore_prerequisites
- # to pick up this include directory, but I'm nervous about making that change.
+ # to pick up these include directories, but I'm nervous about making that change.
['(OS=="linux" or OS=="win") and "WTF_USE_WEBAUDIO_MKL=1" in feature_defines', {
'include_dirs': [
'<(chromium_src_dir)/third_party/mkl/include',
],
}],
+ ['(OS=="linux" or OS=="win") and "WTF_USE_WEBAUDIO_FFTW=1" in feature_defines', {
+ 'include_dirs': [
+ '<(chromium_src_dir)/third_party/fftw/api',
+ ],
+ }],
],
},
{
@@ -1034,6 +1039,14 @@
],
},
}],
+ ['(OS=="linux" or OS=="win") and "WTF_USE_WEBAUDIO_FFTW=1" in feature_defines', {
+ # This directory needs to be on the include path for multiple sub-targets of webcore.
+ 'direct_dependent_settings': {
+ 'include_dirs': [
+ '<(chromium_src_dir)/third_party/fftw/api',
+ ],
+ },
+ }],
],
},
{
@@ -1096,7 +1109,7 @@
# Exclude things that don't apply to the Chromium platform on the basis
# of their enclosing directories and tags at the ends of their
# filenames.
- ['exclude', '(android|cairo|cf|cg|curl|gtk|haiku|linux|mac|mkl|opentype|posix|qt|soup|svg|symbian|win|wx)/'],
+ ['exclude', '(android|cairo|cf|cg|curl|fftw|gtk|haiku|linux|mac|mkl|opentype|posix|qt|soup|svg|symbian|win|wx)/'],
['exclude', '(?<!Chromium)(Android|Cairo|CF|CG|Curl|Gtk|Linux|Mac|OpenType|POSIX|Posix|Qt|Safari|Soup|Symbian|Win|Wx)\\.(cpp|mm?)$'],
# A few things can't be excluded by patterns. List them individually.
@@ -1270,6 +1283,11 @@
['include', 'platform/audio/mkl/FFTFrameMKL\\.cpp$'],
],
}],
+ ['(OS=="linux" or OS=="win") and "WTF_USE_WEBAUDIO_FFTW=1" in feature_defines', {
+ 'sources/': [
+ ['include', 'platform/audio/fftw/FFTFrameFFTW\\.cpp$'],
+ ],
+ }],
],
},
{
@@ -1501,6 +1519,23 @@
},
},
}],
+ ['OS=="linux" and "WTF_USE_WEBAUDIO_FFTW=1" in feature_defines', {
+ # FIXME: (kbr) figure out how to make these dependencies
+ # work in a cross-platform way. Attempts to use
+ # "link_settings" and "libraries" in conjunction with the
+ # msvs-specific settings didn't work so far.
+ 'all_dependent_settings': {
+ 'ldflags': [
+ # FIXME: (kbr) build the FFTW into PRODUCT_DIR using GYP.
+ '-Lthird_party/fftw/.libs',
+ ],
+ 'link_settings': {
+ 'libraries': [
+ '-lfftw3f'
+ ],
+ },
+ },
+ }],
['enable_svg!=0', {
'dependencies': [
'webcore_svg',
diff --git a/Source/WebCore/WebCore.gypi b/Source/WebCore/WebCore.gypi
index 6198c1f..ac6fe6b 100644
--- a/Source/WebCore/WebCore.gypi
+++ b/Source/WebCore/WebCore.gypi
@@ -2435,6 +2435,7 @@
'platform/audio/VectorMath.h',
'platform/audio/VectorMath.cpp',
'platform/audio/chromium/AudioBusChromium.cpp',
+ 'platform/audio/fftw/FFTFrameFFTW.cpp',
'platform/audio/mac/AudioBusMac.mm',
'platform/audio/mac/AudioDestinationMac.h',
'platform/audio/mac/AudioDestinationMac.cpp',
diff --git a/Source/WebCore/platform/audio/FFTFrame.h b/Source/WebCore/platform/audio/FFTFrame.h
index 1a82ef0..bfaa98d 100644
--- a/Source/WebCore/platform/audio/FFTFrame.h
+++ b/Source/WebCore/platform/audio/FFTFrame.h
@@ -35,8 +35,13 @@
#include <Accelerate/Accelerate.h>
#endif
-#if !OS(DARWIN) && USE(WEBAUDIO_MKL)
+#if !OS(DARWIN)
+#if USE(WEBAUDIO_MKL)
#include "mkl_dfti.h"
+#endif // USE(WEBAUDIO_MKL)
+#if USE(WEBAUDIO_FFTW)
+#include "fftw3.h"
+#endif // USE(WEBAUDIO_FFTW)
#endif
#include <wtf/PassOwnPtr.h>
@@ -98,8 +103,8 @@ private:
DSPSplitComplex m_frame;
AudioFloatArray m_realData;
AudioFloatArray m_imagData;
-#endif // OS(DARWIN)
-#if !OS(DARWIN) && USE(WEBAUDIO_MKL)
+#else // !OS(DARWIN)
+#if USE(WEBAUDIO_MKL)
// Interleaves the planar real and imaginary data and returns a
// pointer to the resulting storage which can be used for in-place
// or out-of-place operations. FIXME: ideally all of the MKL
@@ -115,7 +120,26 @@ private:
AudioFloatArray m_complexData;
AudioFloatArray m_realData;
AudioFloatArray m_imagData;
-#endif // !OS(DARWIN) && USE(WEBAUDIO_MKL)
+#endif // USE(WEBAUDIO_MKL)
+#if USE(WEBAUDIO_FFTW)
+ fftwf_plan m_forwardPlan;
+ fftwf_plan m_backwardPlan;
+
+ enum Direction {
+ Forward,
+ Backward
+ };
+
+ AudioFloatArray m_realData;
+ AudioFloatArray m_imagData;
+
+ static fftwf_plan* fftwForwardPlans;
+ static fftwf_plan* fftwBackwardPlans;
+
+ static fftwf_plan fftwPlanForSize(unsigned fftSize, Direction,
+ float*, float*, float*);
+#endif // USE(WEBAUDIO_FFTW)
+#endif // !OS(DARWIN)
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/audio/fftw/FFTFrameFFTW.cpp b/Source/WebCore/platform/audio/fftw/FFTFrameFFTW.cpp
new file mode 100644
index 0000000..c1f7ad1
--- /dev/null
+++ b/Source/WebCore/platform/audio/fftw/FFTFrameFFTW.cpp
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// FFTFrame implementation using the FFTW library.
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO)
+
+#include "FFTFrame.h"
+
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+const int kMaxFFTPow2Size = 24;
+
+fftwf_plan* FFTFrame::fftwForwardPlans = 0;
+fftwf_plan* FFTFrame::fftwBackwardPlans = 0;
+
+namespace {
+
+unsigned unpackedFFTWDataSize(unsigned fftSize)
+{
+ return fftSize / 2 + 1;
+}
+
+} // anonymous namespace
+
+
+// Normal constructor: allocates for a given fftSize.
+FFTFrame::FFTFrame(unsigned fftSize)
+ : m_FFTSize(fftSize)
+ , m_log2FFTSize(static_cast<unsigned>(log2(fftSize)))
+ , m_forwardPlan(0)
+ , m_backwardPlan(0)
+ , m_realData(unpackedFFTWDataSize(fftSize))
+ , m_imagData(unpackedFFTWDataSize(fftSize))
+{
+ // We only allow power of two.
+ ASSERT(1UL << m_log2FFTSize == m_FFTSize);
+
+ // FFTW won't create a plan without being able to look at non-null
+ // pointers for the input and output data; it wants to be able to
+ // see whether these arrays are aligned properly for vector
+ // operations. Ideally we would use fftw_malloc and fftw_free for
+ // the input and output arrays to ensure proper alignment for SIMD
+ // operations, so that we don't have to specify FFTW_UNALIGNED
+ // when creating the plan. However, since we don't have control
+ // over the alignment of the array passed to doFFT / doInverseFFT,
+ // we would need to memcpy it in to or out of the FFTFrame, adding
+ // overhead. For the time being, we just assume unaligned data and
+ // pass a temporary pointer down.
+
+ // FIXME: we should probably allocate both the source and destination
+ // arrays in this class and memcpy the data in and out of them.
+ float temporary;
+ m_forwardPlan = fftwPlanForSize(fftSize, Forward,
+ &temporary, realData(), imagData());
+ m_backwardPlan = fftwPlanForSize(fftSize, Backward,
+ realData(), imagData(), &temporary);
+}
+
+// Creates a blank/empty frame (interpolate() must later be called).
+FFTFrame::FFTFrame()
+ : m_FFTSize(0)
+ , m_log2FFTSize(0)
+ , m_forwardPlan(0)
+ , m_backwardPlan(0)
+{
+}
+
+// Copy constructor.
+FFTFrame::FFTFrame(const FFTFrame& frame)
+ : m_FFTSize(frame.m_FFTSize)
+ , m_log2FFTSize(frame.m_log2FFTSize)
+ , m_forwardPlan(0)
+ , m_backwardPlan(0)
+ , m_realData(unpackedFFTWDataSize(frame.m_FFTSize))
+ , m_imagData(unpackedFFTWDataSize(frame.m_FFTSize))
+{
+ // See the normal constructor for an explanation of the temporary pointer.
+ float temporary;
+ m_forwardPlan = fftwPlanForSize(m_FFTSize, Forward,
+ &temporary, realData(), imagData());
+ m_backwardPlan = fftwPlanForSize(m_FFTSize, Backward,
+ realData(), imagData(), &temporary);
+
+ // Copy/setup frame data.
+ size_t nbytes = sizeof(float) * unpackedFFTWDataSize(fftSize());
+ memcpy(realData(), frame.realData(), nbytes);
+ memcpy(imagData(), frame.imagData(), nbytes);
+}
+
+FFTFrame::~FFTFrame()
+{
+}
+
+void FFTFrame::multiply(const FFTFrame& frame)
+{
+ FFTFrame& frame1 = *this;
+ FFTFrame& frame2 = const_cast<FFTFrame&>(frame);
+
+ float* realP1 = frame1.realData();
+ float* imagP1 = frame1.imagData();
+ const float* realP2 = frame2.realData();
+ const float* imagP2 = frame2.imagData();
+
+ // Scale accounts the peculiar scaling of vecLib on the Mac.
+ // This ensures the right scaling all the way back to inverse FFT.
+ // FIXME: if we change the scaling on the Mac then this scale
+ // factor will need to change too.
+ float scale = 0.5f;
+
+ // Multiply the packed DC/nyquist component
+ realP1[0] *= scale * realP2[0];
+ imagP1[0] *= scale * imagP2[0];
+
+ // Complex multiplication. If this loop turns out to be hot then
+ // we should use SSE or other intrinsics to accelerate it.
+ unsigned halfSize = fftSize() / 2;
+
+ for (unsigned i = 1; i < halfSize; ++i) {
+ float realResult = realP1[i] * realP2[i] - imagP1[i] * imagP2[i];
+ float imagResult = realP1[i] * imagP2[i] + imagP1[i] * realP2[i];
+
+ realP1[i] = scale * realResult;
+ imagP1[i] = scale * imagResult;
+ }
+}
+
+void FFTFrame::doFFT(float* data)
+{
+ fftwf_execute_split_dft_r2c(m_forwardPlan, data, realData(), imagData());
+
+ // Scale the frequency domain data to match vecLib's scale factor
+ // on the Mac. FIXME: if we change the definition of FFTFrame to
+ // eliminate this scale factor then this code will need to change.
+ // Also, if this loop turns out to be hot then we should use SSE
+ // or other intrinsics to accelerate it.
+ float scaleFactor = 2;
+ unsigned length = unpackedFFTWDataSize(fftSize());
+ ASSERT(length == m_realData.size());
+ for (unsigned i = 0; i < length; ++i) {
+ m_realData[i] = m_realData[i] * scaleFactor;
+ m_imagData[i] = m_imagData[i] * scaleFactor;
+ }
+
+ // Move the Nyquist component to the location expected by the
+ // FFTFrame API.
+ m_imagData[0] = m_realData[length - 1];
+}
+
+void FFTFrame::doInverseFFT(float* data)
+{
+ // Move the Nyquist component to the location expected by FFTW.
+ unsigned length = unpackedFFTWDataSize(fftSize());
+ ASSERT(length = m_realData.size());
+ m_realData[length - 1] = m_imagData[0];
+ m_imagData[0] = 0;
+
+ fftwf_execute_split_dft_c2r(m_backwardPlan, realData(), imagData(), data);
+
+ // Restore the original scaling of the time domain data.
+ // FIXME: if we change the definition of FFTFrame to eliminate the
+ // scale factor then this code will need to change. Also, if this
+ // loop turns out to be hot then we should use SSE or other
+ // intrinsics to accelerate it.
+ float scaleFactor = 1.0 / (2.0 * fftSize());
+ for (unsigned i = 0; i < length; ++i)
+ data[i] *= scaleFactor;
+
+ // Move the Nyquist component back to the location expected by the
+ // FFTFrame API.
+ m_imagData[0] = m_realData[length - 1];
+}
+
+void FFTFrame::cleanup()
+{
+ if (!fftwForwardPlans)
+ return;
+
+ for (int i = 0; i < kMaxFFTPow2Size; ++i) {
+ if (fftwForwardPlans[i])
+ fftwf_destroy_plan(fftwForwardPlans[i]);
+ if (fftwBackwardPlans[i])
+ fftwf_destroy_plan(fftwBackwardPlans[i]);
+ }
+
+ delete[] fftwForwardPlans;
+ delete[] fftwBackwardPlans;
+
+ fftwForwardPlans = 0;
+ fftwBackwardPlans = 0;
+}
+
+float* FFTFrame::realData() const
+{
+ return const_cast<float*>(m_realData.data());
+}
+
+float* FFTFrame::imagData() const
+{
+ return const_cast<float*>(m_imagData.data());
+}
+
+fftwf_plan FFTFrame::fftwPlanForSize(unsigned fftSize, Direction direction,
+ float* data1, float* data2, float* data3)
+{
+ if (!fftwForwardPlans) {
+ fftwForwardPlans = new fftwf_plan[kMaxFFTPow2Size];
+ fftwBackwardPlans = new fftwf_plan[kMaxFFTPow2Size];
+ for (int i = 0; i < kMaxFFTPow2Size; ++i) {
+ fftwForwardPlans[i] = 0;
+ fftwBackwardPlans[i] = 0;
+ }
+ }
+
+ ASSERT(fftSize);
+ int pow2size = static_cast<int>(log2(fftSize));
+ ASSERT(pow2size < kMaxFFTPow2Size);
+ fftwf_plan* plans = (direction == Forward) ? fftwForwardPlans : fftwBackwardPlans;
+ if (!plans[pow2size]) {
+ fftwf_iodim dimension;
+ dimension.n = fftSize;
+ dimension.is = 1;
+ dimension.os = 1;
+
+ // For the time being, we do not take the input data into
+ // account when choosing a plan, so that we can most easily
+ // reuse plans with different input data.
+
+ // FIXME: allocate input and output data inside this class to
+ // be able to take advantage of alignment and SIMD optimizations.
+ unsigned flags = FFTW_ESTIMATE | FFTW_PRESERVE_INPUT | FFTW_UNALIGNED;
+ switch (direction) {
+ case Forward:
+ plans[pow2size] = fftwf_plan_guru_split_dft_r2c(1, &dimension, 0, 0,
+ data1, data2, data3,
+ flags);
+ break;
+ case Backward:
+ plans[pow2size] = fftwf_plan_guru_split_dft_c2r(1, &dimension, 0, 0,
+ data1, data2, data3,
+ flags);
+ break;
+ }
+ }
+ ASSERT(plans[pow2size]);
+ return plans[pow2size];
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_AUDIO)
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list