comparison dsp/transforms/FFT.cpp @ 309:d5014ab8b0e5

* Add GPL and README; some tidying
author Chris Cannam <c.cannam@qmul.ac.uk>
date Mon, 13 Dec 2010 14:55:28 +0000
parents 5f2c9119a94a
children f6ccde089491
comparison
equal deleted inserted replaced
308:25af9a1e4ec3 309:d5014ab8b0e5
12 #include "maths/MathUtilities.h" 12 #include "maths/MathUtilities.h"
13 13
14 #include <cmath> 14 #include <cmath>
15 15
16 #include <iostream> 16 #include <iostream>
17
18 //#define USE_BUILTIN_FFT 1
19
20 #ifdef USE_BUILTIN_FFT
21 17
22 FFT::FFT(unsigned int n) : 18 FFT::FFT(unsigned int n) :
23 m_n(n), 19 m_n(n),
24 m_private(0) 20 m_private(0)
25 { 21 {
181 p_lpImagOut[i] /= denom; 177 p_lpImagOut[i] /= denom;
182 } 178 }
183 } 179 }
184 } 180 }
185 181
186 #else
187
188 #include "kissfft/kiss_fft.h"
189 #include "kissfft/kiss_fftr.h"
190
191 struct KissFFTRec {
192 kiss_fft_cfg forward;
193 kiss_fft_cfg inverse;
194 kiss_fft_cpx *in;
195 kiss_fft_cpx *out;
196 };
197
198 FFT::FFT(unsigned int n) :
199 m_n(n),
200 m_private(0)
201 {
202 if (m_n & 1) {
203 std::cerr << "Error: Odd FFT size " << m_n
204 << " not supported in this implementation"
205 << std::endl;
206 return;
207 }
208 KissFFTRec *rec = new KissFFTRec;
209 rec->forward = kiss_fft_alloc(m_n, 0, 0, 0);
210 rec->inverse = kiss_fft_alloc(m_n, 1, 0, 0);
211 rec->in = new kiss_fft_cpx[m_n];
212 rec->out = new kiss_fft_cpx[m_n];
213 m_private = rec;
214 }
215
216 FFT::~FFT()
217 {
218 if (!m_private) return;
219 KissFFTRec *rec = (KissFFTRec *)m_private;
220 kiss_fft_free(rec->forward);
221 kiss_fft_free(rec->inverse);
222 delete[] rec->in;
223 delete[] rec->out;
224 }
225
226 void
227 FFT::process(bool inverse,
228 const double *rin, const double *iin,
229 double *rout, double *iout)
230 {
231 if (!m_private) return;
232 KissFFTRec *rec = (KissFFTRec *)m_private;
233 for (int i = 0; i < m_n; ++i) {
234 rec->in[i].r = rin[i];
235 }
236 if (iin) {
237 for (int i = 0; i < m_n; ++i) {
238 rec->in[i].i = iin[i];
239 }
240 } else {
241 for (int i = 0; i < m_n; ++i) {
242 rec->in[i].i = 0.0;
243 }
244 }
245 if (inverse) {
246 kiss_fft(rec->inverse, rec->in, rec->out);
247 } else {
248 kiss_fft(rec->forward, rec->in, rec->out);
249 }
250 for (int i = 0; i < m_n; ++i) {
251 rout[i] = rec->out[i].r;
252 iout[i] = rec->out[i].i;
253 }
254 }
255
256 struct KissFFTRealRec {
257 kiss_fftr_cfg forward;
258 kiss_fftr_cfg inverse;
259 kiss_fft_cpx *out;
260 };
261
262 FFTReal::FFTReal(unsigned int n) :
263 m_n(n),
264 m_private(0)
265 {
266 if (m_n & 1) {
267 std::cerr << "Error: Odd FFT size " << m_n
268 << " not supported in this implementation"
269 << std::endl;
270 return;
271 }
272 KissFFTRealRec *rec = new KissFFTRealRec;
273 rec->forward = kiss_fftr_alloc(m_n, 0, 0, 0);
274 rec->inverse = kiss_fftr_alloc(m_n, 1, 0, 0);
275 rec->out = new kiss_fft_cpx[m_n];
276 m_private = rec;
277 }
278
279 FFTReal::~FFTReal()
280 {
281 if (!m_private) return;
282 KissFFTRealRec *rec = (KissFFTRealRec *)m_private;
283 kiss_fftr_free(rec->forward);
284 kiss_fftr_free(rec->inverse);
285 delete[] rec->out;
286 }
287
288 void
289 FFTReal::process(bool inverse,
290 const double *rin,
291 double *rout, double *iout)
292 {
293 if (!m_private) return;
294 KissFFTRealRec *rec = (KissFFTRealRec *)m_private;
295 if (inverse) {
296 kiss_fftr(rec->inverse, rin, rec->out);
297 for (int i = 0; i < m_n; ++i) {
298 rout[i] = rec->out[i].r;
299 iout[i] = rec->out[i].i;
300 }
301 } else {
302 kiss_fftr(rec->forward, rin, rec->out);
303 rout[0] = rec->out[0].r;
304 iout[0] = rec->out[0].i;
305 for (int i = 1; i < m_n/2; ++i) {
306 rout[m_n-i] = rout[i] = rec->out[i].r;
307 }
308 for (int i = 1; i < m_n/2; ++i) {
309 iout[i] = rec->out[i].i;
310 iout[m_n-i] = -iout[i];
311 }
312 rout[m_n/2] = rec->out[m_n/2].r;
313 iout[m_n/2] = rec->out[m_n/2].i;
314 }
315 }
316
317 #endif