shithub: opus

Download patch

ref: 49ca99efa524928080db0774eed01beba7be45e2
parent: bd43729ecdbbf6d37042d5a35f2b9decb4273aa0
author: Jean-Marc Valin <[email protected]>
date: Mon Feb 25 09:05:10 EST 2008

fixed-point: initial support for using the fixed-point MDCT (rest is still all
float)

--- a/configure.ac
+++ b/configure.ac
@@ -88,6 +88,21 @@
 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)
--- a/libcelt/_kiss_fft_guts.h
+++ b/libcelt/_kiss_fft_guts.h
@@ -81,11 +81,11 @@
 #   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)
--- a/libcelt/arch.h
+++ b/libcelt/arch.h
@@ -51,10 +51,15 @@
 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 @@
 #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
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -166,10 +166,10 @@
 {
    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 @@
          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 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 @@
          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];
       }
    }
 }
--- a/libcelt/pitch.c
+++ b/libcelt/pitch.c
@@ -48,16 +48,16 @@
 {
    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 @@
    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 @@
       /*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 @@
          max_corr = xx[i];
       }
    }
+   /*printf ("%f\n", max_corr);*/
    /*printf ("\n");
    printf ("%d %f\n", *pitch, max_corr);
    printf ("%d\n", *pitch);*/
--- a/libcelt/psy.c
+++ b/libcelt/psy.c
@@ -122,15 +122,15 @@
 }
 
 /* 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);
@@ -137,7 +137,7 @@
    
 }
 
-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);
--- a/libcelt/psy.h
+++ b/libcelt/psy.h
@@ -45,9 +45,9 @@
 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 */