diff options
Diffstat (limited to 'src/libfaad/mdct.c')
-rw-r--r-- | src/libfaad/mdct.c | 64 |
1 files changed, 62 insertions, 2 deletions
diff --git a/src/libfaad/mdct.c b/src/libfaad/mdct.c index 4d6d05997..886f227ff 100644 --- a/src/libfaad/mdct.c +++ b/src/libfaad/mdct.c @@ -16,7 +16,7 @@ ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** -** $Id: mdct.c,v 1.1 2002/07/14 23:43:01 miguelfreitas Exp $ +** $Id: mdct.c,v 1.2 2002/08/09 22:36:36 miguelfreitas Exp $ **/ /* @@ -42,13 +42,16 @@ #include <stdlib.h> #include <assert.h> +#ifdef USE_FFTW /* uses fftw (http://www.fftw.org) for very fast arbitrary-n FFT and IFFT */ #include <fftw.h> +#else +#include "cfft.h" +#endif #include "mdct.h" - void faad_mdct_init(mdct_info *mdct, uint16_t N) { uint16_t k; @@ -57,8 +60,13 @@ void faad_mdct_init(mdct_info *mdct, uint16_t N) mdct->N = N; mdct->sincos = (faad_sincos*)malloc(N/4*sizeof(faad_sincos)); +#ifdef USE_FFTW mdct->Z1 = (fftw_complex*)malloc(N/4*sizeof(fftw_complex)); mdct->Z2 = (fftw_complex*)malloc(N/4*sizeof(fftw_complex)); +#else + mdct->Z1 = (real_t*)malloc(N/2*sizeof(real_t)); + mdct->Z2 = (faad_complex*)malloc(N/4*sizeof(faad_complex)); +#endif for (k = 0; k < N/4; k++) { @@ -67,18 +75,27 @@ void faad_mdct_init(mdct_info *mdct, uint16_t N) mdct->sincos[k].cos = -cos(angle); } +#ifdef USE_FFTW mdct->plan_backward = fftw_create_plan(N/4, FFTW_BACKWARD, FFTW_ESTIMATE); #ifdef LTP_DEC mdct->plan_forward = fftw_create_plan(N/4, FFTW_FORWARD, FFTW_ESTIMATE); #endif +#else + /* own implementation */ + mdct->cfft = cffti(N/4); +#endif } void faad_mdct_end(mdct_info *mdct) { +#ifdef USE_FFTW fftw_destroy_plan(mdct->plan_backward); #ifdef LTP_DEC fftw_destroy_plan(mdct->plan_forward); #endif +#else + cfftu(mdct->cfft); +#endif if (mdct->Z2) free(mdct->Z2); if (mdct->Z1) free(mdct->Z1); @@ -89,9 +106,15 @@ void faad_imdct(mdct_info *mdct, real_t *X_in, real_t *X_out) { uint16_t k; +#ifdef USE_FFTW fftw_complex *Z1 = mdct->Z1; fftw_complex *Z2 = mdct->Z2; +#else + real_t *Z1 = mdct->Z1; + faad_complex *Z2 = mdct->Z2; +#endif faad_sincos *sincos = mdct->sincos; + real_t fftdata[1024]; uint16_t N = mdct->N; uint16_t N2 = N >> 1; @@ -106,18 +129,32 @@ void faad_imdct(mdct_info *mdct, real_t *X_in, real_t *X_out) uint16_t n = k << 1; real_t x0 = X_in[ n]; real_t x1 = X_in[N2 - 1 - n]; +#ifdef USE_FFTW Z1[k].re = MUL(fac, MUL(x1, sincos[k].cos) - MUL(x0, sincos[k].sin)); Z1[k].im = MUL(fac, MUL(x0, sincos[k].cos) + MUL(x1, sincos[k].sin)); +#else + Z1[2*k] = MUL(fac, MUL(x1, sincos[k].cos) - MUL(x0, sincos[k].sin)); + Z1[2*k+1] = MUL(fac, MUL(x0, sincos[k].cos) + MUL(x1, sincos[k].sin)); +#endif } /* complex IFFT */ +#ifdef USE_FFTW fftw_one(mdct->plan_backward, Z1, Z2); +#else + cfftb(mdct->cfft, Z1); +#endif /* post-IFFT complex multiplication */ for (k = 0; k < N4; k++) { +#ifdef USE_FFTW real_t zr = Z2[k].re; real_t zi = Z2[k].im; +#else + real_t zr = Z1[2*k]; + real_t zi = Z1[2*k+1]; +#endif Z2[k].re = MUL(zr, sincos[k].cos) - MUL(zi, sincos[k].sin); Z2[k].im = MUL(zi, sincos[k].cos) + MUL(zr, sincos[k].sin); } @@ -142,8 +179,12 @@ void faad_mdct(mdct_info *mdct, real_t *X_in, real_t *X_out) { uint16_t k; +#ifdef USE_FFTW fftw_complex *Z1 = mdct->Z1; fftw_complex *Z2 = mdct->Z2; +#else + real_t *Z1 = mdct->Z1; +#endif faad_sincos *sincos = mdct->sincos; uint16_t N = mdct->N; @@ -159,25 +200,44 @@ void faad_mdct(mdct_info *mdct, real_t *X_in, real_t *X_out) real_t zr = X_in[N - N4 - 1 - n] + X_in[N - N4 + n]; real_t zi = X_in[ N4 + n] - X_in[ N4 - 1 - n]; +#ifdef USE_FFTW Z1[k ].re = -MUL(zr, sincos[k ].cos) - MUL(zi, sincos[k ].sin); Z1[k ].im = -MUL(zi, sincos[k ].cos) + MUL(zr, sincos[k ].sin); +#else + Z1[k*2 ] = -MUL(zr, sincos[k ].cos) - MUL(zi, sincos[k ].sin); + Z1[k*2+1 ] = -MUL(zi, sincos[k ].cos) + MUL(zr, sincos[k ].sin); +#endif zr = X_in[ N2 - 1 - n] - X_in[ n]; zi = X_in[ N2 + n] + X_in[N - 1 - n]; +#ifdef USE_FFTW Z1[k + N8].re = -MUL(zr, sincos[k + N8].cos) - MUL(zi, sincos[k + N8].sin); Z1[k + N8].im = -MUL(zi, sincos[k + N8].cos) + MUL(zr, sincos[k + N8].sin); +#else + Z1[k*2 + N8] = -MUL(zr, sincos[k + N8].cos) - MUL(zi, sincos[k + N8].sin); + Z1[k*2+1 + N8] = -MUL(zi, sincos[k + N8].cos) + MUL(zr, sincos[k + N8].sin); +#endif } /* complex FFT */ +#ifdef USE_FFTW fftw_one(mdct->plan_forward, Z1, Z2); +#else + cfftf(mdct->cfft, Z1); +#endif /* post-FFT complex multiplication */ for (k = 0; k < N4; k++) { uint16_t n = k << 1; +#ifdef USE_FFTW real_t zr = MUL(2.0, MUL(Z2[k].re, sincos[k].cos) + MUL(Z2[k].im, sincos[k].sin)); real_t zi = MUL(2.0, MUL(Z2[k].im, sincos[k].cos) - MUL(Z2[k].re, sincos[k].sin)); +#else + real_t zr = MUL(2.0, MUL(Z1[k*2], sincos[k].cos) + MUL(Z1[k*2+1], sincos[k].sin)); + real_t zi = MUL(2.0, MUL(Z1[k*2+1], sincos[k].cos) - MUL(Z1[k*2], sincos[k].sin)); +#endif X_out[ n] = -zr; X_out[N2 - 1 - n] = zi; |