Add support for using ARM FFT in WebAudio
https://bugs.webkit.org/show_bug.cgi?id=109755
Reviewed by Chris Rogers.
Source/WebCore:
No new tests.
* WebCore.gyp/WebCore.gyp: Add dependency on openmax_dl when use_openmax_dl_fft is enabled.
* WebCore.gypi: Add source FFTFrameOpenMAXDLAndroid.cpp
* platform/audio/AudioArray.h:
(WebCore::AudioArray::allocate): Need 32-byte aligntment with the
OpenMAX DL FFT.
* platform/audio/FFTFrame.h:
(FFTFrame): Support OpenMAX DL FFT
* platform/audio/FFTFrameStub.cpp: Support OpenMAX DL FFT
* platform/audio/chromium/FFTFrameOpenMAXDLAndroid.cpp: Added. Implements the
necessary interface using the OpenMAX DL FFT routines.
(WebCore):
(WebCore::FFTFrame::FFTFrame):
(WebCore::FFTFrame::initialize):
(WebCore::FFTFrame::cleanup):
(WebCore::FFTFrame::~FFTFrame):
(WebCore::FFTFrame::multiply):
(WebCore::FFTFrame::doFFT):
(WebCore::FFTFrame::doInverseFFT):
(WebCore::FFTFrame::realData):
(WebCore::FFTFrame::imagData):
(WebCore::FFTFrame::contextForSize):
Source/WebKit/chromium:
* features.gypi: Support building with the OpenMAX DL FFT.
git-svn-id: svn://svn.chromium.org/blink/trunk@147491 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 23723a7..220f86b 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,34 @@
+2013-04-02 Raymond Toy <rtoy@google.com>
+
+ Add support for using ARM FFT in WebAudio
+ https://bugs.webkit.org/show_bug.cgi?id=109755
+
+ Reviewed by Chris Rogers.
+
+ No new tests.
+
+ * WebCore.gyp/WebCore.gyp: Add dependency on openmax_dl when use_openmax_dl_fft is enabled.
+ * WebCore.gypi: Add source FFTFrameOpenMAXDLAndroid.cpp
+ * platform/audio/AudioArray.h:
+ (WebCore::AudioArray::allocate): Need 32-byte aligntment with the
+ OpenMAX DL FFT.
+ * platform/audio/FFTFrame.h:
+ (FFTFrame): Support OpenMAX DL FFT
+ * platform/audio/FFTFrameStub.cpp: Support OpenMAX DL FFT
+ * platform/audio/chromium/FFTFrameOpenMAXDLAndroid.cpp: Added. Implements the
+ necessary interface using the OpenMAX DL FFT routines.
+ (WebCore):
+ (WebCore::FFTFrame::FFTFrame):
+ (WebCore::FFTFrame::initialize):
+ (WebCore::FFTFrame::cleanup):
+ (WebCore::FFTFrame::~FFTFrame):
+ (WebCore::FFTFrame::multiply):
+ (WebCore::FFTFrame::doFFT):
+ (WebCore::FFTFrame::doInverseFFT):
+ (WebCore::FFTFrame::realData):
+ (WebCore::FFTFrame::imagData):
+ (WebCore::FFTFrame::contextForSize):
+
2013-04-02 Sudarsana Nagineni <sudarsana.nagineni@intel.com>
[GStreamer] Memory leaks in MediaPlayerPrivateGStreamer
diff --git a/Source/WebCore/WebCore.gyp/WebCore.gyp b/Source/WebCore/WebCore.gyp/WebCore.gyp
index 1d2e320..7d609d8 100644
--- a/Source/WebCore/WebCore.gyp/WebCore.gyp
+++ b/Source/WebCore/WebCore.gyp/WebCore.gyp
@@ -280,6 +280,11 @@
'<(SHARED_INTERMEDIATE_DIR)/webkit/bindings/V8DerivedSources19.cpp',
],
}],
+ ['OS=="android" and use_openmax_dl_fft!=0', {
+ 'webcore_include_dirs': [
+ '<(DEPTH)/third_party/openmax_dl'
+ ]
+ }],
],
}, # variables
@@ -1590,6 +1595,16 @@
'<(chromium_src_dir)/third_party/ffmpeg/ffmpeg.gyp:ffmpeg',
],
}],
+ ['"WTF_USE_WEBAUDIO_OPENMAX_DL_FFT=1" in feature_defines', {
+ 'direct_dependent_settings': {
+ 'include_dirs': [
+ '<(chromium_src_dir)/third_party/openmax_dl',
+ ],
+ },
+ 'dependencies': [
+ '<(chromium_src_dir)/third_party/openmax_dl/dl/dl.gyp:openmax_dl',
+ ],
+ }],
# Windows shared builder needs extra help for linkage
['OS=="win" and "WTF_USE_WEBAUDIO_FFMPEG=1" in feature_defines', {
'export_dependent_settings': [
diff --git a/Source/WebCore/WebCore.gypi b/Source/WebCore/WebCore.gypi
index 2e4af1f..c3d2926 100644
--- a/Source/WebCore/WebCore.gypi
+++ b/Source/WebCore/WebCore.gypi
@@ -3780,6 +3780,7 @@
'platform/audio/chromium/AudioBusChromium.cpp',
'platform/audio/chromium/AudioDestinationChromium.cpp',
'platform/audio/chromium/AudioDestinationChromium.h',
+ 'platform/audio/chromium/FFTFrameOpenMAXDLAndroid.cpp',
'platform/audio/ffmpeg/FFTFrameFFMPEG.cpp',
'platform/audio/mac/FFTFrameMac.cpp',
'platform/audio/mkl/FFTFrameMKL.cpp',
diff --git a/Source/WebCore/platform/audio/AudioArray.h b/Source/WebCore/platform/audio/AudioArray.h
index 0a6d873..b161cf2 100644
--- a/Source/WebCore/platform/audio/AudioArray.h
+++ b/Source/WebCore/platform/audio/AudioArray.h
@@ -60,7 +60,7 @@
unsigned initialSize = sizeof(T) * n;
-#if USE(WEBAUDIO_FFMPEG)
+#if USE(WEBAUDIO_FFMPEG) || USE(WEBAUDIO_OPENMAX_DL_FFT)
const size_t alignment = 32;
#else
const size_t alignment = 16;
diff --git a/Source/WebCore/platform/audio/FFTFrame.h b/Source/WebCore/platform/audio/FFTFrame.h
index 55ad09b..522cb5f 100644
--- a/Source/WebCore/platform/audio/FFTFrame.h
+++ b/Source/WebCore/platform/audio/FFTFrame.h
@@ -54,9 +54,12 @@
G_END_DECLS
#endif // USE(WEBAUDIO_GSTREAMER)
-#if USE(WEBAUDIO_FFMPEG)
+#if USE(WEBAUDIO_OPENMAX_DL_FFT)
+#include "dl/sp/api/armSP.h"
+#include "dl/sp/api/omxSP.h"
+#elif USE(WEBAUDIO_FFMPEG)
struct RDFTContext;
-#endif // USE(WEBAUDIO_FFMPEG)
+#endif
#endif // !USE_ACCELERATE_FFT
@@ -177,6 +180,17 @@
AudioFloatArray m_imagData;
#endif // USE(WEBAUDIO_IPP)
+#if USE(WEBAUDIO_OPENMAX_DL_FFT)
+ static OMXFFTSpec_R_F32* contextForSize(unsigned log2FFTSize);
+
+ OMXFFTSpec_R_F32* m_forwardContext;
+ OMXFFTSpec_R_F32* m_inverseContext;
+
+ AudioFloatArray m_complexData;
+ AudioFloatArray m_realData;
+ AudioFloatArray m_imagData;
+#endif
+
#endif // !USE_ACCELERATE_FFT
};
diff --git a/Source/WebCore/platform/audio/FFTFrameStub.cpp b/Source/WebCore/platform/audio/FFTFrameStub.cpp
index 6a27be5..3ad3284c 100644
--- a/Source/WebCore/platform/audio/FFTFrameStub.cpp
+++ b/Source/WebCore/platform/audio/FFTFrameStub.cpp
@@ -29,7 +29,7 @@
#if ENABLE(WEB_AUDIO)
-#if !OS(DARWIN) && !USE(WEBAUDIO_MKL) && !USE(WEBAUDIO_FFMPEG) && !USE(WEBAUDIO_GSTREAMER) && !USE(WEBAUDIO_IPP)
+#if !OS(DARWIN) && !USE(WEBAUDIO_MKL) && !USE(WEBAUDIO_FFMPEG) && !USE(WEBAUDIO_GSTREAMER) && !USE(WEBAUDIO_IPP) && !USE(WEBAUDIO_OPENMAX_DL_FFT)
#include "FFTFrame.h"
diff --git a/Source/WebCore/platform/audio/chromium/FFTFrameOpenMAXDLAndroid.cpp b/Source/WebCore/platform/audio/chromium/FFTFrameOpenMAXDLAndroid.cpp
new file mode 100644
index 0000000..a8fd3a2
--- /dev/null
+++ b/Source/WebCore/platform/audio/chromium/FFTFrameOpenMAXDLAndroid.cpp
@@ -0,0 +1,202 @@
+/* Copyright (C) 2013 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.
+ */
+
+#include "config.h"
+
+#if ENABLE(WEB_AUDIO)
+
+#if OS(ANDROID) && USE(WEBAUDIO_OPENMAX_DL_FFT)
+
+#include "FFTFrame.h"
+
+#include "AudioArray.h"
+#include "VectorMath.h"
+#include "dl/sp/api/armSP.h"
+#include "dl/sp/api/omxSP.h"
+
+#include <wtf/MathExtras.h>
+
+namespace WebCore {
+
+const int kMaxFFTPow2Size = 15;
+
+// Normal constructor: allocates for a given fftSize.
+FFTFrame::FFTFrame(unsigned fftSize)
+ : m_FFTSize(fftSize)
+ , m_log2FFTSize(static_cast<unsigned>(log2(fftSize)))
+ , m_forwardContext(0)
+ , m_inverseContext(0)
+ , m_complexData(fftSize)
+ , m_realData(fftSize / 2)
+ , m_imagData(fftSize / 2)
+{
+ // We only allow power of two.
+ ASSERT(1UL << m_log2FFTSize == m_FFTSize);
+
+ m_forwardContext = contextForSize(m_log2FFTSize);
+ m_inverseContext = contextForSize(m_log2FFTSize);
+}
+
+// Creates a blank/empty frame (interpolate() must later be called).
+FFTFrame::FFTFrame()
+ : m_FFTSize(0)
+ , m_log2FFTSize(0)
+ , m_forwardContext(0)
+ , m_inverseContext(0)
+{
+}
+
+// Copy constructor.
+FFTFrame::FFTFrame(const FFTFrame& frame)
+ : m_FFTSize(frame.m_FFTSize)
+ , m_log2FFTSize(frame.m_log2FFTSize)
+ , m_forwardContext(0)
+ , m_inverseContext(0)
+ , m_complexData(frame.m_FFTSize)
+ , m_realData(frame.m_FFTSize / 2)
+ , m_imagData(frame.m_FFTSize / 2)
+{
+ m_forwardContext = contextForSize(m_log2FFTSize);
+ m_inverseContext = contextForSize(m_log2FFTSize);
+
+ // Copy/setup frame data.
+ unsigned nbytes = sizeof(float) * (m_FFTSize / 2);
+ memcpy(realData(), frame.realData(), nbytes);
+ memcpy(imagData(), frame.imagData(), nbytes);
+}
+
+void FFTFrame::initialize()
+{
+}
+
+void FFTFrame::cleanup()
+{
+}
+
+FFTFrame::~FFTFrame()
+{
+ if (m_forwardContext)
+ free(m_forwardContext);
+ if (m_inverseContext)
+ free(m_inverseContext);
+}
+
+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();
+
+ unsigned halfSize = fftSize() / 2;
+ float real0 = realP1[0];
+ float imag0 = imagP1[0];
+
+ VectorMath::zvmul(realP1, imagP1, realP2, imagP2, realP1, imagP1, halfSize);
+
+ // Multiply the packed DC/nyquist component
+ realP1[0] = real0 * realP2[0];
+ imagP1[0] = imag0 * imagP2[0];
+}
+
+void FFTFrame::doFFT(const float* data)
+{
+ ASSERT(m_forwardContext);
+
+ if (m_forwardContext) {
+ AudioFloatArray complexFFT(m_FFTSize + 2);
+
+ omxSP_FFTFwd_RToCCS_F32_Sfs(data, complexFFT.data(), m_forwardContext);
+
+ unsigned len = m_FFTSize / 2;
+
+ // Split FFT data into real and imaginary arrays.
+ for (unsigned k = 1; k < len; ++k) {
+ int index = 2 * k;
+ m_realData[k] = complexFFT[index];
+ m_imagData[k] = complexFFT[index + 1];
+ }
+ m_realData[0] = complexFFT[0];
+ m_imagData[0] = complexFFT[m_FFTSize];
+ }
+}
+
+void FFTFrame::doInverseFFT(float* data)
+{
+ ASSERT(m_inverseContext);
+
+ if (m_inverseContext) {
+ AudioFloatArray fftData(m_FFTSize + 2);
+
+ unsigned len = m_FFTSize / 2;
+
+ // Pack the real and imaginary data into the complex array format
+ for (unsigned k = 1; k < len; ++k) {
+ int index = 2 * k;
+ fftData[index] = m_realData[k];
+ fftData[index + 1] = m_imagData[k];
+ }
+ fftData[0] = m_realData[0];
+ fftData[1] = 0;
+ fftData[m_FFTSize] = m_imagData[0];
+ fftData[m_FFTSize + 1] = 0;
+
+ omxSP_FFTInv_CCSToR_F32_Sfs(fftData.data(), data, m_inverseContext);
+ }
+}
+
+float* FFTFrame::realData() const
+{
+ return const_cast<float*>(m_realData.data());
+}
+
+float* FFTFrame::imagData() const
+{
+ return const_cast<float*>(m_imagData.data());
+}
+
+OMXFFTSpec_R_F32* FFTFrame::contextForSize(unsigned log2FFTSize)
+{
+ ASSERT(log2FFTSize);
+ ASSERT(log2FFTSize < kMaxFFTPow2Size);
+ int bufSize;
+ OMXResult status = omxSP_FFTGetBufSize_R_F32(log2FFTSize, &bufSize);
+
+ if (status == OMX_Sts_NoErr) {
+ OMXFFTSpec_R_F32* context = static_cast<OMXFFTSpec_R_F32*>(malloc(bufSize));
+ omxSP_FFTInit_R_F32(context, log2FFTSize);
+ return context;
+ }
+
+ return 0;
+}
+
+} // namespace WebCore
+
+#endif // #if OS(ANDROID) && !USE(WEBAUDIO_OPENMAX_DL_FFT)
+
+#endif // ENABLE(WEB_AUDIO)
diff --git a/Source/WebKit/chromium/ChangeLog b/Source/WebKit/chromium/ChangeLog
index 8cc5bd6..735e50d 100644
--- a/Source/WebKit/chromium/ChangeLog
+++ b/Source/WebKit/chromium/ChangeLog
@@ -1,3 +1,12 @@
+2013-04-02 Raymond Toy <rtoy@google.com>
+
+ Add support for using ARM FFT in WebAudio
+ https://bugs.webkit.org/show_bug.cgi?id=109755
+
+ Reviewed by Chris Rogers.
+
+ * features.gypi: Support building with the OpenMAX DL FFT.
+
2013-04-01 <webkit.review.bot@gmail.com>
[chromium] Roll chromium deps to 191760.
diff --git a/Source/WebKit/chromium/features.gypi b/Source/WebKit/chromium/features.gypi
index 2dc0b23..c57227a 100644
--- a/Source/WebKit/chromium/features.gypi
+++ b/Source/WebKit/chromium/features.gypi
@@ -185,7 +185,6 @@
# FIXME: Disable once the linking error has been resolved.
# https://bugs.webkit.org/show_bug.cgi?id=88636
'ENABLE_SHARED_WORKERS=1',
- 'ENABLE_WEB_AUDIO=0',
'WTF_USE_NATIVE_FULLSCREEN_VIDEO=1',
],
'enable_touch_icon_loading': 1,
@@ -232,6 +231,14 @@
'WTF_USE_WEBAUDIO_FFMPEG=1',
],
}],
+ ['OS=="android" and use_openmax_dl_fft!=0', {
+ 'feature_defines': [
+ 'WTF_USE_WEBAUDIO_OPENMAX_DL_FFT=1',
+ # Enabling the FFT is enough to enable WebAudio support to
+ # allow most WebAudio features to work on Android.
+ 'ENABLE_WEB_AUDIO=1',
+ ],
+ }],
['OS=="win" or OS=="android" or use_x11==1', {
'feature_defines': [
'ENABLE_OPENTYPE_VERTICAL=1',