shithub: opus

Download patch

ref: fcb841aa0bd187774f882268e567894a0eca9c11
parent: 104c218c9b1565a8d4bc403fea1a527c19271935
author: Jean-Marc Valin <[email protected]>
date: Thu Mar 20 18:23:54 EDT 2008

Making the real/single FFT easier to replace

--- a/libcelt/kfft_single.h
+++ b/libcelt/kfft_single.h
@@ -48,4 +48,10 @@
 #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 */
--- a/libcelt/kiss_fftr.c
+++ b/libcelt/kiss_fftr.c
@@ -128,6 +128,12 @@
    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 */
--- a/libcelt/kiss_fftr.h
+++ b/libcelt/kiss_fftr.h
@@ -47,6 +47,7 @@
 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);
 
--- a/libcelt/pitch.c
+++ b/libcelt/pitch.c
@@ -51,12 +51,12 @@
 
 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,8 +124,8 @@
    {
       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
@@ -132,16 +132,15 @@
       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 @@
    {
       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 @@
    /*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;