Making the real/single FFT easier to replace
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 20 Mar 2008 11:23:54 +0000 (22:23 +1100)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 20 Mar 2008 11:23:54 +0000 (22:23 +1100)
libcelt/kfft_single.h
libcelt/kiss_fftr.c
libcelt/kiss_fftr.h
libcelt/pitch.c

index 7bc081b..018afe1 100644 (file)
 #include "kiss_fftr.h"
 #include "_kiss_fft_guts.h"
 
+#define real16_fft_alloc(length) kiss_fftr_alloc_celt_single(length, 0, 0);
+#define real16_fft_free(state) kiss_fft_free(state)
+#define real16_fft_inplace(state, X) kiss_fftr_inplace(state,X)
+#define BITREV(state, i) ((state)->substate->bitrev[i])
+#define real16_ifft(state, X, Y) kiss_fftri(state,X, Y)
+
 #endif /* KFFT_SINGLE_H */
index 427f2db..ee8d7bb 100644 (file)
@@ -128,6 +128,12 @@ void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar
    kiss_fftr_twiddles(st,freqdata);
 }
 
+void kiss_fftr_inplace(kiss_fftr_cfg st, kiss_fft_scalar *X)
+{
+   kf_work((kiss_fft_cpx*)X, NULL, 1,1, st->substate->factors,st->substate, 1, 1, 1);
+   kiss_fftr_twiddles(st,X);
+}
+
 void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata,kiss_fft_scalar *timedata)
 {
    /* input buffer timedata is stored row-wise */
index 32fda67..f2288c1 100644 (file)
@@ -47,6 +47,7 @@ kiss_fftr_cfg kiss_fftr_alloc(int nfft,void * mem, size_t * lenmem);
 void kiss_fftr_twiddles(kiss_fftr_cfg st,kiss_fft_scalar *freqdata);
 
 void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar *timedata,kiss_fft_scalar *freqdata);
+void kiss_fftr_inplace(kiss_fftr_cfg st, kiss_fft_scalar *X);
 
 void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_scalar *freqdata, kiss_fft_scalar *timedata);
 
index 8b7ccce..d6565cb 100644 (file)
 
 kiss_fftr_cfg pitch_state_alloc(int max_lag)
 {
-   return kiss_fftr_alloc_celt_single(max_lag, 0, 0);
+   return real16_fft_alloc(max_lag);
 }
 
 void pitch_state_free(kiss_fftr_cfg st)
 {
-   kiss_fft_free(st);
+   real16_fft_free(st);
 }
 
 #ifdef FIXED_POINT
@@ -124,24 +124,23 @@ void find_spectral_pitch(kiss_fftr_cfg fft, const struct PsyDecay *decay, const
    {
       for (i=0;i<L2;i++)
       {
-         X[2*bitrev[i]] += SHR32(x[C*(2*i)+c],INPUT_SHIFT);
-         X[2*bitrev[i]+1] += SHR32(x[C*(2*i+1)+c],INPUT_SHIFT);
+         X[2*BITREV(fft,i)] += SHR32(x[C*(2*i)+c],INPUT_SHIFT);
+         X[2*BITREV(fft,i)+1] += SHR32(x[C*(2*i+1)+c],INPUT_SHIFT);
       }
    }
    /* Applying the window in the bit-reverse domain. It's a bit weird, but it
       can help save memory */
    for (i=0;i<overlap/2;i++)
    {
-      X[2*bitrev[i]] = MULT16_16_Q15(window[2*i], X[2*bitrev[i]]);
-      X[2*bitrev[i]+1] = MULT16_16_Q15(window[2*i+1], X[2*bitrev[i]+1]);
-      X[2*bitrev[L2-i-1]] = MULT16_16_Q15(window[2*i+1], X[2*bitrev[L2-i-1]]);
-      X[2*bitrev[L2-i-1]+1] = MULT16_16_Q15(window[2*i], X[2*bitrev[L2-i-1]+1]);
+      X[2*BITREV(fft,i)] = MULT16_16_Q15(window[2*i], X[2*BITREV(fft,i)]);
+      X[2*BITREV(fft,i)+1] = MULT16_16_Q15(window[2*i+1], X[2*BITREV(fft,i)+1]);
+      X[2*BITREV(fft,L2-i-1)] = MULT16_16_Q15(window[2*i+1], X[2*BITREV(fft,L2-i-1)]);
+      X[2*BITREV(fft,L2-i-1)+1] = MULT16_16_Q15(window[2*i], X[2*BITREV(fft,L2-i-1)+1]);
    }
    normalise16(X, lag, 8192);
    /*for (i=0;i<lag;i++) printf ("%d ", X[i]);printf ("\n");*/
    /* Forward real FFT (in-place) */
-   kf_work((kiss_fft_cpx*)X, NULL, 1,1, fft->substate->factors,fft->substate, 1, 1, 1);
-   kiss_fftr_twiddles(fft,X);
+   real16_fft_inplace(fft, X);
 
    compute_masking(decay, X, curve, lag);
 
@@ -154,14 +153,13 @@ void find_spectral_pitch(kiss_fftr_cfg fft, const struct PsyDecay *decay, const
    {
       for (i=0;i<n2;i++)
       {
-         Y[2*bitrev[i]] += SHR32(y[C*(2*i)+c],INPUT_SHIFT);
-         Y[2*bitrev[i]+1] += SHR32(y[C*(2*i+1)+c],INPUT_SHIFT);
+         Y[2*BITREV(fft,i)] += SHR32(y[C*(2*i)+c],INPUT_SHIFT);
+         Y[2*BITREV(fft,i)+1] += SHR32(y[C*(2*i+1)+c],INPUT_SHIFT);
       }
    }
    normalise16(Y, lag, 8192);
    /* Forward real FFT (in-place) */
-   kf_work((kiss_fft_cpx*)Y, NULL, 1,1, fft->substate->factors,fft->substate, 1, 1, 1);
-   kiss_fftr_twiddles(fft,Y);
+   real16_fft_inplace(fft, Y);
 
    /* Compute cross-spectrum using the inverse masking curve as weighting */
    for (i=1;i<n2;i++)
@@ -181,7 +179,7 @@ void find_spectral_pitch(kiss_fftr_cfg fft, const struct PsyDecay *decay, const
    /*for (i=0;i<lag;i++) printf ("%d ", X[i]);printf ("\n");*/
    normalise16(X, lag, 50);
    /* Inverse half-complex to real FFT gives us the correlation */
-   kiss_fftri(fft, X, Y);
+   real16_ifft(fft, X, Y);
    
    /* The peak in the correlation gives us the pitch */
    max_corr=-VERY_LARGE32;