fixed-point: initial support for using the fixed-point MDCT (rest is still all
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Mon, 25 Feb 2008 03:05:10 +0000 (14:05 +1100)
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Mon, 25 Feb 2008 03:12:10 +0000 (14:12 +1100)
float)

configure.ac
libcelt/_kiss_fft_guts.h
libcelt/arch.h
libcelt/celt.c
libcelt/pitch.c
libcelt/psy.c
libcelt/psy.h

index 04c2736..c2b2953 100644 (file)
@@ -88,6 +88,21 @@ AC_DEFINE_UNQUOTED(CELT_MINOR_VERSION, ${CELT_MINOR_VERSION}, [Version minor])
 AC_DEFINE_UNQUOTED(CELT_MICRO_VERSION, ${CELT_MICRO_VERSION}, [Version micro])
 AC_DEFINE_UNQUOTED(CELT_EXTRA_VERSION, "${CELT_EXTRA_VERSION}", [Version extra])
 
+AC_ARG_ENABLE(fixed-point, [  --enable-fixed-point    Compile as fixed-point],
+[if test "$enableval" = yes; then
+  AC_DEFINE([FIXED_POINT], , [Compile as fixed-point])
+  AC_DEFINE([DOUBLE_PRECISION], , [Compile as fixed-point])
+else
+  AC_DEFINE([FLOATING_POINT], , [Compile as floating-point])
+fi],
+AC_DEFINE([FLOATING_POINT], , [Compile as floating-point]))
+
+AC_ARG_ENABLE(fixed-point-debug, [  --enable-fixed-point-debug  Debug fixed-point implementation],
+[if test "$enableval" = yes; then
+  AC_DEFINE([FIXED_DEBUG], , [Debug fixed-point implementation])
+fi])
+
+
 AC_CHECK_SIZEOF(short)
 AC_CHECK_SIZEOF(int)
 AC_CHECK_SIZEOF(long)
index e0bde06..644539c 100644 (file)
@@ -81,11 +81,11 @@ struct kiss_fft_state{
 #   define smul(a,b) ( (SAMPPROD)(a)*(b) )
 #   define sround( x )  (kiss_fft_scalar)( ( (x) + ((SAMPPROD)1<<(FRACBITS-1)) ) >> FRACBITS )
 
-#if MIXED_PRECISION
+#ifdef MIXED_PRECISION
 
 #undef MULT16_32_Q15
 #define MULT16_16SU(a,b) ((celt_word32_t)(celt_word16_t)(a)*(celt_word32_t)(celt_uint16_t)(b))
-//#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
+/*#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))*/
 #define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15))
 
 #   define S_MUL(a,b) MULT16_32_Q15(b, a)
index 8521b9c..76ef86f 100644 (file)
 typedef celt_int16_t celt_word16_t;
 typedef celt_int32_t celt_word32_t;
 
+typedef float celt_sig_t;
+typedef float celt_norm_t;
+
 #define Q15ONE 32767
 
 #define LPC_SCALING  8192
-#define SIG_SCALING  16384
+#define SIG_SCALING 16384.f
+#define SIG_SCALING_1 0.000061035
+
 #define LSP_SCALING  8192.
 #define GAMMA_SCALING 32768.
 #define GAIN_SCALING 64
@@ -99,6 +104,7 @@ typedef float celt_norm_t;
 #define Q15ONE 1.0f
 #define LPC_SCALING  1.f
 #define SIG_SCALING  1.f
+#define SIG_SCALING_1 1.f
 #define LSP_SCALING  1.f
 #define GAMMA_SCALING 1.f
 #define GAIN_SCALING 1.f
index 8621261..156716c 100644 (file)
@@ -166,10 +166,10 @@ static float compute_mdcts(mdct_lookup *mdct_lookup, float *window, celt_sig_t *
 {
    int i, c;
    float E = 1e-15;
-   VARDECL(celt_sig_t *x);
-   VARDECL(celt_sig_t *tmp);
-   ALLOC(x, 2*N, celt_sig_t);
-   ALLOC(tmp, N, celt_sig_t);
+   VARDECL(celt_word32_t *x);
+   VARDECL(celt_word32_t *tmp);
+   ALLOC(x, 2*N, celt_word32_t);
+   ALLOC(tmp, N, celt_word32_t);
    for (c=0;c<C;c++)
    {
       for (i=0;i<B;i++)
@@ -177,13 +177,13 @@ static float compute_mdcts(mdct_lookup *mdct_lookup, float *window, celt_sig_t *
          int j;
          for (j=0;j<2*N;j++)
          {
-            x[j] = window[j]*in[C*i*N+C*j+c];
-            E += x[j]*x[j];
+            x[j] = SIG_SCALING*window[j]*in[C*i*N+C*j+c];
+            E += SIG_SCALING_1*SIG_SCALING_1*x[j]*x[j];
          }
          mdct_forward(mdct_lookup, x, tmp);
          /* Interleaving the sub-frames */
          for (j=0;j<N;j++)
-            out[C*B*j+C*i+c] = tmp[j];
+            out[C*B*j+C*i+c] = SIG_SCALING_1*tmp[j];
       }
    }
    return E;
@@ -193,10 +193,10 @@ static float compute_mdcts(mdct_lookup *mdct_lookup, float *window, celt_sig_t *
 static void compute_inv_mdcts(mdct_lookup *mdct_lookup, float *window, celt_sig_t *X, celt_sig_t *out_mem, celt_sig_t *mdct_overlap, int N, int overlap, int B, int C)
 {
    int i, c, N4;
-   VARDECL(celt_sig_t *x);
-   VARDECL(celt_sig_t *tmp);
-   ALLOC(x, 2*N, celt_sig_t);
-   ALLOC(tmp, N, celt_sig_t);
+   VARDECL(celt_word32_t *x);
+   VARDECL(celt_word32_t *tmp);
+   ALLOC(x, 2*N, celt_word32_t);
+   ALLOC(tmp, N, celt_word32_t);
    N4 = (N-overlap)/2;
    for (c=0;c<C;c++)
    {
@@ -205,16 +205,16 @@ static void compute_inv_mdcts(mdct_lookup *mdct_lookup, float *window, celt_sig_
          int j;
          /* De-interleaving the sub-frames */
          for (j=0;j<N;j++)
-            tmp[j] = X[C*B*j+C*i+c];
+            tmp[j] = SIG_SCALING*X[C*B*j+C*i+c];
          mdct_backward(mdct_lookup, tmp, x);
          for (j=0;j<2*N;j++)
             x[j] = window[j]*x[j];
          for (j=0;j<overlap;j++)
-            out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] = 2*(x[N4+j]+mdct_overlap[C*j+c]);
+            out_mem[C*(MAX_PERIOD+(i-B)*N)+C*j+c] = 2*(SIG_SCALING_1*x[N4+j]+mdct_overlap[C*j+c]);
          for (j=0;j<2*N4;j++)
-            out_mem[C*(MAX_PERIOD+(i-B)*N)+C*(j+overlap)+c] = 2*x[j+N4+overlap];
+            out_mem[C*(MAX_PERIOD+(i-B)*N)+C*(j+overlap)+c] = 2*SIG_SCALING_1*x[j+N4+overlap];
          for (j=0;j<overlap;j++)
-            mdct_overlap[C*j+c] = x[N+N4+j];
+            mdct_overlap[C*j+c] = SIG_SCALING_1*x[N+N4+j];
       }
    }
 }
index bee52e0..54e87d2 100644 (file)
@@ -48,16 +48,16 @@ void find_spectral_pitch(kiss_fftr_cfg fft, struct PsyDecay *decay, celt_sig_t *
 {
    int c, i;
    float max_corr;
-   VARDECL(celt_sig_t *xx);
-   VARDECL(celt_sig_t *yy);
-   VARDECL(celt_sig_t *X);
-   VARDECL(celt_sig_t *Y);
+   VARDECL(celt_word32_t *xx);
+   VARDECL(celt_word32_t *yy);
+   VARDECL(celt_word32_t *X);
+   VARDECL(celt_word32_t *Y);
    VARDECL(float *curve);
    int n2 = lag/2;
-   ALLOC(xx, lag*C, celt_sig_t);
-   ALLOC(yy, lag*C, celt_sig_t);
-   ALLOC(X, lag*C, celt_sig_t);
-   ALLOC(Y, lag*C, celt_sig_t);
+   ALLOC(xx, lag*C, celt_word32_t);
+   ALLOC(yy, lag*C, celt_word32_t);
+   ALLOC(X, lag*C, celt_word32_t);
+   ALLOC(Y, lag*C, celt_word32_t);
    ALLOC(curve, n2*C, float);
    
    for (i=0;i<C*lag;i++)
@@ -65,9 +65,9 @@ void find_spectral_pitch(kiss_fftr_cfg fft, struct PsyDecay *decay, celt_sig_t *
    for (c=0;c<C;c++)
    {
       for (i=0;i<len;i++)
-         xx[c*lag+i] = x[C*i+c];
+         xx[c*lag+i] = SIG_SCALING*x[C*i+c];
       for (i=0;i<lag;i++)
-         yy[c*lag+i] = y[C*i+c];
+         yy[c*lag+i] = SIG_SCALING*y[C*i+c];
       
    }
    
@@ -82,13 +82,17 @@ void find_spectral_pitch(kiss_fftr_cfg fft, struct PsyDecay *decay, celt_sig_t *
       /*n = 1.f/(1e1+sqrt(sqrt((X[2*i-1]*X[2*i-1] + X[2*i  ]*X[2*i  ])*(Y[2*i-1]*Y[2*i-1] + Y[2*i  ]*Y[2*i  ]))));*/
       /*n = 1;*/
       n = 1.f/sqrt(1+curve[i]);
+      /*printf ("%f ", n);*/
       /*n = 1.f/(1+curve[i]);*/
       tmp = X[2*i];
-      X[2*i] = (X[2*i  ]*Y[2*i  ] + X[2*i+1]*Y[2*i+1])*n;
-      X[2*i+1] = (- X[2*i+1]*Y[2*i  ] + tmp*Y[2*i+1])*n;
+      X[2*i] = (1.f*X[2*i  ]*Y[2*i  ] + 1.f*X[2*i+1]*Y[2*i+1])*n;
+      X[2*i+1] = (- 1.f*X[2*i+1]*Y[2*i  ] + 1.f*tmp*Y[2*i+1])*n;
    }
+   /*printf ("\n");*/
    X[0] = X[1] = 0;
    kiss_fftri(fft, X, xx);
+   /*for (i=0;i<C*lag;i++)
+      printf ("%d %d\n", X[i], xx[i]);*/
    
    max_corr=-1e10;
    *pitch = 0;
@@ -101,6 +105,7 @@ void find_spectral_pitch(kiss_fftr_cfg fft, struct PsyDecay *decay, celt_sig_t *
          max_corr = xx[i];
       }
    }
+   /*printf ("%f\n", max_corr);*/
    /*printf ("\n");
    printf ("%d %f\n", *pitch, max_corr);
    printf ("%d\n", *pitch);*/
index bbebf8b..2c1d41e 100644 (file)
@@ -122,22 +122,22 @@ static void spreading_func(struct PsyDecay *d, float *psd, float *mask, int len,
 }
 
 /* Compute a marking threshold from the spectrum X. */
-void compute_masking(struct PsyDecay *decay, celt_sig_t *X, float *mask, int len, int Fs)
+void compute_masking(struct PsyDecay *decay, celt_word32_t *X, float *mask, int len, int Fs)
 {
    int i;
    VARDECL(float *psd);
    int N=len/2;
    ALLOC(psd, N, float);
-   psd[0] = X[0]*X[0];
+   psd[0] = X[0]*1.f*X[0];
    for (i=1;i<N;i++)
-      psd[i] = X[i*2]*X[i*2] + X[i*2+1]*X[i*2+1];
+      psd[i] = X[i*2]*1.f*X[i*2] + X[i*2+1]*1.f*X[i*2+1];
    /* TODO: Do tone masking */
    /* Noise masking */
    spreading_func(decay, psd, mask, N, Fs);
    
 }
 
-void compute_mdct_masking(struct PsyDecay *decay, float *X, float *mask, int len, int Fs)
+void compute_mdct_masking(struct PsyDecay *decay, celt_word32_t *X, float *mask, int len, int Fs)
 {
    int i;
    VARDECL(float *psd);
index 45b7544..fd5208a 100644 (file)
@@ -45,9 +45,9 @@ void psydecay_init(struct PsyDecay *decay, int len, int Fs);
 void psydecay_clear(struct PsyDecay *decay);
 
 /** Compute the masking curve for an input (DFT) spectrum X */
-void compute_masking(struct PsyDecay *decay, celt_sig_t *X, float *mask, int len, int Fs);
+void compute_masking(struct PsyDecay *decay, celt_word32_t *X, float *mask, int len, int Fs);
 
 /** Compute the masking curve for an input (MDCT) spectrum X */
-void compute_mdct_masking(struct PsyDecay *decay, float *X, float *mask, int len, int Fs);
+void compute_mdct_masking(struct PsyDecay *decay, celt_word32_t *X, float *mask, int len, int Fs);
 
 #endif /* PSY_H */