Mercurial > hg > vamp-plugin-sdk
comparison src/vamp-sdk/FFT.cpp @ 434:e979a9c4ffb6 vampipe
Switch from Cross FFT with option of FFTW build, to KissFFT only (code bundled). This is much faster than the default build and simpler than managing two options.
author | Chris Cannam |
---|---|
date | Tue, 16 Aug 2016 16:04:09 +0100 |
parents | abdf03252c8a |
children | 41baa6241da2 |
comparison
equal
deleted
inserted
replaced
432:8dea61e4a7be | 434:e979a9c4ffb6 |
---|---|
34 authorization. | 34 authorization. |
35 */ | 35 */ |
36 | 36 |
37 #include <vamp-sdk/FFT.h> | 37 #include <vamp-sdk/FFT.h> |
38 | 38 |
39 #include <cmath> | 39 #include <stdlib.h> |
40 #include <stdio.h> | |
41 #include <math.h> | |
42 #include <string.h> | |
40 | 43 |
41 #if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 7 ) | 44 #if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 7 ) |
42 #error Unexpected version of Vamp SDK header included | 45 #error Unexpected version of Vamp SDK header included |
43 #endif | 46 #endif |
44 | 47 |
45 #ifdef _MSC_VER | |
46 #include <stdlib.h> | |
47 #include <malloc.h> | |
48 #endif | |
49 | |
50 _VAMP_SDK_PLUGSPACE_BEGIN(FFT.cpp) | 48 _VAMP_SDK_PLUGSPACE_BEGIN(FFT.cpp) |
51 | 49 |
50 // Override C linkage for KissFFT headers. So long as we have already | |
51 // included all of the other (system etc) headers KissFFT depends on, | |
52 // this should work out OK | |
53 #undef __cplusplus | |
54 | |
55 namespace KissSingle { | |
56 #undef KISS_FFT_H | |
57 #undef KISS_FTR_H | |
58 #undef KISS_FFT__GUTS_H | |
59 #undef FIXED_POINT | |
60 #undef USE_SIMD | |
61 #undef kiss_fft_scalar | |
62 #define kiss_fft_scalar float | |
63 inline void free(void *ptr) { ::free(ptr); } | |
64 #include "ext/kiss_fft.c" | |
65 #include "ext/kiss_fftr.c" | |
66 } | |
67 | |
68 namespace KissDouble { | |
69 #undef KISS_FFT_H | |
70 #undef KISS_FTR_H | |
71 #undef KISS_FFT__GUTS_H | |
72 #undef FIXED_POINT | |
73 #undef USE_SIMD | |
74 #undef kiss_fft_scalar | |
75 #define kiss_fft_scalar double | |
76 inline void free(void *ptr) { ::free(ptr); } | |
77 #include "ext/kiss_fft.c" | |
78 #include "ext/kiss_fftr.c" | |
79 } | |
80 | |
52 namespace Vamp { | 81 namespace Vamp { |
53 | 82 |
54 #include "FFTimpl.cpp" | 83 void |
55 | 84 FFT::forward(unsigned int un, |
56 void | |
57 FFT::forward(unsigned int n, | |
58 const double *ri, const double *ii, | 85 const double *ri, const double *ii, |
59 double *ro, double *io) | 86 double *ro, double *io) |
60 { | 87 { |
61 fft(n, false, ri, ii, ro, io); | 88 int n(un); |
62 } | 89 KissDouble::kiss_fft_cfg c = KissDouble::kiss_fft_alloc(n, false, 0, 0); |
63 | 90 KissDouble::kiss_fft_cpx *in = new KissDouble::kiss_fft_cpx[n]; |
64 void | 91 KissDouble::kiss_fft_cpx *out = new KissDouble::kiss_fft_cpx[n]; |
65 FFT::inverse(unsigned int n, | 92 for (int i = 0; i < n; ++i) { |
93 in[i].r = ri[i]; | |
94 in[i].i = 0; | |
95 } | |
96 if (ii) { | |
97 for (int i = 0; i < n; ++i) { | |
98 in[i].i = ii[i]; | |
99 } | |
100 } | |
101 kiss_fft(c, in, out); | |
102 for (int i = 0; i < n; ++i) { | |
103 ro[i] = out[i].r; | |
104 io[i] = out[i].i; | |
105 } | |
106 KissDouble::kiss_fft_free(c); | |
107 delete[] in; | |
108 delete[] out; | |
109 } | |
110 | |
111 void | |
112 FFT::inverse(unsigned int un, | |
66 const double *ri, const double *ii, | 113 const double *ri, const double *ii, |
67 double *ro, double *io) | 114 double *ro, double *io) |
68 { | 115 { |
69 fft(n, true, ri, ii, ro, io); | 116 int n(un); |
117 KissDouble::kiss_fft_cfg c = KissDouble::kiss_fft_alloc(n, true, 0, 0); | |
118 KissDouble::kiss_fft_cpx *in = new KissDouble::kiss_fft_cpx[n]; | |
119 KissDouble::kiss_fft_cpx *out = new KissDouble::kiss_fft_cpx[n]; | |
120 for (int i = 0; i < n; ++i) { | |
121 in[i].r = ri[i]; | |
122 in[i].i = 0; | |
123 } | |
124 if (ii) { | |
125 for (int i = 0; i < n; ++i) { | |
126 in[i].i = ii[i]; | |
127 } | |
128 } | |
129 kiss_fft(c, in, out); | |
130 double scale = 1.0 / double(n); | |
131 for (int i = 0; i < n; ++i) { | |
132 ro[i] = out[i].r * scale; | |
133 io[i] = out[i].i * scale; | |
134 } | |
135 KissDouble::kiss_fft_free(c); | |
136 delete[] in; | |
137 delete[] out; | |
138 KissDouble::kiss_fft_free(c); | |
139 } | |
140 | |
141 class FFTReal::D | |
142 { | |
143 public: | |
144 | |
145 D(int n) : | |
146 m_n(n), | |
147 m_cf(KissSingle::kiss_fftr_alloc(n, false, 0, 0)), | |
148 m_ci(KissSingle::kiss_fftr_alloc(n, true, 0, 0)), | |
149 m_freq(new KissSingle::kiss_fft_cpx[n/2+1]) { } | |
150 | |
151 ~D() { | |
152 KissSingle::kiss_fftr_free(m_cf); | |
153 KissSingle::kiss_fftr_free(m_ci); | |
154 delete[] m_freq; | |
155 } | |
156 | |
157 void forward(const float *ri, float *co) { | |
158 KissSingle::kiss_fftr(m_cf, ri, m_freq); | |
159 int hs = m_n/2 + 1; | |
160 for (int i = 0; i < hs; ++i) { | |
161 co[i*2] = m_freq[i].r; | |
162 co[i*2+1] = m_freq[i].i; | |
163 } | |
164 } | |
165 | |
166 void inverse(const float *ci, float *ro) { | |
167 int hs = m_n/2 + 1; | |
168 for (int i = 0; i < hs; ++i) { | |
169 m_freq[i].r = ci[i*2]; | |
170 m_freq[i].i = ci[i*2+1]; | |
171 } | |
172 KissSingle::kiss_fftri(m_ci, m_freq, ro); | |
173 double scale = 1.0 / double(m_n); | |
174 for (int i = 0; i < m_n; ++i) { | |
175 ro[i] *= scale; | |
176 } | |
177 } | |
178 | |
179 private: | |
180 int m_n; | |
181 KissSingle::kiss_fftr_cfg m_cf; | |
182 KissSingle::kiss_fftr_cfg m_ci; | |
183 KissSingle::kiss_fft_cpx *m_freq; | |
184 }; | |
185 | |
186 FFTReal::FFTReal(unsigned int n) : | |
187 m_d(new D(n)) | |
188 { | |
189 } | |
190 | |
191 FFTReal::~FFTReal() | |
192 { | |
193 delete m_d; | |
194 } | |
195 | |
196 void | |
197 FFTReal::forward(const float *ri, float *co) | |
198 { | |
199 m_d->forward(ri, co); | |
200 } | |
201 | |
202 void | |
203 FFTReal::inverse(const float *ci, float *ro) | |
204 { | |
205 m_d->inverse(ci, ro); | |
70 } | 206 } |
71 | 207 |
72 } | 208 } |
73 | 209 |
74 _VAMP_SDK_PLUGSPACE_END(FFT.cpp) | 210 _VAMP_SDK_PLUGSPACE_END(FFT.cpp) |