28#if defined(AUDIOFFT_APPLE_ACCELERATE)
29#define AUDIOFFT_APPLE_ACCELERATE_USED
30#include <Accelerate/Accelerate.h>
32#elif defined(AUDIOFFT_FFTW3)
33#define AUDIOFFT_FFTW3_USED
36#if !defined(AUDIOFFT_OOURA)
39#define AUDIOFFT_OOURA_USED
56 virtual void init(
size_t size) = 0;
57 virtual void fft(
const float* data,
float* re,
float* im) = 0;
58 virtual void ifft(
float* data,
const float* re,
const float* im) = 0;
61 constexpr bool IsPowerOf2(
size_t val) {
return (val == 1 || (val & (val - 1)) == 0); }
63 template <
typename TypeDest,
typename TypeSrc>
66 for (
size_t i = 0; i < len; ++i)
68 dest[i] =
static_cast<TypeDest
>(src[i]);
72 template <
typename TypeDest,
typename TypeSrc,
typename TypeFactor>
73 void ScaleBuffer(TypeDest* dest,
const TypeSrc* src,
const TypeFactor factor,
size_t len)
75 for (
size_t i = 0; i < len; ++i)
77 dest[i] =
static_cast<TypeDest
>(
static_cast<TypeFactor
>(src[i]) * factor);
85#ifdef AUDIOFFT_OOURA_USED
100 virtual void init(
size_t size)
override
104 _ip.resize(2 +
static_cast<size_t>(std::sqrt(
static_cast<double>(size))));
109 const int size4 =
static_cast<int>(
_size) / 4;
115 virtual void fft(
const float* data,
float* re,
float* im)
override
125 double* bEnd = b +
_size;
130 *(r++) =
static_cast<float>(*(b++));
131 *(i++) =
static_cast<float>(-(*(b++)));
134 const size_t size2 =
_size / 2;
140 virtual void ifft(
float* data,
const float* re,
const float* im)
override
145 double* bEnd = b +
_size;
150 *(b++) =
static_cast<double>(*(r++));
151 *(b++) = -
static_cast<double>(*(i++));
165 std::vector<double>
_w;
168 void rdft(
int n,
int isgn,
double* a,
int* ip,
double* w)
185 double xi = a[0] - a[1];
191 a[1] = 0.5 * (a[0] - a[1]);
218 delta = atan(1.0) / nwh;
221 w[nwh] = cos(delta * nwh);
225 for (j = 2; j < nwh; j += 2)
248 delta = atan(1.0) / nch;
249 c[0] = cos(delta * nch);
251 for (j = 1; j < nch; j++)
253 c[j] = 0.5 * cos(delta * j);
254 c[nc - j] = 0.5 * sin(delta * j);
263 int j, j1, k, k1, l, m, m2;
264 double xr, xi, yr, yi;
272 for (j = 0; j < m; j++)
274 ip[m + j] = ip[j] + l;
281 for (k = 0; k < m; k++)
283 for (j = 0; j < k; j++)
326 j1 = 2 * k + m2 + ip[k];
340 for (k = 1; k < m; k++)
342 for (j = 0; j < k; j++)
371 int j, j1, j2, j3, l;
372 double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
387 for (j = 0; j < l; j += 2)
393 x0i = a[j + 1] + a[j1 + 1];
395 x1i = a[j + 1] - a[j1 + 1];
397 x2i = a[j2 + 1] + a[j3 + 1];
399 x3i = a[j2 + 1] - a[j3 + 1];
401 a[j + 1] = x0i + x2i;
403 a[j2 + 1] = x0i - x2i;
405 a[j1 + 1] = x1i + x3r;
407 a[j3 + 1] = x1i - x3r;
412 for (j = 0; j < l; j += 2)
416 x0i = a[j + 1] - a[j1 + 1];
418 a[j + 1] += a[j1 + 1];
427 int j, j1, j2, j3, l;
428 double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
443 for (j = 0; j < l; j += 2)
449 x0i = -a[j + 1] - a[j1 + 1];
451 x1i = -a[j + 1] + a[j1 + 1];
453 x2i = a[j2 + 1] + a[j3 + 1];
455 x3i = a[j2 + 1] - a[j3 + 1];
457 a[j + 1] = x0i - x2i;
459 a[j2 + 1] = x0i + x2i;
461 a[j1 + 1] = x1i - x3r;
463 a[j3 + 1] = x1i + x3r;
468 for (j = 0; j < l; j += 2)
472 x0i = -a[j + 1] + a[j1 + 1];
474 a[j + 1] = -a[j + 1] - a[j1 + 1];
484 double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
485 double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
518 a[10] = wk1r * (x0r - x0i);
519 a[11] = wk1r * (x0r + x0i);
522 a[14] = wk1r * (x0i - x0r);
523 a[15] = wk1r * (x0i + x0r);
525 for (j = 16; j < n; j += 16)
533 wk3r = wk1r - 2 * wk2i * wk1i;
534 wk3i = 2 * wk2i * wk1r - wk1i;
535 x0r = a[j] + a[j + 2];
536 x0i = a[j + 1] + a[j + 3];
537 x1r = a[j] - a[j + 2];
538 x1i = a[j + 1] - a[j + 3];
539 x2r = a[j + 4] + a[j + 6];
540 x2i = a[j + 5] + a[j + 7];
541 x3r = a[j + 4] - a[j + 6];
542 x3i = a[j + 5] - a[j + 7];
544 a[j + 1] = x0i + x2i;
547 a[j + 4] = wk2r * x0r - wk2i * x0i;
548 a[j + 5] = wk2r * x0i + wk2i * x0r;
551 a[j + 2] = wk1r * x0r - wk1i * x0i;
552 a[j + 3] = wk1r * x0i + wk1i * x0r;
555 a[j + 6] = wk3r * x0r - wk3i * x0i;
556 a[j + 7] = wk3r * x0i + wk3i * x0r;
559 wk3r = wk1r - 2 * wk2r * wk1i;
560 wk3i = 2 * wk2r * wk1r - wk1i;
561 x0r = a[j + 8] + a[j + 10];
562 x0i = a[j + 9] + a[j + 11];
563 x1r = a[j + 8] - a[j + 10];
564 x1i = a[j + 9] - a[j + 11];
565 x2r = a[j + 12] + a[j + 14];
566 x2i = a[j + 13] + a[j + 15];
567 x3r = a[j + 12] - a[j + 14];
568 x3i = a[j + 13] - a[j + 15];
569 a[j + 8] = x0r + x2r;
570 a[j + 9] = x0i + x2i;
573 a[j + 12] = -wk2i * x0r - wk2r * x0i;
574 a[j + 13] = -wk2i * x0i + wk2r * x0r;
577 a[j + 10] = wk1r * x0r - wk1i * x0i;
578 a[j + 11] = wk1r * x0i + wk1i * x0r;
581 a[j + 14] = wk3r * x0r - wk3i * x0i;
582 a[j + 15] = wk3r * x0i + wk3i * x0r;
586 void cftmdl(
int n,
int l,
double* a,
double* w)
588 int j, j1, j2, j3, k, k1, k2, m, m2;
589 double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
590 double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
593 for (j = 0; j < l; j += 2)
599 x0i = a[j + 1] + a[j1 + 1];
601 x1i = a[j + 1] - a[j1 + 1];
603 x2i = a[j2 + 1] + a[j3 + 1];
605 x3i = a[j2 + 1] - a[j3 + 1];
607 a[j + 1] = x0i + x2i;
609 a[j2 + 1] = x0i - x2i;
611 a[j1 + 1] = x1i + x3r;
613 a[j3 + 1] = x1i - x3r;
616 for (j = m; j < l + m; j += 2)
622 x0i = a[j + 1] + a[j1 + 1];
624 x1i = a[j + 1] - a[j1 + 1];
626 x2i = a[j2 + 1] + a[j3 + 1];
628 x3i = a[j2 + 1] - a[j3 + 1];
630 a[j + 1] = x0i + x2i;
632 a[j2 + 1] = x0r - x2r;
635 a[j1] = wk1r * (x0r - x0i);
636 a[j1 + 1] = wk1r * (x0r + x0i);
639 a[j3] = wk1r * (x0i - x0r);
640 a[j3 + 1] = wk1r * (x0i + x0r);
644 for (k = m2; k < n; k += m2)
652 wk3r = wk1r - 2 * wk2i * wk1i;
653 wk3i = 2 * wk2i * wk1r - wk1i;
654 for (j = k; j < l + k; j += 2)
660 x0i = a[j + 1] + a[j1 + 1];
662 x1i = a[j + 1] - a[j1 + 1];
664 x2i = a[j2 + 1] + a[j3 + 1];
666 x3i = a[j2 + 1] - a[j3 + 1];
668 a[j + 1] = x0i + x2i;
671 a[j2] = wk2r * x0r - wk2i * x0i;
672 a[j2 + 1] = wk2r * x0i + wk2i * x0r;
675 a[j1] = wk1r * x0r - wk1i * x0i;
676 a[j1 + 1] = wk1r * x0i + wk1i * x0r;
679 a[j3] = wk3r * x0r - wk3i * x0i;
680 a[j3 + 1] = wk3r * x0i + wk3i * x0r;
684 wk3r = wk1r - 2 * wk2r * wk1i;
685 wk3i = 2 * wk2r * wk1r - wk1i;
686 for (j = k + m; j < l + (k + m); j += 2)
692 x0i = a[j + 1] + a[j1 + 1];
694 x1i = a[j + 1] - a[j1 + 1];
696 x2i = a[j2 + 1] + a[j3 + 1];
698 x3i = a[j2 + 1] - a[j3 + 1];
700 a[j + 1] = x0i + x2i;
703 a[j2] = -wk2i * x0r - wk2r * x0i;
704 a[j2 + 1] = -wk2i * x0i + wk2r * x0r;
707 a[j1] = wk1r * x0r - wk1i * x0i;
708 a[j1 + 1] = wk1r * x0i + wk1i * x0r;
711 a[j3] = wk3r * x0r - wk3i * x0i;
712 a[j3 + 1] = wk3r * x0i + wk3i * x0r;
717 void rftfsub(
int n,
double* a,
int nc,
double* c)
720 double wkr, wki, xr, xi, yr, yi;
725 for (j = 2; j < m; j += 2)
729 wkr = 0.5 - c[nc - kk];
732 xi = a[j + 1] + a[k + 1];
733 yr = wkr * xr - wki * xi;
734 yi = wkr * xi + wki * xr;
742 void rftbsub(
int n,
double* a,
int nc,
double* c)
745 double wkr, wki, xr, xi, yr, yi;
751 for (j = 2; j < m; j += 2)
755 wkr = 0.5 - c[nc - kk];
758 xi = a[j + 1] + a[k + 1];
759 yr = wkr * xr + wki * xi;
760 yi = wkr * xi - wki * xr;
762 a[j + 1] = yi - a[j + 1];
764 a[k + 1] = yi - a[k + 1];
766 a[m + 1] = -a[m + 1];
780#ifdef AUDIOFFT_APPLE_ACCELERATE_USED
790 AppleAccelerateFFT() :
detail::AudioFFTImpl(), _size(0), _powerOf2(0), _fftSetup(0), _re(), _im() {}
792 AppleAccelerateFFT(
const AppleAccelerateFFT&) =
delete;
793 AppleAccelerateFFT& operator=(
const AppleAccelerateFFT&) =
delete;
795 virtual ~AppleAccelerateFFT() { init(0); }
797 virtual void init(
size_t size)
override
801 vDSP_destroy_fftsetup(_fftSetup);
813 while ((1 << _powerOf2) < _size)
817 _fftSetup = vDSP_create_fftsetup(_powerOf2, FFT_RADIX2);
818 _re.resize(_size / 2);
819 _im.resize(_size / 2);
823 virtual void fft(
const float* data,
float* re,
float* im)
override
825 const size_t size2 = _size / 2;
826 DSPSplitComplex splitComplex;
827 splitComplex.realp = re;
828 splitComplex.imagp = im;
829 vDSP_ctoz(
reinterpret_cast<const COMPLEX*
>(data), 2, &splitComplex, 1, size2);
830 vDSP_fft_zrip(_fftSetup, &splitComplex, 1, _powerOf2, FFT_FORWARD);
831 const float factor = 0.5f;
832 vDSP_vsmul(re, 1, &factor, re, 1, size2);
833 vDSP_vsmul(im, 1, &factor, im, 1, size2);
839 virtual void ifft(
float* data,
const float* re,
const float* im)
override
841 const size_t size2 = _size / 2;
842 ::memcpy(_re.data(), re, size2 *
sizeof(
float));
843 ::memcpy(_im.data(), im, size2 *
sizeof(
float));
845 DSPSplitComplex splitComplex;
846 splitComplex.realp = _re.data();
847 splitComplex.imagp = _im.data();
848 vDSP_fft_zrip(_fftSetup, &splitComplex, 1, _powerOf2, FFT_INVERSE);
849 vDSP_ztoc(&splitComplex, 1,
reinterpret_cast<COMPLEX*
>(data), 2, size2);
850 const float factor = 1.0f /
static_cast<float>(_size);
851 vDSP_vsmul(data, 1, &factor, data, 1, _size);
858 std::vector<float> _re;
859 std::vector<float> _im;
872#ifdef AUDIOFFT_FFTW3_USED
879 class FFTW3FFT :
public detail::AudioFFTImpl
883 : detail::AudioFFTImpl(), _size(0), _complexSize(0), _planForward(0), _planBackward(0), _data(0), _re(0),
888 FFTW3FFT(
const FFTW3FFT&) =
delete;
889 FFTW3FFT& operator=(
const FFTW3FFT&) =
delete;
891 virtual ~FFTW3FFT() { init(0); }
893 virtual void init(
size_t size)
override
899 fftwf_destroy_plan(_planForward);
900 fftwf_destroy_plan(_planBackward);
928 _complexSize = AudioFFT::ComplexSize(_size);
929 const size_t complexSize = AudioFFT::ComplexSize(_size);
930 _data =
reinterpret_cast<float*
>(fftwf_malloc(_size *
sizeof(
float)));
931 _re =
reinterpret_cast<float*
>(fftwf_malloc(complexSize *
sizeof(
float)));
932 _im =
reinterpret_cast<float*
>(fftwf_malloc(complexSize *
sizeof(
float)));
935 dim.n =
static_cast<int>(size);
938 _planForward = fftwf_plan_guru_split_dft_r2c(1, &dim, 0, 0, _data, _re, _im, FFTW_MEASURE);
939 _planBackward = fftwf_plan_guru_split_dft_c2r(1, &dim, 0, 0, _re, _im, _data, FFTW_MEASURE);
944 virtual void fft(
const float* data,
float* re,
float* im)
override
946 ::memcpy(_data, data, _size *
sizeof(
float));
947 fftwf_execute_split_dft_r2c(_planForward, _data, _re, _im);
948 ::memcpy(re, _re, _complexSize *
sizeof(
float));
949 ::memcpy(im, _im, _complexSize *
sizeof(
float));
952 virtual void ifft(
float* data,
const float* re,
const float* im)
override
954 ::memcpy(_re, re, _complexSize *
sizeof(
float));
955 ::memcpy(_im, im, _complexSize *
sizeof(
float));
956 fftwf_execute_split_dft_c2r(_planBackward, _re, _im, _data);
957 detail::ScaleBuffer(data, _data, 1.0f /
static_cast<float>(_size), _size);
963 fftwf_plan _planForward;
964 fftwf_plan _planBackward;
std::unique_ptr< detail::AudioFFTImpl > _impl
Definition AudioFFT.h:151
void init(size_t size)
Initializes the FFT object.
Definition AudioFFT.cpp:984
void fft(const float *data, float *re, float *im)
Performs the forward FFT.
Definition AudioFFT.cpp:990
void ifft(float *data, const float *re, const float *im)
Performs the inverse FFT.
Definition AudioFFT.cpp:992
~AudioFFT()
Destructor.
Definition AudioFFT.cpp:982
AudioFFT()
Constructor.
Definition AudioFFT.cpp:980
static size_t ComplexSize(size_t size)
Calculates the necessary size of the real/imaginary complex arrays.
Definition AudioFFT.cpp:994
Definition AudioFFT.cpp:93
void makewt(int nw, int *ip, double *w)
Definition AudioFFT.cpp:208
virtual void fft(const float *data, float *re, float *im) override
Definition AudioFFT.cpp:115
void makect(int nc, int *ip, double *c)
Definition AudioFFT.cpp:239
void cft1st(int n, double *a, double *w)
Definition AudioFFT.cpp:481
void rdft(int n, int isgn, double *a, int *ip, double *w)
Definition AudioFFT.cpp:168
OouraFFT(const OouraFFT &)=delete
virtual void init(size_t size) override
Definition AudioFFT.cpp:100
void rftbsub(int n, double *a, int nc, double *c)
Definition AudioFFT.cpp:742
std::vector< double > _buffer
Definition AudioFFT.cpp:166
void cftmdl(int n, int l, double *a, double *w)
Definition AudioFFT.cpp:586
std::vector< double > _w
Definition AudioFFT.cpp:165
virtual void ifft(float *data, const float *re, const float *im) override
Definition AudioFFT.cpp:140
void bitrv2(int n, int *ip, double *a)
Definition AudioFFT.cpp:261
void rftfsub(int n, double *a, int nc, double *c)
Definition AudioFFT.cpp:717
void cftfsub(int n, double *a, double *w)
Definition AudioFFT.cpp:369
OouraFFT()
Definition AudioFFT.cpp:95
OouraFFT & operator=(const OouraFFT &)=delete
void cftbsub(int n, double *a, double *w)
Definition AudioFFT.cpp:425
size_t _size
Definition AudioFFT.cpp:163
std::vector< int > _ip
Definition AudioFFT.cpp:164
Definition AudioFFT.cpp:50
virtual ~AudioFFTImpl()=default
virtual void ifft(float *data, const float *re, const float *im)=0
virtual void init(size_t size)=0
AudioFFTImpl & operator=(const AudioFFTImpl &)=delete
AudioFFTImpl(const AudioFFTImpl &)=delete
virtual void fft(const float *data, float *re, float *im)=0
constexpr bool IsPowerOf2(size_t val)
Definition AudioFFT.cpp:61
void ConvertBuffer(TypeDest *dest, const TypeSrc *src, size_t len)
Definition AudioFFT.cpp:64
void ScaleBuffer(TypeDest *dest, const TypeSrc *src, const TypeFactor factor, size_t len)
Definition AudioFFT.cpp:73
Definition AudioFFT.cpp:44
OouraFFT AudioFFTImplementation
Definition AudioFFT.cpp:774