Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / audio / android / FFTFrameOpenMAXDLAndroid.cpp
1 /* Copyright (C) 2013 Google Inc. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions
5  * are met:
6  *
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
20  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #if ENABLE(WEB_AUDIO)
28
29 #if OS(ANDROID) && USE(WEBAUDIO_OPENMAX_DL_FFT)
30
31 #include "platform/audio/FFTFrame.h"
32
33 #include "platform/audio/AudioArray.h"
34 #include "wtf/MathExtras.h"
35 #include <dl/sp/api/armSP.h>
36 #include <dl/sp/api/omxSP.h>
37
38 namespace blink {
39
40 #if ENABLE(ASSERT)
41 const unsigned kMaxFFTPow2Size = 15;
42 #endif
43
44 // Normal constructor: allocates for a given fftSize.
45 FFTFrame::FFTFrame(unsigned fftSize)
46     : m_FFTSize(fftSize)
47     , m_log2FFTSize(static_cast<unsigned>(log2(fftSize)))
48     , m_realData(fftSize / 2)
49     , m_imagData(fftSize / 2)
50     , m_forwardContext(0)
51     , m_inverseContext(0)
52     , m_complexData(fftSize)
53 {
54     // We only allow power of two.
55     ASSERT(1UL << m_log2FFTSize == m_FFTSize);
56
57     m_forwardContext = contextForSize(m_log2FFTSize);
58     m_inverseContext = contextForSize(m_log2FFTSize);
59 }
60
61 // Creates a blank/empty frame (interpolate() must later be called).
62 FFTFrame::FFTFrame()
63     : m_FFTSize(0)
64     , m_log2FFTSize(0)
65     , m_forwardContext(0)
66     , m_inverseContext(0)
67 {
68 }
69
70 // Copy constructor.
71 FFTFrame::FFTFrame(const FFTFrame& frame)
72     : m_FFTSize(frame.m_FFTSize)
73     , m_log2FFTSize(frame.m_log2FFTSize)
74     , m_realData(frame.m_FFTSize / 2)
75     , m_imagData(frame.m_FFTSize / 2)
76     , m_forwardContext(0)
77     , m_inverseContext(0)
78     , m_complexData(frame.m_FFTSize)
79 {
80     m_forwardContext = contextForSize(m_log2FFTSize);
81     m_inverseContext = contextForSize(m_log2FFTSize);
82
83     // Copy/setup frame data.
84     unsigned nbytes = sizeof(float) * (m_FFTSize / 2);
85     memcpy(realData(), frame.realData(), nbytes);
86     memcpy(imagData(), frame.imagData(), nbytes);
87 }
88
89 void FFTFrame::initialize()
90 {
91 }
92
93 void FFTFrame::cleanup()
94 {
95 }
96
97 FFTFrame::~FFTFrame()
98 {
99     if (m_forwardContext)
100         free(m_forwardContext);
101     if (m_inverseContext)
102         free(m_inverseContext);
103 }
104
105 void FFTFrame::doFFT(const float* data)
106 {
107     ASSERT(m_forwardContext);
108
109     if (m_forwardContext) {
110         AudioFloatArray complexFFT(m_FFTSize + 2);
111
112         omxSP_FFTFwd_RToCCS_F32(data, complexFFT.data(), m_forwardContext);
113
114         unsigned len = m_FFTSize / 2;
115
116         // Split FFT data into real and imaginary arrays.
117         const float* c = complexFFT.data();
118         float* real = m_realData.data();
119         float* imag = m_imagData.data();
120         for (unsigned k = 1; k < len; ++k) {
121             int index = 2 * k;
122             real[k] = c[index];
123             imag[k] = c[index + 1];
124         }
125         real[0] = c[0];
126         imag[0] = c[m_FFTSize];
127     }
128 }
129
130 void FFTFrame::doInverseFFT(float* data)
131 {
132     ASSERT(m_inverseContext);
133
134     if (m_inverseContext) {
135         AudioFloatArray fftDataArray(m_FFTSize + 2);
136
137         unsigned len = m_FFTSize / 2;
138
139         // Pack the real and imaginary data into the complex array format
140         float* fftData = fftDataArray.data();
141         const float* real = m_realData.data();
142         const float* imag = m_imagData.data();
143         for (unsigned k = 1; k < len; ++k) {
144             int index = 2 * k;
145             fftData[index] = real[k];
146             fftData[index + 1] = imag[k];
147         }
148         fftData[0] = real[0];
149         fftData[1] = 0;
150         fftData[m_FFTSize] = imag[0];
151         fftData[m_FFTSize + 1] = 0;
152
153         omxSP_FFTInv_CCSToR_F32(fftData, data, m_inverseContext);
154     }
155 }
156
157 OMXFFTSpec_R_F32* FFTFrame::contextForSize(unsigned log2FFTSize)
158 {
159     ASSERT(log2FFTSize);
160     ASSERT(log2FFTSize <= kMaxFFTPow2Size);
161     int bufSize;
162     OMXResult status = omxSP_FFTGetBufSize_R_F32(log2FFTSize, &bufSize);
163
164     if (status == OMX_Sts_NoErr) {
165         OMXFFTSpec_R_F32* context = static_cast<OMXFFTSpec_R_F32*>(malloc(bufSize));
166         omxSP_FFTInit_R_F32(context, log2FFTSize);
167         return context;
168     }
169
170     return 0;
171 }
172
173 } // namespace blink
174
175 #endif // #if OS(ANDROID) && !USE(WEBAUDIO_OPENMAX_DL_FFT)
176
177 #endif // ENABLE(WEB_AUDIO)