OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | |
3 * Copyright (C) 2012 Intel Inc. All rights reserved. | |
4 * | |
5 * Redistribution and use in source and binary forms, with or without | |
6 * modification, are permitted provided that the following conditions | |
7 * are met: | |
8 * | |
9 * 1. Redistributions of source code must retain the above copyright | |
10 * notice, this list of conditions and the following disclaimer. | |
11 * 2. Redistributions in binary form must reproduce the above copyright | |
12 * notice, this list of conditions and the following disclaimer in the | |
13 * documentation and/or other materials provided with the distribution. | |
14 * | |
15 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY | |
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
18 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY | |
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
25 */ | |
26 | |
27 // FFTFrame implementation using Intel IPP's DFT algorithm, | |
28 // suitable for use on Linux. | |
29 | |
30 #include "platform/wtf/build_config.h" | |
31 | |
32 #if USE(WEBAUDIO_IPP) | |
33 | |
34 #include "platform/audio/FFTFrame.h" | |
35 | |
36 #include "platform/wtf/MathExtras.h" | |
37 | |
38 namespace blink { | |
39 | |
40 const unsigned maximumFFTPower2Size = 24; | |
41 | |
42 // Normal constructor: allocates for a given fftSize. | |
43 FFTFrame::FFTFrame(unsigned fftSize) | |
44 : m_FFTSize(fftSize), | |
45 m_log2FFTSize(static_cast<unsigned>(log2(fftSize))), | |
46 m_realData(fftSize / 2), | |
47 m_imagData(fftSize / 2), | |
48 m_complexData(fftSize) { | |
49 // We only allow power of two. | |
50 DCHECK_EQ(1UL << m_log2FFTSize, m_FFTSize); | |
51 DCHECK_LE(m_log2FFTSize, maximumFFTPower2Size); | |
52 | |
53 ippsDFTInitAlloc_R_32f(&m_DFTSpec, m_FFTSize, IPP_FFT_NODIV_BY_ANY, | |
54 ippAlgHintFast); | |
55 int bufferSize = 0; | |
56 ippsDFTGetBufSize_R_32f(m_DFTSpec, &bufferSize); | |
57 m_buffer = ippsMalloc_8u(bufferSize); | |
58 } | |
59 | |
60 // Creates a blank/empty frame (interpolate() must later be called). | |
61 FFTFrame::FFTFrame() : m_FFTSize(0), m_log2FFTSize(0) {} | |
62 | |
63 // Copy constructor. | |
64 FFTFrame::FFTFrame(const FFTFrame& frame) | |
65 : m_FFTSize(frame.m_FFTSize), | |
66 m_log2FFTSize(frame.m_log2FFTSize), | |
67 m_realData(frame.m_FFTSize / 2), | |
68 m_imagData(frame.m_FFTSize / 2), | |
69 m_complexData(frame.m_FFTSize) { | |
70 ippsDFTInitAlloc_R_32f(&m_DFTSpec, m_FFTSize, IPP_FFT_NODIV_BY_ANY, | |
71 ippAlgHintFast); | |
72 int bufferSize = 0; | |
73 ippsDFTGetBufSize_R_32f(m_DFTSpec, &bufferSize); | |
74 m_buffer = ippsMalloc_8u(bufferSize); | |
75 | |
76 // Copy/setup frame data. | |
77 unsigned numberOfBytes = sizeof(float) * m_FFTSize; | |
78 memcpy(realData(), frame.realData(), numberOfBytes); | |
79 memcpy(imagData(), frame.imagData(), numberOfBytes); | |
80 } | |
81 | |
82 void FFTFrame::initialize() {} | |
83 | |
84 void FFTFrame::cleanup() {} | |
85 | |
86 FFTFrame::~FFTFrame() { | |
87 ippsFree(m_buffer); | |
88 ippsDFTFree_R_32f(m_DFTSpec); | |
89 } | |
90 | |
91 void FFTFrame::doFFT(const float* data) { | |
92 Ipp32f* complexP = m_complexData.data(); | |
93 | |
94 // Compute Forward transform to perm format. | |
95 ippsDFTFwd_RToPerm_32f(reinterpret_cast<Ipp32f*>(const_cast<float*>(data)), | |
96 complexP, m_DFTSpec, m_buffer); | |
97 | |
98 Ipp32f* realP = m_realData.data(); | |
99 Ipp32f* imagP = m_imagData.data(); | |
100 ippsCplxToReal_32fc(reinterpret_cast<Ipp32fc*>(complexP), realP, imagP, | |
101 m_FFTSize >> 1); | |
102 } | |
103 | |
104 void FFTFrame::doInverseFFT(float* data) { | |
105 Ipp32f* complexP = getUpToDateComplexData(); | |
106 | |
107 // Compute inverse transform. | |
108 ippsDFTInv_PermToR_32f(complexP, reinterpret_cast<Ipp32f*>(data), m_DFTSpec, | |
109 m_buffer); | |
110 | |
111 // Scale so that a forward then inverse FFT yields exactly the original data. | |
112 const float scale = 1.0 / m_FFTSize; | |
113 | |
114 ippsMulC_32f_I(scale, reinterpret_cast<Ipp32f*>(data), m_FFTSize); | |
115 } | |
116 | |
117 float* FFTFrame::getUpToDateComplexData() { | |
118 int len = m_FFTSize >> 1; | |
119 // Merge the real and imagimary vectors to complex vector. | |
120 Ipp32f* realP = m_realData.data(); | |
121 Ipp32f* imagP = m_imagData.data(); | |
122 Ipp32fc* complexP = reinterpret_cast<Ipp32fc*>(m_complexData.data()); | |
123 ippsRealToCplx_32f(realP, imagP, complexP, len); | |
124 | |
125 return const_cast<float*>(m_complexData.data()); | |
126 } | |
127 | |
128 } // namespace blink | |
129 | |
130 #endif // USE(WEBAUDIO_IPP) | |
OLD | NEW |