From 42667b0a5f4fde51f211e50b5eb78a1d5c98b1d0 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin Date: Mon, 25 Feb 2008 09:47:25 +1100 Subject: [PATCH] real fft no longer needs an internal buffer. --- libcelt/kiss_fft.c | 40 ++++++++++++++++++++-------------------- libcelt/kiss_fft.h | 4 ++++ libcelt/kiss_fftr.c | 31 ++++++++++++++----------------- 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/libcelt/kiss_fft.c b/libcelt/kiss_fft.c index 33a1c69b..ee45f964 100644 --- a/libcelt/kiss_fft.c +++ b/libcelt/kiss_fft.c @@ -478,8 +478,8 @@ static void ki_bfly_generic( static void compute_bitrev_table( - int * Fout, - int f, + int Fout, + int *f, const size_t fstride, int in_stride, int * factors, @@ -495,7 +495,7 @@ void compute_bitrev_table( int j; for (j=0;jbitrev = (int*)((char*)st + memneeded - sizeof(int)*nfft); - compute_bitrev_table(st->bitrev, 0, 1,1, st->factors,st); + compute_bitrev_table(0, st->bitrev, 1,1, st->factors,st); } return st; } @@ -654,10 +654,10 @@ void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout, int i; for (i=0;infft;i++) { - fout[i] = fin[st->bitrev[i]]; + fout[st->bitrev[i]] = fin[i]; #ifndef FIXED_POINT - fout[i].r *= st->scale; - fout[i].i *= st->scale; + fout[st->bitrev[i]].r *= st->scale; + fout[st->bitrev[i]].i *= st->scale; #endif } kf_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1); @@ -678,7 +678,7 @@ void kiss_ifft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout /* Bit-reverse the input */ int i; for (i=0;infft;i++) - fout[i] = fin[st->bitrev[i]]; + fout[st->bitrev[i]] = fin[i]; ki_work( fout, fin, 1,in_stride, st->factors,st, 1, in_stride, 1); } } diff --git a/libcelt/kiss_fft.h b/libcelt/kiss_fft.h index 7aa67942..fb1c9d07 100644 --- a/libcelt/kiss_fft.h +++ b/libcelt/kiss_fft.h @@ -85,6 +85,10 @@ typedef struct kiss_fft_state* kiss_fft_cfg; kiss_fft_cfg kiss_fft_alloc(int nfft,void * mem,size_t * lenmem); +/** Internal function. Can be useful when you want to do the bit-reversing yourself */ +void ki_work(kiss_fft_cpx * Fout, const kiss_fft_cpx * f, const size_t fstride, + int in_stride,int * factors,const kiss_fft_cfg st,int N,int s2,int m2); + /** * kiss_fft(cfg,in_out_buf) * diff --git a/libcelt/kiss_fftr.c b/libcelt/kiss_fftr.c index 6d829e84..c09364cd 100644 --- a/libcelt/kiss_fftr.c +++ b/libcelt/kiss_fftr.c @@ -26,7 +26,6 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND struct kiss_fftr_state{ kiss_fft_cfg substate; - kiss_fft_cpx * tmpbuf; kiss_twiddle_cpx * super_twiddles; #ifdef USE_SIMD long pad; @@ -46,7 +45,7 @@ kiss_fftr_cfg kiss_fftr_alloc(int nfft,void * mem,size_t * lenmem) nfft >>= 1; kiss_fft_alloc (nfft, NULL, &subsize); - memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_fft_cpx) * ( nfft) + sizeof(kiss_twiddle_cpx)*nfft; + memneeded = sizeof(struct kiss_fftr_state) + subsize + sizeof(kiss_twiddle_cpx)*nfft; if (lenmem == NULL) { st = (kiss_fftr_cfg) KISS_FFT_MALLOC (memneeded); @@ -59,8 +58,7 @@ kiss_fftr_cfg kiss_fftr_alloc(int nfft,void * mem,size_t * lenmem) return NULL; st->substate = (kiss_fft_cfg) (st + 1); /*just beyond kiss_fftr_state struct */ - st->tmpbuf = (kiss_fft_cpx *) (((char *) st->substate) + subsize); - st->super_twiddles = (kiss_twiddle_cpx*)(st->tmpbuf + nfft); + st->super_twiddles = (kiss_twiddle_cpx*) (((char *) st->substate) + subsize); kiss_fft_alloc(nfft, st->substate, &subsize); #ifndef FIXED_POINT st->substate->scale *= .5; @@ -135,26 +133,25 @@ void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata,kiss_fft_scalar ncfft = st->substate->nfft; - st->tmpbuf[0].r = freqdata[0] + freqdata[1]; - st->tmpbuf[0].i = freqdata[0] - freqdata[1]; - + timedata[2*st->substate->bitrev[0]] = freqdata[0] + freqdata[1]; + timedata[2*st->substate->bitrev[0]+1] = freqdata[0] - freqdata[1]; for (k = 1; k <= ncfft / 2; ++k) { kiss_fft_cpx fk, fnkc, fek, fok, tmp; + int k1, k2; + k1 = st->substate->bitrev[k]; + k2 = st->substate->bitrev[ncfft-k]; fk.r = freqdata[2*k]; fk.i = freqdata[2*k+1]; - fnkc.r = freqdata[2*(ncfft - k)]; - fnkc.i = -freqdata[2*(ncfft - k)+1]; + fnkc.r = freqdata[2*(ncfft-k)]; + fnkc.i = -freqdata[2*(ncfft-k)+1]; C_ADD (fek, fk, fnkc); C_SUB (tmp, fk, fnkc); C_MUL (fok, tmp, st->super_twiddles[k]); - C_ADD (st->tmpbuf[k], fek, fok); - C_SUB (st->tmpbuf[ncfft - k], fek, fok); -#ifdef USE_SIMD - st->tmpbuf[ncfft - k].i *= _mm_set1_ps(-1.0); -#else - st->tmpbuf[ncfft - k].i *= -1; -#endif + timedata[2*k1] = fek.r + fok.r; + timedata[2*k1+1] = fek.i + fok.i; + timedata[2*k2] = fek.r - fok.r; + timedata[2*k2+1] = fok.i - fek.i; } - kiss_ifft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); + ki_work((kiss_fft_cpx*)timedata, NULL, 1,1, st->substate->factors,st->substate, 1, 1, 1); }