1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
5 An audio time-stretching and pitch-shifting library.
6 Copyright 2007-2008 Chris Cannam.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version. See the file
12 COPYING included with this distribution for more information.
19 //#define FFT_MEASUREMENT 1
21 #define HAVE_FFTW3 // for Ardour
30 #include "bsd-3rdparty/kissfft/kiss_fftr.h"
35 #ifndef USE_BUILTIN_FFT
36 #error No FFT implementation selected!
48 namespace RubberBand {
53 virtual ~FFTImpl() { }
55 virtual void initFloat() = 0;
56 virtual void initDouble() = 0;
58 virtual void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut) = 0;
59 virtual void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) = 0;
60 virtual void forwardMagnitude(const double *R__ realIn, double *R__ magOut) = 0;
62 virtual void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut) = 0;
63 virtual void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) = 0;
64 virtual void forwardMagnitude(const float *R__ realIn, float *R__ magOut) = 0;
66 virtual void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut) = 0;
67 virtual void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) = 0;
68 virtual void inverseCepstral(const double *R__ magIn, double *R__ cepOut) = 0;
70 virtual void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut) = 0;
71 virtual void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) = 0;
72 virtual void inverseCepstral(const float *R__ magIn, float *R__ cepOut) = 0;
74 virtual float *getFloatTimeBuffer() = 0;
75 virtual double *getDoubleTimeBuffer() = 0;
83 // Define FFTW_DOUBLE_ONLY to make all uses of FFTW functions be
84 // double-precision (so "float" FFTs are calculated by casting to
85 // doubles and using the double-precision FFTW function).
87 // Define FFTW_FLOAT_ONLY to make all uses of FFTW functions be
88 // single-precision (so "double" FFTs are calculated by casting to
89 // floats and using the single-precision FFTW function).
91 // Neither of these flags is terribly desirable -- FFTW_FLOAT_ONLY
92 // obviously loses you precision, and neither is handled in the most
93 // efficient way so any performance improvement will be small at best.
94 // The only real reason to define either flag would be to avoid
95 // linking against both fftw3 and fftw3f libraries.
97 //#define FFTW_DOUBLE_ONLY 1
98 //#define FFTW_FLOAT_ONLY 1
100 #if defined(FFTW_DOUBLE_ONLY) && defined(FFTW_FLOAT_ONLY)
101 // Can't meaningfully define both
102 #undef FFTW_DOUBLE_ONLY
103 #undef FFTW_FLOAT_ONLY
106 #ifdef FFTW_DOUBLE_ONLY
107 #define fft_float_type double
108 #define fftwf_complex fftw_complex
109 #define fftwf_plan fftw_plan
110 #define fftwf_plan_dft_r2c_1d fftw_plan_dft_r2c_1d
111 #define fftwf_plan_dft_c2r_1d fftw_plan_dft_c2r_1d
112 #define fftwf_destroy_plan fftw_destroy_plan
113 #define fftwf_malloc fftw_malloc
114 #define fftwf_free fftw_free
115 #define fftwf_execute fftw_execute
121 #define fft_float_type float
122 #endif /* FFTW_DOUBLE_ONLY */
124 #ifdef FFTW_FLOAT_ONLY
125 #define fft_double_type float
126 #define fftw_complex fftwf_complex
127 #define fftw_plan fftwf_plan
128 #define fftw_plan_dft_r2c_1d fftwf_plan_dft_r2c_1d
129 #define fftw_plan_dft_c2r_1d fftwf_plan_dft_c2r_1d
130 #define fftw_destroy_plan fftwf_destroy_plan
131 #define fftw_malloc fftwf_malloc
132 #define fftw_free fftwf_free
133 #define fftw_execute fftwf_execute
139 #define fft_double_type double
140 #endif /* FFTW_FLOAT_ONLY */
142 class D_FFTW : public FFTImpl
145 D_FFTW(int size) : m_fplanf(0)
146 #ifdef FFTW_DOUBLE_ONLY
150 #ifdef FFTW_FLOAT_ONLY
160 m_extantMutex.lock();
161 if (m_extantf > 0 && --m_extantf == 0) save = true;
162 m_extantMutex.unlock();
163 #ifndef FFTW_DOUBLE_ONLY
164 if (save) saveWisdom('f');
166 fftwf_destroy_plan(m_fplanf);
167 fftwf_destroy_plan(m_fplani);
169 fftwf_free(m_fpacked);
170 #ifdef FFTW_DOUBLE_ONLY
171 if (m_frb) fftw_free(m_frb);
176 m_extantMutex.lock();
177 if (m_extantd > 0 && --m_extantd == 0) save = true;
178 m_extantMutex.unlock();
179 #ifndef FFTW_FLOAT_ONLY
180 if (save) saveWisdom('d');
182 fftw_destroy_plan(m_dplanf);
183 fftw_destroy_plan(m_dplani);
185 fftw_free(m_dpacked);
186 #ifdef FFTW_FLOAT_ONLY
187 if (m_drb) fftwf_free(m_drb);
193 if (m_fplanf) return;
195 m_extantMutex.lock();
196 if (m_extantf++ == 0) load = true;
197 m_extantMutex.unlock();
198 #ifdef FFTW_DOUBLE_ONLY
199 if (load) loadWisdom('d');
201 if (load) loadWisdom('f');
203 m_fbuf = (fft_float_type *)fftw_malloc(m_size * sizeof(fft_float_type));
204 m_fpacked = (fftwf_complex *)fftw_malloc
205 ((m_size/2 + 1) * sizeof(fftwf_complex));
206 m_fplanf = fftwf_plan_dft_r2c_1d
207 (m_size, m_fbuf, m_fpacked, FFTW_MEASURE);
208 m_fplani = fftwf_plan_dft_c2r_1d
209 (m_size, m_fpacked, m_fbuf, FFTW_MEASURE);
213 if (m_dplanf) return;
215 m_extantMutex.lock();
216 if (m_extantd++ == 0) load = true;
217 m_extantMutex.unlock();
218 #ifdef FFTW_FLOAT_ONLY
219 if (load) loadWisdom('f');
221 if (load) loadWisdom('d');
223 m_dbuf = (fft_double_type *)fftw_malloc(m_size * sizeof(fft_double_type));
224 m_dpacked = (fftw_complex *)fftw_malloc
225 ((m_size/2 + 1) * sizeof(fftw_complex));
226 m_dplanf = fftw_plan_dft_r2c_1d
227 (m_size, m_dbuf, m_dpacked, FFTW_MEASURE);
228 m_dplani = fftw_plan_dft_c2r_1d
229 (m_size, m_dpacked, m_dbuf, FFTW_MEASURE);
232 void loadWisdom(char type) { wisdom(false, type); }
233 void saveWisdom(char type) { wisdom(true, type); }
235 void wisdom(bool save, char type) {
237 #ifdef FFTW_DOUBLE_ONLY
238 if (type == 'f') return;
240 #ifdef FFTW_FLOAT_ONLY
241 if (type == 'd') return;
244 const char *home = getenv("HOME");
248 snprintf(fn, 256, "%s/%s.%c", home, ".rubberband.wisdom", type);
250 FILE *f = fopen(fn, save ? "wb" : "rb");
255 #ifdef FFTW_DOUBLE_ONLY
258 case 'f': fftwf_export_wisdom_to_file(f); break;
260 #ifdef FFTW_FLOAT_ONLY
263 case 'd': fftw_export_wisdom_to_file(f); break;
269 #ifdef FFTW_DOUBLE_ONLY
272 case 'f': fftwf_import_wisdom_from_file(f); break;
274 #ifdef FFTW_FLOAT_ONLY
277 case 'd': fftw_import_wisdom_from_file(f); break;
286 void packFloat(const float *R__ re, const float *R__ im) {
287 const int hs = m_size/2;
288 fftwf_complex *const R__ fpacked = m_fpacked;
289 for (int i = 0; i <= hs; ++i) {
290 fpacked[i][0] = re[i];
293 for (int i = 0; i <= hs; ++i) {
294 fpacked[i][1] = im[i];
297 for (int i = 0; i <= hs; ++i) {
303 void packDouble(const double *R__ re, const double *R__ im) {
304 const int hs = m_size/2;
305 fftw_complex *const R__ dpacked = m_dpacked;
306 for (int i = 0; i <= hs; ++i) {
307 dpacked[i][0] = re[i];
310 for (int i = 0; i <= hs; ++i) {
311 dpacked[i][1] = im[i];
314 for (int i = 0; i <= hs; ++i) {
320 void unpackFloat(float *R__ re, float *R__ im) {
321 const int hs = m_size/2;
322 for (int i = 0; i <= hs; ++i) {
323 re[i] = m_fpacked[i][0];
326 for (int i = 0; i <= hs; ++i) {
327 im[i] = m_fpacked[i][1];
332 void unpackDouble(double *R__ re, double *R__ im) {
333 const int hs = m_size/2;
334 for (int i = 0; i <= hs; ++i) {
335 re[i] = m_dpacked[i][0];
338 for (int i = 0; i <= hs; ++i) {
339 im[i] = m_dpacked[i][1];
344 void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut) {
345 if (!m_dplanf) initDouble();
346 const int sz = m_size;
347 fft_double_type *const R__ dbuf = m_dbuf;
348 #ifndef FFTW_FLOAT_ONLY
351 for (int i = 0; i < sz; ++i) {
354 fftw_execute(m_dplanf);
355 unpackDouble(realOut, imagOut);
358 void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) {
359 if (!m_dplanf) initDouble();
360 fft_double_type *const R__ dbuf = m_dbuf;
361 const int sz = m_size;
362 #ifndef FFTW_FLOAT_ONLY
365 for (int i = 0; i < sz; ++i) {
368 fftw_execute(m_dplanf);
369 const int hs = m_size/2;
370 for (int i = 0; i <= hs; ++i) {
371 magOut[i] = sqrt(m_dpacked[i][0] * m_dpacked[i][0] +
372 m_dpacked[i][1] * m_dpacked[i][1]);
374 for (int i = 0; i <= hs; ++i) {
375 phaseOut[i] = atan2(m_dpacked[i][1], m_dpacked[i][0]);
379 void forwardMagnitude(const double *R__ realIn, double *R__ magOut) {
380 if (!m_dplanf) initDouble();
381 fft_double_type *const R__ dbuf = m_dbuf;
382 const int sz = m_size;
383 #ifndef FFTW_FLOAT_ONLY
384 if (realIn != m_dbuf)
386 for (int i = 0; i < sz; ++i) {
389 fftw_execute(m_dplanf);
390 const int hs = m_size/2;
391 for (int i = 0; i <= hs; ++i) {
392 magOut[i] = sqrt(m_dpacked[i][0] * m_dpacked[i][0] +
393 m_dpacked[i][1] * m_dpacked[i][1]);
397 void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut) {
398 if (!m_fplanf) initFloat();
399 fft_float_type *const R__ fbuf = m_fbuf;
400 const int sz = m_size;
401 #ifndef FFTW_DOUBLE_ONLY
404 for (int i = 0; i < sz; ++i) {
407 fftwf_execute(m_fplanf);
408 unpackFloat(realOut, imagOut);
411 void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) {
412 if (!m_fplanf) initFloat();
413 fft_float_type *const R__ fbuf = m_fbuf;
414 const int sz = m_size;
415 #ifndef FFTW_DOUBLE_ONLY
418 for (int i = 0; i < sz; ++i) {
421 fftwf_execute(m_fplanf);
422 const int hs = m_size/2;
423 for (int i = 0; i <= hs; ++i) {
424 magOut[i] = sqrtf(m_fpacked[i][0] * m_fpacked[i][0] +
425 m_fpacked[i][1] * m_fpacked[i][1]);
427 for (int i = 0; i <= hs; ++i) {
428 phaseOut[i] = atan2f(m_fpacked[i][1], m_fpacked[i][0]) ;
432 void forwardMagnitude(const float *R__ realIn, float *R__ magOut) {
433 if (!m_fplanf) initFloat();
434 fft_float_type *const R__ fbuf = m_fbuf;
435 const int sz = m_size;
436 #ifndef FFTW_DOUBLE_ONLY
439 for (int i = 0; i < sz; ++i) {
442 fftwf_execute(m_fplanf);
443 const int hs = m_size/2;
444 for (int i = 0; i <= hs; ++i) {
445 magOut[i] = sqrtf(m_fpacked[i][0] * m_fpacked[i][0] +
446 m_fpacked[i][1] * m_fpacked[i][1]);
450 void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut) {
451 if (!m_dplanf) initDouble();
452 packDouble(realIn, imagIn);
453 fftw_execute(m_dplani);
454 const int sz = m_size;
455 fft_double_type *const R__ dbuf = m_dbuf;
456 #ifndef FFTW_FLOAT_ONLY
459 for (int i = 0; i < sz; ++i) {
460 realOut[i] = dbuf[i];
464 void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) {
465 if (!m_dplanf) initDouble();
466 const int hs = m_size/2;
467 fftw_complex *const R__ dpacked = m_dpacked;
468 for (int i = 0; i <= hs; ++i) {
469 dpacked[i][0] = magIn[i] * cos(phaseIn[i]);
471 for (int i = 0; i <= hs; ++i) {
472 dpacked[i][1] = magIn[i] * sin(phaseIn[i]);
474 fftw_execute(m_dplani);
475 const int sz = m_size;
476 fft_double_type *const R__ dbuf = m_dbuf;
477 #ifndef FFTW_FLOAT_ONLY
480 for (int i = 0; i < sz; ++i) {
481 realOut[i] = dbuf[i];
485 void inverseCepstral(const double *R__ magIn, double *R__ cepOut) {
486 if (!m_dplanf) initDouble();
487 fft_double_type *const R__ dbuf = m_dbuf;
488 fftw_complex *const R__ dpacked = m_dpacked;
489 const int hs = m_size/2;
490 for (int i = 0; i <= hs; ++i) {
491 dpacked[i][0] = log(magIn[i] + 0.000001);
493 for (int i = 0; i <= hs; ++i) {
496 fftw_execute(m_dplani);
497 const int sz = m_size;
498 #ifndef FFTW_FLOAT_ONLY
501 for (int i = 0; i < sz; ++i) {
506 void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut) {
507 if (!m_fplanf) initFloat();
508 packFloat(realIn, imagIn);
509 fftwf_execute(m_fplani);
510 const int sz = m_size;
511 fft_float_type *const R__ fbuf = m_fbuf;
512 #ifndef FFTW_DOUBLE_ONLY
515 for (int i = 0; i < sz; ++i) {
516 realOut[i] = fbuf[i];
520 void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) {
521 if (!m_fplanf) initFloat();
522 const int hs = m_size/2;
523 fftwf_complex *const R__ fpacked = m_fpacked;
524 for (int i = 0; i <= hs; ++i) {
525 fpacked[i][0] = magIn[i] * cosf(phaseIn[i]);
527 for (int i = 0; i <= hs; ++i) {
528 fpacked[i][1] = magIn[i] * sinf(phaseIn[i]);
530 fftwf_execute(m_fplani);
531 const int sz = m_size;
532 fft_float_type *const R__ fbuf = m_fbuf;
533 #ifndef FFTW_DOUBLE_ONLY
536 for (int i = 0; i < sz; ++i) {
537 realOut[i] = fbuf[i];
541 void inverseCepstral(const float *R__ magIn, float *R__ cepOut) {
542 if (!m_fplanf) initFloat();
543 const int hs = m_size/2;
544 fftwf_complex *const R__ fpacked = m_fpacked;
545 for (int i = 0; i <= hs; ++i) {
546 fpacked[i][0] = logf(magIn[i] + 0.000001f);
548 for (int i = 0; i <= hs; ++i) {
551 fftwf_execute(m_fplani);
552 const int sz = m_size;
553 fft_float_type *const R__ fbuf = m_fbuf;
554 #ifndef FFTW_DOUBLE_ONLY
557 for (int i = 0; i < sz; ++i) {
562 float *getFloatTimeBuffer() {
564 #ifdef FFTW_DOUBLE_ONLY
565 if (!m_frb) m_frb = (float *)fftw_malloc(m_size * sizeof(float));
572 double *getDoubleTimeBuffer() {
574 #ifdef FFTW_FLOAT_ONLY
575 if (!m_drb) m_drb = (double *)fftwf_malloc(m_size * sizeof(double));
585 #ifdef FFTW_DOUBLE_ONLY
591 fftwf_complex *m_fpacked;
594 #ifdef FFTW_FLOAT_ONLY
600 fftw_complex * m_dpacked;
602 static int m_extantf;
603 static int m_extantd;
604 static Mutex m_extantMutex;
608 D_FFTW::m_extantf = 0;
611 D_FFTW::m_extantd = 0;
614 D_FFTW::m_extantMutex;
616 #endif /* HAVE_FFTW3 */
620 class D_KISSFFT : public FFTImpl
623 D_KISSFFT(int size) :
631 #error KISSFFT is not configured for float values
633 if (sizeof(kiss_fft_scalar) != sizeof(float)) {
634 std::cerr << "ERROR: KISSFFT is not configured for float values"
638 m_fbuf = new kiss_fft_scalar[m_size + 2];
639 m_fpacked = new kiss_fft_cpx[m_size + 2];
640 m_fplanf = kiss_fftr_alloc(m_size, 0, NULL, NULL);
641 m_fplani = kiss_fftr_alloc(m_size, 1, NULL, NULL);
645 kiss_fftr_free(m_fplanf);
646 kiss_fftr_free(m_fplani);
652 if (m_frb) delete[] m_frb;
653 if (m_drb) delete[] m_drb;
657 void initDouble() { }
659 void packFloat(const float *R__ re, const float *R__ im) {
660 const int hs = m_size/2;
661 for (int i = 0; i <= hs; ++i) {
662 m_fpacked[i].r = re[i];
663 m_fpacked[i].i = im[i];
667 void unpackFloat(float *R__ re, float *R__ im) {
668 const int hs = m_size/2;
669 for (int i = 0; i <= hs; ++i) {
670 re[i] = m_fpacked[i].r;
671 im[i] = m_fpacked[i].i;
675 void packDouble(const double *R__ re, const double *R__ im) {
676 const int hs = m_size/2;
677 for (int i = 0; i <= hs; ++i) {
678 m_fpacked[i].r = float(re[i]);
679 m_fpacked[i].i = float(im[i]);
683 void unpackDouble(double *R__ re, double *R__ im) {
684 const int hs = m_size/2;
685 for (int i = 0; i <= hs; ++i) {
686 re[i] = double(m_fpacked[i].r);
687 im[i] = double(m_fpacked[i].i);
691 void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut) {
693 for (int i = 0; i < m_size; ++i) {
694 m_fbuf[i] = float(realIn[i]);
697 kiss_fftr(m_fplanf, m_fbuf, m_fpacked);
698 unpackDouble(realOut, imagOut);
701 void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) {
703 for (int i = 0; i < m_size; ++i) {
704 m_fbuf[i] = float(realIn[i]);
707 kiss_fftr(m_fplanf, m_fbuf, m_fpacked);
709 const int hs = m_size/2;
711 for (int i = 0; i <= hs; ++i) {
712 magOut[i] = sqrt(double(m_fpacked[i].r) * double(m_fpacked[i].r) +
713 double(m_fpacked[i].i) * double(m_fpacked[i].i));
716 for (int i = 0; i <= hs; ++i) {
717 phaseOut[i] = atan2(double(m_fpacked[i].i), double(m_fpacked[i].r));
721 void forwardMagnitude(const double *R__ realIn, double *R__ magOut) {
723 for (int i = 0; i < m_size; ++i) {
724 m_fbuf[i] = float(realIn[i]);
727 kiss_fftr(m_fplanf, m_fbuf, m_fpacked);
729 const int hs = m_size/2;
731 for (int i = 0; i <= hs; ++i) {
732 magOut[i] = sqrt(double(m_fpacked[i].r) * double(m_fpacked[i].r) +
733 double(m_fpacked[i].i) * double(m_fpacked[i].i));
737 void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut) {
739 kiss_fftr(m_fplanf, realIn, m_fpacked);
740 unpackFloat(realOut, imagOut);
743 void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) {
745 kiss_fftr(m_fplanf, realIn, m_fpacked);
747 const int hs = m_size/2;
749 for (int i = 0; i <= hs; ++i) {
750 magOut[i] = sqrtf(m_fpacked[i].r * m_fpacked[i].r +
751 m_fpacked[i].i * m_fpacked[i].i);
754 for (int i = 0; i <= hs; ++i) {
755 phaseOut[i] = atan2f(m_fpacked[i].i, m_fpacked[i].r);
759 void forwardMagnitude(const float *R__ realIn, float *R__ magOut) {
761 kiss_fftr(m_fplanf, realIn, m_fpacked);
763 const int hs = m_size/2;
765 for (int i = 0; i <= hs; ++i) {
766 magOut[i] = sqrtf(m_fpacked[i].r * m_fpacked[i].r +
767 m_fpacked[i].i * m_fpacked[i].i);
771 void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut) {
773 packDouble(realIn, imagIn);
775 kiss_fftri(m_fplani, m_fpacked, m_fbuf);
777 for (int i = 0; i < m_size; ++i) {
778 realOut[i] = m_fbuf[i];
782 void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) {
784 const int hs = m_size/2;
786 for (int i = 0; i <= hs; ++i) {
787 m_fpacked[i].r = float(magIn[i] * cos(phaseIn[i]));
788 m_fpacked[i].i = float(magIn[i] * sin(phaseIn[i]));
791 kiss_fftri(m_fplani, m_fpacked, m_fbuf);
793 for (int i = 0; i < m_size; ++i) {
794 realOut[i] = m_fbuf[i];
798 void inverseCepstral(const double *R__ magIn, double *R__ cepOut) {
800 const int hs = m_size/2;
802 for (int i = 0; i <= hs; ++i) {
803 m_fpacked[i].r = float(log(magIn[i] + 0.000001));
804 m_fpacked[i].i = 0.0f;
807 kiss_fftri(m_fplani, m_fpacked, m_fbuf);
809 for (int i = 0; i < m_size; ++i) {
810 cepOut[i] = m_fbuf[i];
814 void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut) {
816 packFloat(realIn, imagIn);
817 kiss_fftri(m_fplani, m_fpacked, realOut);
820 void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) {
822 const int hs = m_size/2;
824 for (int i = 0; i <= hs; ++i) {
825 m_fpacked[i].r = magIn[i] * cosf(phaseIn[i]);
826 m_fpacked[i].i = magIn[i] * sinf(phaseIn[i]);
829 kiss_fftri(m_fplani, m_fpacked, realOut);
832 void inverseCepstral(const float *R__ magIn, float *R__ cepOut) {
834 const int hs = m_size/2;
836 for (int i = 0; i <= hs; ++i) {
837 m_fpacked[i].r = logf(magIn[i] + 0.000001f);
838 m_fpacked[i].i = 0.0f;
841 kiss_fftri(m_fplani, m_fpacked, cepOut);
844 float *getFloatTimeBuffer() {
845 if (!m_frb) m_frb = new float[m_size];
849 double *getDoubleTimeBuffer() {
850 if (!m_drb) m_drb = new double[m_size];
858 kiss_fftr_cfg m_fplanf;
859 kiss_fftr_cfg m_fplani;
860 kiss_fft_scalar *m_fbuf;
861 kiss_fft_cpx *m_fpacked;
864 #endif /* USE_KISSFFT */
866 #ifdef USE_BUILTIN_FFT
868 class D_Cross : public FFTImpl
871 D_Cross(int size) : m_size(size), m_table(0), m_frb(0), m_drb(0) {
873 m_a = new double[size];
874 m_b = new double[size];
875 m_c = new double[size];
876 m_d = new double[size];
878 m_table = new int[m_size];
884 if (m_size & (1 << i)) {
890 for (i = 0; i < m_size; ++i) {
894 for (j = k = 0; j < bits; ++j) {
895 k = (k << 1) | (m & 1);
914 void initDouble() { }
916 void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut) {
917 basefft(false, realIn, 0, m_c, m_d);
918 const int hs = m_size/2;
919 for (int i = 0; i <= hs; ++i) realOut[i] = m_c[i];
921 for (int i = 0; i <= hs; ++i) imagOut[i] = m_d[i];
925 void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) {
926 basefft(false, realIn, 0, m_c, m_d);
927 const int hs = m_size/2;
928 for (int i = 0; i <= hs; ++i) {
929 magOut[i] = sqrt(m_c[i] * m_c[i] + m_d[i] * m_d[i]);
930 phaseOut[i] = atan2(m_d[i], m_c[i]) ;
934 void forwardMagnitude(const double *R__ realIn, double *R__ magOut) {
935 basefft(false, realIn, 0, m_c, m_d);
936 const int hs = m_size/2;
937 for (int i = 0; i <= hs; ++i) {
938 magOut[i] = sqrt(m_c[i] * m_c[i] + m_d[i] * m_d[i]);
942 void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut) {
943 for (int i = 0; i < m_size; ++i) m_a[i] = realIn[i];
944 basefft(false, m_a, 0, m_c, m_d);
945 const int hs = m_size/2;
946 for (int i = 0; i <= hs; ++i) realOut[i] = m_c[i];
948 for (int i = 0; i <= hs; ++i) imagOut[i] = m_d[i];
952 void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) {
953 for (int i = 0; i < m_size; ++i) m_a[i] = realIn[i];
954 basefft(false, m_a, 0, m_c, m_d);
955 const int hs = m_size/2;
956 for (int i = 0; i <= hs; ++i) {
957 magOut[i] = sqrt(m_c[i] * m_c[i] + m_d[i] * m_d[i]);
958 phaseOut[i] = atan2(m_d[i], m_c[i]) ;
962 void forwardMagnitude(const float *R__ realIn, float *R__ magOut) {
963 for (int i = 0; i < m_size; ++i) m_a[i] = realIn[i];
964 basefft(false, m_a, 0, m_c, m_d);
965 const int hs = m_size/2;
966 for (int i = 0; i <= hs; ++i) {
967 magOut[i] = sqrt(m_c[i] * m_c[i] + m_d[i] * m_d[i]);
971 void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut) {
972 const int hs = m_size/2;
973 for (int i = 0; i <= hs; ++i) {
974 double real = realIn[i];
975 double imag = imagIn[i];
979 m_a[m_size-i] = real;
980 m_b[m_size-i] = -imag;
983 basefft(true, m_a, m_b, realOut, m_d);
986 void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) {
987 const int hs = m_size/2;
988 for (int i = 0; i <= hs; ++i) {
989 double real = magIn[i] * cos(phaseIn[i]);
990 double imag = magIn[i] * sin(phaseIn[i]);
994 m_a[m_size-i] = real;
995 m_b[m_size-i] = -imag;
998 basefft(true, m_a, m_b, realOut, m_d);
1001 void inverseCepstral(const double *R__ magIn, double *R__ cepOut) {
1002 const int hs = m_size/2;
1003 for (int i = 0; i <= hs; ++i) {
1004 double real = log(magIn[i] + 0.000001);
1008 m_a[m_size-i] = real;
1009 m_b[m_size-i] = 0.0;
1012 basefft(true, m_a, m_b, cepOut, m_d);
1015 void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut) {
1016 const int hs = m_size/2;
1017 for (int i = 0; i <= hs; ++i) {
1018 float real = realIn[i];
1019 float imag = imagIn[i];
1023 m_a[m_size-i] = real;
1024 m_b[m_size-i] = -imag;
1027 basefft(true, m_a, m_b, m_c, m_d);
1028 for (int i = 0; i < m_size; ++i) realOut[i] = m_c[i];
1031 void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) {
1032 const int hs = m_size/2;
1033 for (int i = 0; i <= hs; ++i) {
1034 float real = magIn[i] * cosf(phaseIn[i]);
1035 float imag = magIn[i] * sinf(phaseIn[i]);
1039 m_a[m_size-i] = real;
1040 m_b[m_size-i] = -imag;
1043 basefft(true, m_a, m_b, m_c, m_d);
1044 for (int i = 0; i < m_size; ++i) realOut[i] = m_c[i];
1047 void inverseCepstral(const float *R__ magIn, float *R__ cepOut) {
1048 const int hs = m_size/2;
1049 for (int i = 0; i <= hs; ++i) {
1050 float real = logf(magIn[i] + 0.000001);
1054 m_a[m_size-i] = real;
1055 m_b[m_size-i] = 0.0;
1058 basefft(true, m_a, m_b, m_c, m_d);
1059 for (int i = 0; i < m_size; ++i) cepOut[i] = m_c[i];
1062 float *getFloatTimeBuffer() {
1063 if (!m_frb) m_frb = new float[m_size];
1067 double *getDoubleTimeBuffer() {
1068 if (!m_drb) m_drb = new double[m_size];
1081 void basefft(bool inverse, const double *R__ ri, const double *R__ ii, double *R__ ro, double *R__ io);
1085 D_Cross::basefft(bool inverse, const double *R__ ri, const double *R__ ii, double *R__ ro, double *R__ io)
1087 if (!ri || !ro || !io) return;
1090 int blockSize, blockEnd;
1094 double angle = 2.0 * M_PI;
1095 if (inverse) angle = -angle;
1097 const int n = m_size;
1100 for (i = 0; i < n; ++i) {
1101 ro[m_table[i]] = ri[i];
1103 for (i = 0; i < n; ++i) {
1104 io[m_table[i]] = ii[i];
1107 for (i = 0; i < n; ++i) {
1108 ro[m_table[i]] = ri[i];
1110 for (i = 0; i < n; ++i) {
1111 io[m_table[i]] = 0.0;
1117 for (blockSize = 2; blockSize <= n; blockSize <<= 1) {
1119 double delta = angle / (double)blockSize;
1120 double sm2 = -sin(-2 * delta);
1121 double sm1 = -sin(-delta);
1122 double cm2 = cos(-2 * delta);
1123 double cm1 = cos(-delta);
1125 double ar[3], ai[3];
1127 for (i = 0; i < n; i += blockSize) {
1135 for (j = i, m = 0; m < blockEnd; j++, m++) {
1137 ar[0] = w * ar[1] - ar[2];
1141 ai[0] = w * ai[1] - ai[2];
1146 tr = ar[0] * ro[k] - ai[0] * io[k];
1147 ti = ar[0] * io[k] + ai[0] * ro[k];
1157 blockEnd = blockSize;
1160 /* fftw doesn't rescale, so nor will we
1164 double denom = (double)n;
1166 for (i = 0; i < n; i++) {
1174 #endif /* USE_BUILTIN_FFT */
1176 } /* end namespace FFTs */
1181 FFT::FFT(int size, int debugLevel)
1184 (size & (size-1))) {
1185 std::cerr << "FFT::FFT(" << size << "): power-of-two sizes only supported, minimum size 2" << std::endl;
1189 if (m_method == -1) {
1202 std::cerr << "FFT::FFT(" << size << "): WARNING: Selected implemention not available" << std::endl;
1203 #ifdef USE_BUILTIN_FFT
1204 d = new FFTs::D_Cross(size);
1206 std::cerr << "FFT::FFT(" << size << "): ERROR: Fallback implementation not available!" << std::endl;
1213 if (debugLevel > 0) {
1214 std::cerr << "FFT::FFT(" << size << "): using FFTW3 implementation"
1217 d = new FFTs::D_FFTW(size);
1219 std::cerr << "FFT::FFT(" << size << "): WARNING: Selected implemention not available" << std::endl;
1220 #ifdef USE_BUILTIN_FFT
1221 d = new FFTs::D_Cross(size);
1223 std::cerr << "FFT::FFT(" << size << "): ERROR: Fallback implementation not available!" << std::endl;
1231 if (debugLevel > 0) {
1232 std::cerr << "FFT::FFT(" << size << "): using KISSFFT implementation"
1235 d = new FFTs::D_KISSFFT(size);
1237 std::cerr << "FFT::FFT(" << size << "): WARNING: Selected implemention not available" << std::endl;
1238 #ifdef USE_BUILTIN_FFT
1239 d = new FFTs::D_Cross(size);
1241 std::cerr << "FFT::FFT(" << size << "): ERROR: Fallback implementation not available!" << std::endl;
1248 #ifdef USE_BUILTIN_FFT
1249 std::cerr << "FFT::FFT(" << size << "): WARNING: using slow built-in implementation" << std::endl;
1250 d = new FFTs::D_Cross(size);
1252 std::cerr << "FFT::FFT(" << size << "): ERROR: Fallback implementation not available!" << std::endl;
1265 FFT::forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut)
1267 d->forward(realIn, realOut, imagOut);
1271 FFT::forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut)
1273 d->forwardPolar(realIn, magOut, phaseOut);
1277 FFT::forwardMagnitude(const double *R__ realIn, double *R__ magOut)
1279 d->forwardMagnitude(realIn, magOut);
1283 FFT::forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut)
1285 d->forward(realIn, realOut, imagOut);
1289 FFT::forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut)
1291 d->forwardPolar(realIn, magOut, phaseOut);
1295 FFT::forwardMagnitude(const float *R__ realIn, float *R__ magOut)
1297 d->forwardMagnitude(realIn, magOut);
1301 FFT::inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut)
1303 d->inverse(realIn, imagIn, realOut);
1307 FFT::inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut)
1309 d->inversePolar(magIn, phaseIn, realOut);
1313 FFT::inverseCepstral(const double *R__ magIn, double *R__ cepOut)
1315 d->inverseCepstral(magIn, cepOut);
1319 FFT::inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut)
1321 d->inverse(realIn, imagIn, realOut);
1325 FFT::inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut)
1327 d->inversePolar(magIn, phaseIn, realOut);
1331 FFT::inverseCepstral(const float *R__ magIn, float *R__ cepOut)
1333 d->inverseCepstral(magIn, cepOut);
1349 FFT::getFloatTimeBuffer()
1351 return d->getFloatTimeBuffer();
1355 FFT::getDoubleTimeBuffer()
1357 return d->getDoubleTimeBuffer();