diff --git a/libcelt/kfft_single.h b/libcelt/kfft_single.h
index 7bc081bd852099215973b73bc692d89cf1b60973..018afe1c47f380a2dd6ea18d06e1d7107a09b756 100644
--- 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 */
diff --git a/libcelt/kiss_fftr.c b/libcelt/kiss_fftr.c
index 427f2db45f5bbec2a5d6023c1e4f52f823f6a637..ee8d7bb124570e00cf336558522c9dc14feb24f5 100644
--- a/libcelt/kiss_fftr.c
+++ b/libcelt/kiss_fftr.c
@@ -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 */
diff --git a/libcelt/kiss_fftr.h b/libcelt/kiss_fftr.h
index 32fda675ce1c4f5c7f31be7f0fd7a6b6ce05b4e1..f2288c136c15eea6c1e7d55afc1b50cc7ff6095b 100644
--- a/libcelt/kiss_fftr.h
+++ b/libcelt/kiss_fftr.h
@@ -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);
 
diff --git a/libcelt/pitch.c b/libcelt/pitch.c
index 8b7ccce58771c8f5cc5aeaedfbb58b828c4127e5..d6565cb68628d83e40d5ceaea06e88f159a3b59a 100644
--- 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,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;