diff options
Diffstat (limited to 'WebCore/platform/audio/mkl/FFTFrameMKL.cpp')
-rw-r--r-- | WebCore/platform/audio/mkl/FFTFrameMKL.cpp | 260 |
1 files changed, 0 insertions, 260 deletions
diff --git a/WebCore/platform/audio/mkl/FFTFrameMKL.cpp b/WebCore/platform/audio/mkl/FFTFrameMKL.cpp deleted file mode 100644 index f66a485..0000000 --- a/WebCore/platform/audio/mkl/FFTFrameMKL.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2010 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 Intel's Math Kernel Library (MKL), -// suitable for use on Windows and Linux. - -#include "config.h" - -#if ENABLE(WEB_AUDIO) - -#include "FFTFrame.h" - -#include "mkl_vml.h" -#include <wtf/MathExtras.h> - -namespace { - -DFTI_DESCRIPTOR_HANDLE createDescriptorHandle(int fftSize) -{ - DFTI_DESCRIPTOR_HANDLE handle = 0; - - // Create DFTI descriptor for 1D single precision transform. - MKL_LONG status = DftiCreateDescriptor(&handle, DFTI_SINGLE, DFTI_REAL, 1, fftSize); - ASSERT(DftiErrorClass(status, DFTI_NO_ERROR)); - - // Set placement of result to DFTI_NOT_INPLACE. - status = DftiSetValue(handle, DFTI_PLACEMENT, DFTI_NOT_INPLACE); - ASSERT(DftiErrorClass(status, DFTI_NO_ERROR)); - - // Set packing format to PERM; this produces the layout which - // matches Accelerate.framework's on the Mac, though interleaved. - status = DftiSetValue(handle, DFTI_PACKED_FORMAT, DFTI_PERM_FORMAT); - ASSERT(DftiErrorClass(status, DFTI_NO_ERROR)); - - // Set the forward scale factor to 2 to match Accelerate.framework's. - // FIXME: FFTFrameMac's scaling factor could be fixed to be 1.0, - // in which case this code would need to be changed as well. - status = DftiSetValue(handle, DFTI_FORWARD_SCALE, 2.0); - ASSERT(DftiErrorClass(status, DFTI_NO_ERROR)); - - // Set the backward scale factor to 1 / 2n to match Accelerate.framework's. - // FIXME: if the above scaling factor is fixed then this needs to be as well. - double scale = 1.0 / (2.0 * fftSize); - status = DftiSetValue(handle, DFTI_BACKWARD_SCALE, scale); - ASSERT(DftiErrorClass(status, DFTI_NO_ERROR)); - - // Use the default DFTI_CONJUGATE_EVEN_STORAGE = DFTI_COMPLEX_REAL. - - // Commit DFTI descriptor. - status = DftiCommitDescriptor(handle); - ASSERT(DftiErrorClass(status, DFTI_NO_ERROR)); - - return handle; -} - -} // anonymous namespace - -namespace WebCore { - -const int kMaxFFTPow2Size = 24; - -DFTI_DESCRIPTOR_HANDLE* FFTFrame::descriptorHandles = 0; - -// Normal constructor: allocates for a given fftSize. -FFTFrame::FFTFrame(unsigned fftSize) - : m_FFTSize(fftSize) - , m_log2FFTSize(static_cast<unsigned>(log2(fftSize))) - , m_handle(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_handle = descriptorHandleForSize(fftSize); -} - -// Creates a blank/empty frame (interpolate() must later be called). -FFTFrame::FFTFrame() - : m_FFTSize(0) - , m_log2FFTSize(0) - , m_handle(0) -{ -} - -// Copy constructor. -FFTFrame::FFTFrame(const FFTFrame& frame) - : m_FFTSize(frame.m_FFTSize) - , m_log2FFTSize(frame.m_log2FFTSize) - , m_handle(0) - , m_complexData(frame.m_FFTSize) - , m_realData(frame.m_FFTSize / 2) - , m_imagData(frame.m_FFTSize / 2) -{ - m_handle = descriptorHandleForSize(m_FFTSize); - - // Copy/setup frame data. - unsigned nbytes = sizeof(float) * (m_FFTSize / 2); - 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 for vecLib's peculiar scaling. - // This ensures the right scaling all the way back to inverse FFT. - // FIXME: this scaling factor will be 1.0f if the above 2.0 -> 1.0 - // scaling factor is fixed. - float scale = 0.5f; - - // Multiply packed DC/nyquist component. - realP1[0] *= scale * realP2[0]; - imagP1[0] *= scale * imagP2[0]; - - // Multiply the rest, skipping packed DC/Nyquist components. - float* interleavedData1 = frame1.getUpToDateComplexData(); - float* interleavedData2 = frame2.getUpToDateComplexData(); - - unsigned halfSize = m_FFTSize / 2; - - // Complex multiply. - vcMul(halfSize - 1, - reinterpret_cast<MKL_Complex8*>(interleavedData1) + 1, - reinterpret_cast<MKL_Complex8*>(interleavedData2) + 1, - reinterpret_cast<MKL_Complex8*>(interleavedData1) + 1); - - // De-interleave and scale the rest of the data. - // FIXME: find an MKL routine to do at least the scaling more efficiently. - for (unsigned i = 1; i < halfSize; ++i) { - int baseComplexIndex = 2 * i; - realP1[i] = scale * interleavedData1[baseComplexIndex]; - imagP1[i] = scale * interleavedData1[baseComplexIndex + 1]; - } -} - -void FFTFrame::doFFT(float* data) -{ - // Compute Forward transform. - MKL_LONG status = DftiComputeForward(m_handle, data, m_complexData.data()); - ASSERT(DftiErrorClass(status, DFTI_NO_ERROR)); - - // De-interleave to separate real and complex arrays. FIXME: - // figure out if it's possible to get MKL to use split-complex - // form for 1D real-to-complex out-of-place FFTs. - int len = m_FFTSize / 2; - for (int i = 0; i < len; ++i) { - int baseComplexIndex = 2 * i; - // m_realData[0] is the DC component and m_imagData[0] the - // Nyquist component since the interleaved complex data is - // packed. - m_realData[i] = m_complexData[baseComplexIndex]; - m_imagData[i] = m_complexData[baseComplexIndex + 1]; - } -} - -void FFTFrame::doInverseFFT(float* data) -{ - // Prepare interleaved data. FIXME: figure out if it's possible to - // get MKL to use split-complex form for 1D backward - // (complex-to-real) out-of-place FFTs. - float* interleavedData = getUpToDateComplexData(); - - // Compute backward transform. - MKL_LONG status = DftiComputeBackward(m_handle, interleavedData, data); - ASSERT(DftiErrorClass(status, DFTI_NO_ERROR)); -} - -void FFTFrame::cleanup() -{ - if (!descriptorHandles) - return; - - for (int i = 0; i < kMaxFFTPow2Size; ++i) { - if (descriptorHandles[i]) { - MKL_LONG status = DftiFreeDescriptor(&descriptorHandles[i]); - ASSERT(DftiErrorClass(status, DFTI_NO_ERROR)); - } - } - - delete[] descriptorHandles; - descriptorHandles = 0; -} - -float* FFTFrame::realData() const -{ - return const_cast<float*>(m_realData.data()); -} - -float* FFTFrame::imagData() const -{ - return const_cast<float*>(m_imagData.data()); -} - -float* FFTFrame::getUpToDateComplexData() -{ - // FIXME: if we can't completely get rid of this method, SSE - // optimization could be considered if it shows up hot on profiles. - int len = m_FFTSize / 2; - for (int i = 0; i < len; ++i) { - int baseComplexIndex = 2 * i; - m_complexData[baseComplexIndex] = m_realData[i]; - m_complexData[baseComplexIndex + 1] = m_imagData[i]; - } - return const_cast<float*>(m_complexData.data()); -} - -DFTI_DESCRIPTOR_HANDLE FFTFrame::descriptorHandleForSize(unsigned fftSize) -{ - if (!descriptorHandles) { - descriptorHandles = new DFTI_DESCRIPTOR_HANDLE[kMaxFFTPow2Size]; - for (int i = 0; i < kMaxFFTPow2Size; ++i) - descriptorHandles[i] = 0; - } - - ASSERT(fftSize); - int pow2size = static_cast<int>(log2(fftSize)); - ASSERT(pow2size < kMaxFFTPow2Size); - if (!descriptorHandles[pow2size]) - descriptorHandles[pow2size] = createDescriptorHandle(fftSize); - return descriptorHandles[pow2size]; -} - -} // namespace WebCore - -#endif // ENABLE(WEB_AUDIO) |