shithub: opus

Download patch

ref: 009978ee6c240a1b33a5cafd1d9cc9e7fbfc96f3
parent: ae319fe66bd70718336abcba8eb051e9d5a19d03
author: Jean-Marc Valin <[email protected]>
date: Mon Sep 13 07:05:08 EDT 2010

Moves the bit-side gain application to the quantizer

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -177,7 +177,7 @@
    for (c=0;c<C;c++)
    {
       i=0; do {
-         renormalise_vector(X+M*eBands[i]+c*M*m->shortMdctSize, M*eBands[i+1]-M*eBands[i]);
+         renormalise_vector(X+M*eBands[i]+c*M*m->shortMdctSize, M*eBands[i+1]-M*eBands[i], Q15ONE);
       } while (++i<end);
    }
 }
@@ -437,7 +437,8 @@
    can be called recursively so bands can end up being split in 8 parts. */
 static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_norm *Y,
       int N, int b, int spread, int B, int tf_change, celt_norm *lowband, int resynth, void *ec,
-      celt_int32 *remaining_bits, int LM, celt_norm *lowband_out, const celt_ener *bandE, int level, celt_int32 *seed)
+      celt_int32 *remaining_bits, int LM, celt_norm *lowband_out, const celt_ener *bandE, int level,
+      celt_int32 *seed, celt_word16 gain)
 {
    int q;
    int curr_bits;
@@ -628,7 +629,7 @@
             }
             qalloc = log2_frac(ft,BITRES) - log2_frac(fs,BITRES) + 1;
          }
-         itheta = itheta*16384/qn;
+         itheta = (celt_int32)itheta*16384/qn;
       } else {
          if (stereo && encode)
             stereo_band_mix(m, X, Y, bandE, 1, i, 1, N);
@@ -683,7 +684,7 @@
             }
          }
          sign = 2*sign - 1;
-         quant_band(encode, m, i, x2, NULL, N, mbits, spread, B, tf_change, lowband, resynth, ec, remaining_bits, LM, lowband_out, NULL, level+1, seed);
+         quant_band(encode, m, i, x2, NULL, N, mbits, spread, B, tf_change, lowband, resynth, ec, remaining_bits, LM, lowband_out, NULL, level+1, seed, gain);
          y2[0] = -sign*x2[1];
          y2[1] = sign*x2[0];
       } else {
@@ -692,6 +693,14 @@
          celt_norm *next_lowband_out1=NULL;
          int next_level=0;
 
+#ifdef FIXED_POINT
+         mid = imid;
+         side = iside;
+#else
+         mid = (1.f/32768)*imid;
+         side = (1.f/32768)*iside;
+#endif
+
          /* Give more bits to low-energy MDCTs than they would otherwise deserve */
          if (B>1 && !stereo)
             delta >>= 1;
@@ -707,14 +716,19 @@
          if (lowband && !stereo)
             next_lowband2 = lowband+N; /* >32-bit split case */
 
-         /* Only stereo needs to pass on lowband_out. Otherwise, it's handled at the end */
+         /* Only stereo needs to pass on lowband_out. Otherwise, it's
+            handled at the end */
          if (stereo)
             next_lowband_out1 = lowband_out;
          else
             next_level = level+1;
 
-         quant_band(encode, m, i, X, NULL, N, mbits, spread, B, tf_change, lowband, resynth, ec, remaining_bits, LM, next_lowband_out1, NULL, next_level, seed);
-         quant_band(encode, m, i, Y, NULL, N, sbits, spread, B, tf_change, next_lowband2, resynth, ec, remaining_bits, LM, NULL, NULL, next_level, seed);
+         quant_band(encode, m, i, X, NULL, N, mbits, spread, B, tf_change,
+               lowband, resynth, ec, remaining_bits, LM, next_lowband_out1,
+               NULL, next_level, seed, MULT16_16_P15(gain,mid));
+         quant_band(encode, m, i, Y, NULL, N, sbits, spread, B, tf_change,
+               next_lowband2, resynth, ec, remaining_bits, LM, NULL,
+               NULL, next_level, seed, MULT16_16_P15(gain,side));
       }
 
    } else {
@@ -734,9 +748,9 @@
 
       /* Finally do the actual quantization */
       if (encode)
-         alg_quant(X, N, q, spread, B, lowband, resynth, (ec_enc*)ec, seed);
+         alg_quant(X, N, q, spread, B, lowband, resynth, (ec_enc*)ec, seed, gain);
       else
-         alg_unquant(X, N, q, spread, B, lowband, (ec_dec*)ec, seed);
+         alg_unquant(X, N, q, spread, B, lowband, (ec_dec*)ec, seed, gain);
    }
 
    /* This code is used by the decoder and by the resynthesis-enabled encoder */
@@ -744,23 +758,6 @@
    {
       int k;
 
-      if (split)
-      {
-         int j;
-         celt_word16 mid, side;
-#ifdef FIXED_POINT
-         mid = imid;
-         side = iside;
-#else
-         mid = (1.f/32768)*imid;
-         side = (1.f/32768)*iside;
-#endif
-         for (j=0;j<N;j++)
-            X[j] = MULT16_16_Q15(X[j], mid);
-         for (j=0;j<N;j++)
-            Y[j] = MULT16_16_Q15(Y[j], side);
-      }
-
       /* Undo the sample reorganization going from time order to frequency order */
       if (!stereo && B0>1 && level==0)
       {
@@ -805,8 +802,8 @@
          stereo_band_mix(m, X, Y, bandE, 0, i, -1, N);
          /* We only need to renormalize because quantization may not
             have preserved orthogonality of mid and side */
-         renormalise_vector(X, N);
-         renormalise_vector(Y, N);
+         renormalise_vector(X, N, Q15ONE);
+         renormalise_vector(Y, N, Q15ONE);
       }
    }
 }
@@ -888,7 +885,9 @@
          effective_lowband = NULL;
       else
          effective_lowband = lowband;
-      quant_band(encode, m, i, X, Y, N, b, fold, B, tf_change, effective_lowband, resynth, ec, &remaining_bits, LM, norm+M*eBands[i], bandE, 0, &seed);
+      quant_band(encode, m, i, X, Y, N, b, fold, B, tf_change,
+            effective_lowband, resynth, ec, &remaining_bits, LM,
+            norm+M*eBands[i], bandE, 0, &seed, Q15ONE);
 
       balance += pulses[i] + tell;
 
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -139,7 +139,8 @@
 
 /** Takes the pitch vector and the decoded residual vector, computes the gain
     that will give ||p+g*y||=1 and mixes the residual with the pitch. */
-static void normalise_residual(int * restrict iy, celt_norm * restrict X, int N, int K, celt_word32 Ryy)
+static void normalise_residual(int * restrict iy, celt_norm * restrict X,
+      int N, int K, celt_word32 Ryy, celt_word16 gain)
 {
    int i;
 #ifdef FIXED_POINT
@@ -152,7 +153,7 @@
    k = celt_ilog2(Ryy)>>1;
 #endif
    t = VSHR32(Ryy, (k-7)<<1);
-   g = celt_rsqrt_norm(t);
+   g = MULT16_16_P15(celt_rsqrt_norm(t),gain);
 
    i=0;
    do
@@ -160,7 +161,8 @@
    while (++i < N);
 }
 
-void alg_quant(celt_norm *X, int N, int K, int spread, int B, celt_norm *lowband, int resynth, ec_enc *enc, celt_int32 *seed)
+void alg_quant(celt_norm *X, int N, int K, int spread, int B, celt_norm *lowband,
+      int resynth, ec_enc *enc, celt_int32 *seed, celt_word16 gain)
 {
    VARDECL(celt_norm, y);
    VARDECL(int, iy);
@@ -191,7 +193,7 @@
             X[j] = (int)(*seed)>>20;
          }
       }
-      renormalise_vector(X, N);
+      renormalise_vector(X, N, gain);
       return;
    }
    K = get_pulses(K);
@@ -338,7 +340,7 @@
    
    if (resynth)
    {
-      normalise_residual(iy, X, N, K, EXTRACT16(SHR32(yy,2*yshift)));
+      normalise_residual(iy, X, N, K, EXTRACT16(SHR32(yy,2*yshift)), gain);
       exp_rotation(X, N, -1, B, K, spread);
    }
    RESTORE_STACK;
@@ -347,7 +349,8 @@
 
 /** 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 *X, int N, int K, int spread, int B, celt_norm *lowband, ec_dec *dec, celt_int32 *seed)
+void alg_unquant(celt_norm *X, int N, int K, int spread, int B,
+      celt_norm *lowband, ec_dec *dec, celt_int32 *seed, celt_word16 gain)
 {
    int i;
    celt_word32 Ryy;
@@ -368,7 +371,7 @@
             X[i] = (int)(*seed)>>20;
          }
       }
-      renormalise_vector(X, N);
+      renormalise_vector(X, N, gain);
       return;
    }
    K = get_pulses(K);
@@ -379,7 +382,7 @@
    do {
       Ryy = MAC16_16(Ryy, iy[i], iy[i]);
    } while (++i < N);
-   normalise_residual(iy, X, N, K, Ryy);
+   normalise_residual(iy, X, N, K, Ryy, gain);
    exp_rotation(X, N, -1, B, K, spread);
    RESTORE_STACK;
 }
@@ -397,7 +400,7 @@
    return celt_sqrt(E);
 }
 
-void renormalise_vector(celt_norm *X, int N)
+void renormalise_vector(celt_norm *X, int N, celt_word16 gain)
 {
    int i;
 #ifdef FIXED_POINT
@@ -416,7 +419,7 @@
    k = celt_ilog2(E)>>1;
 #endif
    t = VSHR32(E, (k-7)<<1);
-   g = celt_rsqrt_norm(t);
+   g = MULT16_16_P15(celt_rsqrt_norm(t),gain);
 
    xptr = X;
    for (i=0;i<N;i++)
--- a/libcelt/vq.h
+++ b/libcelt/vq.h
@@ -51,7 +51,8 @@
  * @param p Pitch vector (it is assumed that p+x is a unit vector)
  * @param enc Entropy encoder state
 */
-void alg_quant(celt_norm *X, int N, int K, int spread, int B, celt_norm *lowband, int resynth, ec_enc *enc, celt_int32 *seed);
+void alg_quant(celt_norm *X, int N, int K, int spread, int B, celt_norm *lowband,
+      int resynth, ec_enc *enc, celt_int32 *seed, celt_word16 gain);
 
 /** Algebraic pulse decoder
  * @param x Decoded normalised spectrum (returned)
@@ -60,9 +61,10 @@
  * @param p Pitch vector (automatically added to x)
  * @param dec Entropy decoder state
  */
-void alg_unquant(celt_norm *X, int N, int K, int spread, int B, celt_norm *lowband, ec_dec *dec, celt_int32 *seed);
+void alg_unquant(celt_norm *X, int N, int K, int spread, int B,
+      celt_norm *lowband, ec_dec *dec, celt_int32 *seed, celt_word16 gain);
 
-void renormalise_vector(celt_norm *X, int N);
+void renormalise_vector(celt_norm *X, int N, celt_word16 gain);
 
 celt_word16 vector_norm(const celt_norm *X, int N);