1/*
2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1.  Redistributions of source code must retain the above copyright
9 *     notice, this list of conditions and the following disclaimer.
10 * 2.  Redistributions in binary form must reproduce the above copyright
11 *     notice, this list of conditions and the following disclaimer in the
12 *     documentation and/or other materials provided with the distribution.
13 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 *     its contributors may be used to endorse or promote products derived
15 *     from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef FFTFrame_h
30#define FFTFrame_h
31
32#include "platform/PlatformExport.h"
33#include "platform/audio/AudioArray.h"
34
35#if OS(MACOSX) && !USE(WEBAUDIO_FFMPEG)
36#define USE_ACCELERATE_FFT 1
37#else
38#define USE_ACCELERATE_FFT 0
39#endif
40
41#if USE_ACCELERATE_FFT
42#include <Accelerate/Accelerate.h>
43#endif
44
45#if !USE_ACCELERATE_FFT
46
47#if USE(WEBAUDIO_OPENMAX_DL_FFT)
48#include <dl/sp/api/omxSP.h>
49#elif USE(WEBAUDIO_FFMPEG)
50struct RDFTContext;
51#endif
52
53#endif // !USE_ACCELERATE_FFT
54
55#if USE(WEBAUDIO_IPP)
56#include <ipps.h>
57#endif // USE(WEBAUDIO_IPP)
58
59#include "wtf/Forward.h"
60#include "wtf/PassOwnPtr.h"
61#include "wtf/Threading.h"
62
63namespace WebCore {
64
65// Defines the interface for an "FFT frame", an object which is able to perform a forward
66// and reverse FFT, internally storing the resultant frequency-domain data.
67
68class PLATFORM_EXPORT FFTFrame {
69public:
70    // The constructors, destructor, and methods up to the CROSS-PLATFORM section have platform-dependent implementations.
71
72    FFTFrame(unsigned fftSize);
73    FFTFrame(); // creates a blank/empty frame for later use with createInterpolatedFrame()
74    FFTFrame(const FFTFrame& frame);
75    ~FFTFrame();
76
77    static void initialize();
78    static void cleanup();
79    void doFFT(const float* data);
80    void doInverseFFT(float* data);
81    void multiply(const FFTFrame& frame); // multiplies ourself with frame : effectively operator*=()
82
83    float* realData() const;
84    float* imagData() const;
85
86    void print(); // for debugging
87
88    // CROSS-PLATFORM
89    // The remaining public methods have cross-platform implementations:
90
91    // Interpolates from frame1 -> frame2 as x goes from 0.0 -> 1.0
92    static PassOwnPtr<FFTFrame> createInterpolatedFrame(const FFTFrame& frame1, const FFTFrame& frame2, double x);
93
94    void doPaddedFFT(const float* data, size_t dataSize); // zero-padding with dataSize <= fftSize
95    double extractAverageGroupDelay();
96    void addConstantGroupDelay(double sampleFrameDelay);
97
98    unsigned fftSize() const { return m_FFTSize; }
99    unsigned log2FFTSize() const { return m_log2FFTSize; }
100
101private:
102    unsigned m_FFTSize;
103    unsigned m_log2FFTSize;
104
105    void interpolateFrequencyComponents(const FFTFrame& frame1, const FFTFrame& frame2, double x);
106
107#if USE_ACCELERATE_FFT
108    DSPSplitComplex& dspSplitComplex() { return m_frame; }
109    DSPSplitComplex dspSplitComplex() const { return m_frame; }
110
111    static FFTSetup fftSetupForSize(unsigned fftSize);
112
113    static FFTSetup* fftSetups;
114
115    FFTSetup m_FFTSetup;
116
117    DSPSplitComplex m_frame;
118    AudioFloatArray m_realData;
119    AudioFloatArray m_imagData;
120#else // !USE_ACCELERATE_FFT
121
122#if USE(WEBAUDIO_FFMPEG)
123    static RDFTContext* contextForSize(unsigned fftSize, int trans);
124
125    RDFTContext* m_forwardContext;
126    RDFTContext* m_inverseContext;
127
128    float* getUpToDateComplexData();
129    AudioFloatArray m_complexData;
130    AudioFloatArray m_realData;
131    AudioFloatArray m_imagData;
132#endif // USE(WEBAUDIO_FFMPEG)
133
134#if USE(WEBAUDIO_IPP)
135    Ipp8u* m_buffer;
136    IppsDFTSpec_R_32f* m_DFTSpec;
137
138    float* getUpToDateComplexData();
139    AudioFloatArray m_complexData;
140    AudioFloatArray m_realData;
141    AudioFloatArray m_imagData;
142#endif // USE(WEBAUDIO_IPP)
143
144#if USE(WEBAUDIO_OPENMAX_DL_FFT)
145    static OMXFFTSpec_R_F32* contextForSize(unsigned log2FFTSize);
146
147    OMXFFTSpec_R_F32* m_forwardContext;
148    OMXFFTSpec_R_F32* m_inverseContext;
149
150    AudioFloatArray m_complexData;
151    AudioFloatArray m_realData;
152    AudioFloatArray m_imagData;
153#endif
154
155#endif // !USE_ACCELERATE_FFT
156};
157
158} // namespace WebCore
159
160#endif // FFTFrame_h
161