ref: 69c39ca249f1a1c6f5006c8c8d218876751e4040
parent: f69e3bd28ec756be2e25d146bf852c619bf930fa
author: Paul Brossier <piem@piem.org>
date: Tue Oct 15 18:54:59 EDT 2013
src/spectral/fft.c: add vDSP for HAVE_AUBIO_DOUBLE
--- a/src/spectral/fft.c
+++ b/src/spectral/fft.c
@@ -99,9 +99,15 @@
#else
#ifdef HAVE_ACCELERATE // using ACCELERATE
int log2fftsize;
+#if !HAVE_AUBIO_DOUBLE
FFTSetup fftSetup;
DSPSplitComplex spec;
float *in, *out;
+#else
+ FFTSetupD fftSetup;
+ DSPDoubleSplitComplex spec;
+ double *in, *out;
+#endif
#else // using OOURA
double *in, *out;
double *w;
@@ -147,11 +153,19 @@
s->fft_size = winsize;
s->compspec = new_fvec(winsize);
s->log2fftsize = (uint_t)log2f(s->fft_size);
+#if !HAVE_AUBIO_DOUBLE
s->in = AUBIO_ARRAY(float, s->fft_size);
s->out = AUBIO_ARRAY(float, s->fft_size);
s->spec.realp = AUBIO_ARRAY(float, s->fft_size/2);
s->spec.imagp = AUBIO_ARRAY(float, s->fft_size/2);
s->fftSetup = vDSP_create_fftsetup(s->log2fftsize, FFT_RADIX2);
+#else
+ s->in = AUBIO_ARRAY(double, s->fft_size);
+ s->out = AUBIO_ARRAY(double, s->fft_size);
+ s->spec.realp = AUBIO_ARRAY(double, s->fft_size/2);
+ s->spec.imagp = AUBIO_ARRAY(double, s->fft_size/2);
+ s->fftSetup = vDSP_create_fftsetupD(s->log2fftsize, FFT_RADIX2);
+#endif
#else // using OOURA
s->winsize = winsize;
s->fft_size = winsize / 2 + 1;
@@ -218,10 +232,17 @@
#endif /* HAVE_COMPLEX_H */
#else /* HAVE_FFTW3 */
#ifdef HAVE_ACCELERATE // using ACCELERATE
+#if !HAVE_AUBIO_DOUBLE
// convert real data to even/odd format used in vDSP
- vDSP_ctoz((COMPLEX*)s->in, 2, &s->spec, 1, s->fft_size/2);
+ vDSP_ctoz((DSPComplex*)s->in, 2, &s->spec, 1, s->fft_size/2);
// compute the FFT
vDSP_fft_zrip(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_FORWARD);
+#else
+ // convert real data to even/odd format used in vDSP
+ vDSP_ctozD((DSPDoubleComplex*)s->in, 2, &s->spec, 1, s->fft_size/2);
+ // compute the FFT
+ vDSP_fft_zripD(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_FORWARD);
+#endif
// convert from vDSP complex split to [ r0, r1, ..., rN, iN-1, .., i2, i1]
compspec->data[0] = s->spec.realp[0];
compspec->data[s->fft_size / 2] = s->spec.imagp[0];
@@ -231,7 +252,11 @@
}
// apply scaling
smpl_t scale = 1./2.;
+#if !HAVE_AUBIO_DOUBLE
vDSP_vsmul(compspec->data, 1, &scale, compspec->data, 1, s->fft_size);
+#else
+ vDSP_vsmulD(compspec->data, 1, &scale, compspec->data, 1, s->fft_size);
+#endif
#else // using OOURA
rdft(s->winsize, 1, s->in, s->ip, s->w);
compspec->data[0] = s->in[0];
@@ -274,15 +299,27 @@
s->out[2 * i] = compspec->data[i];
s->out[2 * i + 1] = compspec->data[s->winsize - i];
}
+#if !HAVE_AUBIO_DOUBLE
// convert to split complex format used in vDSP
- vDSP_ctoz((COMPLEX*)s->out, 2, &s->spec, 1, s->fft_size/2);
+ vDSP_ctoz((DSPComplex*)s->out, 2, &s->spec, 1, s->fft_size/2);
// compute the FFT
vDSP_fft_zrip(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_INVERSE);
// convert result to real output
- vDSP_ztoc(&s->spec, 1, (COMPLEX*)output->data, 2, s->fft_size/2);
+ vDSP_ztoc(&s->spec, 1, (DSPComplex*)output->data, 2, s->fft_size/2);
// apply scaling
smpl_t scale = 1.0 / s->winsize;
vDSP_vsmul(output->data, 1, &scale, output->data, 1, s->fft_size);
+#else
+ // convert to split complex format used in vDSP
+ vDSP_ctozD((DSPDoubleComplex*)s->out, 2, &s->spec, 1, s->fft_size/2);
+ // compute the FFT
+ vDSP_fft_zripD(s->fftSetup, &s->spec, 1, s->log2fftsize, FFT_INVERSE);
+ // convert result to real output
+ vDSP_ztocD(&s->spec, 1, (DSPDoubleComplex*)output->data, 2, s->fft_size/2);
+ // apply scaling
+ smpl_t scale = 1.0 / s->winsize;
+ vDSP_vsmulD(output->data, 1, &scale, output->data, 1, s->fft_size);
+#endif
#else // using OOURA
smpl_t scale = 2.0 / s->winsize;
s->out[0] = compspec->data[0];