fixed-point: compression factor (alpha) now a 16-bit value (still internally
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Wed, 27 Feb 2008 05:17:39 +0000 (16:17 +1100)
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Wed, 27 Feb 2008 05:17:39 +0000 (16:17 +1100)
converted to float though)

libcelt/arch.h
libcelt/bands.c
libcelt/vq.c
libcelt/vq.h

index 73ebef5..c836910 100644 (file)
@@ -80,6 +80,7 @@ typedef float celt_mask_t;
 #define VERY_LARGE32 ((celt_word32_t)2147483647)
 #define VERY_LARGE16 ((celt_word16_t)32767)
 #define Q15_ONE ((celt_word16_t)32767)
+#define Q15_ONE_1 (1.f/32768.f)
 
 
 #ifdef FIXED_DEBUG
@@ -129,6 +130,7 @@ typedef float celt_mask_t;
 #define VERY_LARGE32 1e15f
 #define VERY_LARGE16 1e15f
 #define Q15_ONE ((celt_word16_t)1.f)
+#define Q15_ONE_1 ((celt_word16_t)1.f)
 
 #define QCONST16(x,bits) (x)
 #define QCONST32(x,bits) (x)
index dbe2150..6b7f2b0 100644 (file)
@@ -221,7 +221,7 @@ void quant_bands(const CELTMode *m, celt_norm_t *X, celt_norm_t *P, celt_mask_t
 {
    int i, j, B, bits;
    const int *eBands = m->eBands;
-   float alpha = .7;
+   celt_word16_t alpha;
    VARDECL(celt_norm_t *norm);
    VARDECL(int *pulses);
    VARDECL(int *offsets);
@@ -263,7 +263,7 @@ void quant_bands(const CELTMode *m, celt_norm_t *X, celt_norm_t *P, celt_mask_t
          else
             intra_prediction(X+B*eBands[i], W+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i], enc);
       } else {
-         alpha = .7;
+         alpha = QCONST16(.7f,15);
       }
       
       if (q > 0)
@@ -285,7 +285,7 @@ void unquant_bands(const CELTMode *m, celt_norm_t *X, celt_norm_t *P, int total_
 {
    int i, j, B, bits;
    const int *eBands = m->eBands;
-   float alpha = .7;
+   celt_word16_t alpha;
    VARDECL(celt_norm_t *norm);
    VARDECL(int *pulses);
    VARDECL(int *offsets);
@@ -322,7 +322,7 @@ void unquant_bands(const CELTMode *m, celt_norm_t *X, celt_norm_t *P, int total_
          else
             intra_unquant(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i], dec);
       } else {
-         alpha = .7;
+         alpha = QCONST16(.7f,15);
       }
       
       if (q > 0)
index ff877bb..9c96eb5 100644 (file)
@@ -62,7 +62,7 @@ static inline float approx_inv(float x)
 /** Takes the pitch vector and the decoded residual vector (non-compressed), 
    applies the compression in the pitch direction, computes the gain that will
    give ||p+g*y||=1 and mixes the residual with the pitch. */
-static void mix_pitch_and_residual(int *iy, celt_norm_t *X, int N, celt_norm_t *P, float alpha)
+static void mix_pitch_and_residual(int *iy, celt_norm_t *X, int N, celt_norm_t *P, celt_word16_t alpha)
 {
    int i;
    float Rpp=0, Ryp=0, Ryy=0;
@@ -70,7 +70,8 @@ static void mix_pitch_and_residual(int *iy, celt_norm_t *X, int N, celt_norm_t *
    VARDECL(float *y);
    VARDECL(float *x);
    VARDECL(float *p);
-   
+   float _alpha = Q15_ONE_1*alpha;
+
    ALLOC(y, N, float);
    ALLOC(x, N, float);
    ALLOC(p, N, float);
@@ -87,7 +88,7 @@ static void mix_pitch_and_residual(int *iy, celt_norm_t *X, int N, celt_norm_t *
       Ryp += iy[i]*p[i];
 
    for (i=0;i<N;i++)
-      y[i] = iy[i] - alpha*Ryp*p[i];
+      y[i] = iy[i] - _alpha*Ryp*p[i];
 
    /* Recompute after the projection (I think it's right) */
    Ryp = 0;
@@ -115,7 +116,7 @@ struct NBest {
    float yp;
 };
 
-void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, celt_norm_t *P, float alpha, ec_enc *enc)
+void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, celt_norm_t *P, celt_word16_t alpha, ec_enc *enc)
 {
    int L = 3;
    VARDECL(float *x);
@@ -137,7 +138,8 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, celt_norm_t *P, flo
    VARDECL(struct NBest **nbest);
    float Rpp=0, Rxp=0;
    int maxL = 1;
-   
+   float _alpha = Q15_ONE_1*alpha;
+
    ALLOC(x, N, float);
    ALLOC(p, N, float);
    ALLOC(_y, L*N, float);
@@ -230,9 +232,9 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, celt_norm_t *P, flo
                   continue;
 
                /* Updating the sums of the new pulse(s) */
-               tmp_xy = xy[m] + s*x[j]               - alpha*s*p[j]*Rxp;
-               tmp_yy = yy[m] + 2.f*s*y[m][j] + s*s      +s*s*alpha*alpha*p[j]*p[j]*Rpp - 2.f*alpha*s*p[j]*yp[m] - 2.f*s*s*alpha*p[j]*p[j];
-               tmp_yp = yp[m] + s*p[j]               *(1.f-alpha*Rpp);
+               tmp_xy = xy[m] + s*x[j]               - _alpha*s*p[j]*Rxp;
+               tmp_yy = yy[m] + 2.f*s*y[m][j] + s*s      +s*s*_alpha*_alpha*p[j]*p[j]*Rpp - 2.f*_alpha*s*p[j]*yp[m] - 2.f*s*s*_alpha*p[j]*p[j];
+               tmp_yp = yp[m] + s*p[j]               *(1.f-_alpha*Rpp);
                
                /* Compute the gain such that ||p + g*y|| = 1 */
                g = (approx_sqrt(tmp_yp*tmp_yp + tmp_yy - tmp_yy*Rpp) - tmp_yp)*approx_inv(tmp_yy);
@@ -280,7 +282,7 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, celt_norm_t *P, flo
          is = nbest[k]->sign*pulsesAtOnce;
          s = is;
          for (n=0;n<N;n++)
-            ny[k][n] = y[nbest[k]->orig][n] - alpha*s*p[nbest[k]->pos]*p[n];
+            ny[k][n] = y[nbest[k]->orig][n] - _alpha*s*p[nbest[k]->pos]*p[n];
          ny[k][nbest[k]->pos] += s;
 
          for (n=0;n<N;n++)
@@ -344,7 +346,7 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, celt_norm_t *P, flo
 
 /** Decode pulse vector and combine the result with the pitch vector to produce
     the final normalised signal in the current band. */
-void alg_unquant(celt_norm_t *X, int N, int K, celt_norm_t *P, float alpha, ec_dec *dec)
+void alg_unquant(celt_norm_t *X, int N, int K, celt_norm_t *P, celt_word16_t alpha, ec_dec *dec)
 {
    VARDECL(int *iy);
    ALLOC(iy, N, int);
index b763167..70e46cb 100644 (file)
@@ -51,7 +51,7 @@
  * @param alpha compression factor to apply in the pitch direction (magic!)
  * @param enc Entropy encoder state
 */
-void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, celt_norm_t *P, float alpha, ec_enc *enc);
+void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, celt_norm_t *P, celt_word16_t alpha, ec_enc *enc);
 
 /** Algebraic pulse decoder
  * @param x Decoded normalised spectrum (returned)
@@ -61,7 +61,7 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, celt_norm_t *P, flo
  * @param alpha compression factor in the pitch direction (magic!)
  * @param dec Entropy decoder state
  */
-void alg_unquant(celt_norm_t *X, int N, int K, celt_norm_t *P, float alpha, ec_dec *dec);
+void alg_unquant(celt_norm_t *X, int N, int K, celt_norm_t *P, celt_word16_t alpha, ec_dec *dec);
 
 /** Intra-frame predictor that matches a section of the current frame (at lower
  * frequencies) to encode the current band.