ref: 14e300e8c9313387f48b159370dc126176309fd2
parent: ce5475207e4b3355ae3ab825a551a2845afa8825
author: Paul Brossier <piem@piem.org>
date: Sun Oct 1 14:11:46 EDT 2017
src/spectral/fft.{c,h}: revert changes to fft.h, use ippsAtan2
--- a/src/spectral/fft.c
+++ b/src/spectral/fft.c
@@ -117,22 +117,22 @@
#define aubio_IppFloat Ipp32f
#define aubio_IppComplex Ipp32fc
#define aubio_FFTSpec FFTSpec_R_32f
-#define aubio_ippsPhas ippsPhase_32fc
#define aubio_ippsMalloc_complex ippsMalloc_32fc
#define aubio_ippsFFTInit_R ippsFFTInit_R_32f
#define aubio_ippsFFTGetSize_R ippsFFTGetSize_R_32f
#define aubio_ippsFFTInv_CCSToR ippsFFTInv_CCSToR_32f
#define aubio_ippsFFTFwd_RToCCS ippsFFTFwd_RToCCS_32f
+#define aubio_ippsAtan2 ippsAtan2_32f_A21
#else /* HAVE_AUBIO_DOUBLE */
#define aubio_IppFloat Ipp64f
#define aubio_IppComplex Ipp64fc
#define aubio_FFTSpec FFTSpec_R_64f
-#define aubio_ippsPhas ippsPhase_64fc
#define aubio_ippsMalloc_complex ippsMalloc_64fc
#define aubio_ippsFFTInit_R ippsFFTInit_R_64f
#define aubio_ippsFFTGetSize_R ippsFFTGetSize_R_64f
#define aubio_ippsFFTInv_CCSToR ippsFFTInv_CCSToR_64f
#define aubio_ippsFFTFwd_RToCCS ippsFFTFwd_RToCCS_64f
+#define aubio_ippsAtan2 ippsAtan2_64f_A50
#endif
@@ -158,8 +158,6 @@
smpl_t *in, *out;
#elif defined HAVE_INTEL_IPP // using Intel IPP
- // mark FFT impl as Intel IPP
- #define INTEL_IPP_FFT 1
smpl_t *in, *out;
Ipp8u* memSpec;
Ipp8u* memInit;
@@ -315,11 +313,11 @@
void aubio_fft_do(aubio_fft_t * s, const fvec_t * input, cvec_t * spectrum) {
aubio_fft_do_complex(s, input, s->compspec);
- aubio_fft_get_spectrum(s, s->compspec, spectrum);
+ aubio_fft_get_spectrum(s->compspec, spectrum);
}
void aubio_fft_rdo(aubio_fft_t * s, const cvec_t * spectrum, fvec_t * output) {
- aubio_fft_get_realimag(s, spectrum, s->compspec);
+ aubio_fft_get_realimag(spectrum, s->compspec);
aubio_fft_rdo_complex(s, s->compspec, output);
}
@@ -458,56 +456,51 @@
#endif
}
-void aubio_fft_get_spectrum(aubio_fft_t *s, const fvec_t * compspec, cvec_t * spectrum) {
- aubio_fft_get_phas(s, compspec, spectrum);
- aubio_fft_get_norm(s, compspec, spectrum);
+void aubio_fft_get_spectrum(const fvec_t * compspec, cvec_t * spectrum) {
+ aubio_fft_get_phas(compspec, spectrum);
+ aubio_fft_get_norm(compspec, spectrum);
}
-void aubio_fft_get_realimag(aubio_fft_t *s, const cvec_t * spectrum, fvec_t * compspec) {
- aubio_fft_get_imag(s, spectrum, compspec);
- aubio_fft_get_real(s, spectrum, compspec);
+void aubio_fft_get_realimag(const cvec_t * spectrum, fvec_t * compspec) {
+ aubio_fft_get_imag(spectrum, compspec);
+ aubio_fft_get_real(spectrum, compspec);
}
-void aubio_fft_get_phas(aubio_fft_t *s, const fvec_t * compspec, cvec_t * spectrum) {
-
-#ifdef INTEL_IPP_FFT // using Intel IPP FFT
+void aubio_fft_get_phas(const fvec_t * compspec, cvec_t * spectrum) {
uint_t i;
-
- // convert from real imag [ r0, 0, ..., rN, iN-1, .., i2, i1, iN-1] to complex format
- s->complexOut[0].re = compspec->data[0];
- s->complexOut[0].im = 0;
- s->complexOut[s->fft_size / 2].re = compspec->data[s->fft_size / 2];
- s->complexOut[s->fft_size / 2].im = 0.0;
- for (i = 1; i < spectrum->length - 1; i++) {
- s->complexOut[i].re = compspec->data[i];
- s->complexOut[i].im = compspec->data[compspec->length - i];
- }
-
- IppStatus status = aubio_ippsPhas(s->complexOut, spectrum->phas, spectrum->length);
- if (status != ippStsNoErr) {
- AUBIO_ERR("fft: failed to extract phase from fft. IPP error: %d\n", status);
- }
-
-#else // NOT using Intel IPP
- uint_t i;
if (compspec->data[0] < 0) {
spectrum->phas[0] = PI;
} else {
spectrum->phas[0] = 0.;
}
+#if defined(HAVE_INTEL_IPP)
+ // convert from real imag [ r0, r1, ..., rN, iN-1, ..., i2, i1, i0]
+ // to [ r0, r1, ..., rN, i0, i1, i2, ..., iN-1]
+ for (i = 1; i < spectrum->length / 2; i++) {
+ ELEM_SWAP(compspec->data[compspec->length - i],
+ compspec->data[spectrum->length + i - 1]);
+ }
+ aubio_ippsAtan2(compspec->data + spectrum->length,
+ compspec->data + 1, spectrum->phas + 1, spectrum->length - 1);
+ // revert the imaginary part back again
+ for (i = 1; i < spectrum->length / 2; i++) {
+ ELEM_SWAP(compspec->data[spectrum->length + i - 1],
+ compspec->data[compspec->length - i]);
+ }
+#else
for (i=1; i < spectrum->length - 1; i++) {
spectrum->phas[i] = ATAN2(compspec->data[compspec->length-i],
compspec->data[i]);
}
+#endif
if (compspec->data[compspec->length/2] < 0) {
spectrum->phas[spectrum->length - 1] = PI;
} else {
spectrum->phas[spectrum->length - 1] = 0.;
}
-#endif
}
-void aubio_fft_get_norm(aubio_fft_t *s, const fvec_t * compspec, cvec_t * spectrum) {
+void aubio_fft_get_norm(const fvec_t * compspec, cvec_t * spectrum) {
uint_t i = 0;
spectrum->norm[0] = ABS(compspec->data[0]);
for (i=1; i < spectrum->length - 1; i++) {
@@ -518,7 +511,7 @@
ABS(compspec->data[compspec->length/2]);
}
-void aubio_fft_get_imag(aubio_fft_t *s, const cvec_t * spectrum, fvec_t * compspec) {
+void aubio_fft_get_imag(const cvec_t * spectrum, fvec_t * compspec) {
uint_t i;
for (i = 1; i < ( compspec->length + 1 ) / 2 /*- 1 + 1*/; i++) {
compspec->data[compspec->length - i] =
@@ -526,7 +519,7 @@
}
}
-void aubio_fft_get_real(aubio_fft_t *s, const cvec_t * spectrum, fvec_t * compspec) {
+void aubio_fft_get_real(const cvec_t * spectrum, fvec_t * compspec) {
uint_t i;
for (i = 0; i < compspec->length / 2 + 1; i++) {
compspec->data[i] =
--- a/src/spectral/fft.h
+++ b/src/spectral/fft.h
@@ -98,7 +98,7 @@
\param spectrum cvec norm/phas output array
*/
-void aubio_fft_get_spectrum(aubio_fft_t *s, const fvec_t * compspec, cvec_t * spectrum);
+void aubio_fft_get_spectrum(const fvec_t * compspec, cvec_t * spectrum);
/** convert real/imag spectrum to norm/phas spectrum
\param compspec real/imag input fft array
@@ -105,7 +105,7 @@
\param spectrum cvec norm/phas output array
*/
-void aubio_fft_get_realimag(aubio_fft_t *s, const cvec_t * spectrum, fvec_t * compspec);
+void aubio_fft_get_realimag(const cvec_t * spectrum, fvec_t * compspec);
/** compute phas spectrum from real/imag parts
@@ -113,7 +113,7 @@
\param spectrum cvec norm/phas output array
*/
-void aubio_fft_get_phas(aubio_fft_t *s, const fvec_t * compspec, cvec_t * spectrum);
+void aubio_fft_get_phas(const fvec_t * compspec, cvec_t * spectrum);
/** compute imaginary part from the norm/phas cvec
\param spectrum norm/phas input array
@@ -120,7 +120,7 @@
\param compspec real/imag output fft array
*/
-void aubio_fft_get_imag(aubio_fft_t *s, const cvec_t * spectrum, fvec_t * compspec);
+void aubio_fft_get_imag(const cvec_t * spectrum, fvec_t * compspec);
/** compute norm component from real/imag parts
@@ -128,7 +128,7 @@
\param spectrum cvec norm/phas output array
*/
-void aubio_fft_get_norm(aubio_fft_t *s, const fvec_t * compspec, cvec_t * spectrum);
+void aubio_fft_get_norm(const fvec_t * compspec, cvec_t * spectrum);
/** compute real part from norm/phas components
\param spectrum norm/phas input array
@@ -135,7 +135,7 @@
\param compspec real/imag output fft array
*/
-void aubio_fft_get_real(aubio_fft_t *s, const cvec_t * spectrum, fvec_t * compspec);
+void aubio_fft_get_real(const cvec_t * spectrum, fvec_t * compspec);
#ifdef __cplusplus
}