Mercurial > hg > qm-dsp
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 |