shithub: opus

Download patch

ref: 9d8d9b3f37497fec9585ce10f73dce3fbf4d9a61
parent: 9fbb56a50ef2f08202e9207348d641ca6d2e72ab
author: Jean-Marc Valin <[email protected]>
date: Wed Feb 27 11:17:39 EST 2008

fixed-point: compression factor (alpha) now a 16-bit value (still internally
converted to float though)

--- a/libcelt/arch.h
+++ b/libcelt/arch.h
@@ -80,6 +80,7 @@
 #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 @@
 #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)
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -221,7 +221,7 @@
 {
    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 @@
          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 @@
 {
    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 @@
          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)
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -62,7 +62,7 @@
 /** 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 @@
    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 @@
       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 @@
    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 @@
    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 @@
                   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 @@
          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 @@
 
 /** 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);
--- a/libcelt/vq.h
+++ b/libcelt/vq.h
@@ -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 @@
  * @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.