New VQ search nearly fixed-point ready
[opus.git] / libcelt / vq.c
index daaaa3f..51c9ab8 100644 (file)
@@ -91,7 +91,7 @@ static void mix_pitch_and_residual(int * restrict iy, celt_norm_t * restrict X,
 }
 
 
-void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, const celt_norm_t *P, ec_enc *enc)
+void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, celt_norm_t *P, ec_enc *enc)
 {
    VARDECL(celt_norm_t, y);
    VARDECL(int, iy);
@@ -122,8 +122,11 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, const celt_norm_t *
       X[j] -= P[j];
       if (X[j]>0)
          signx[j]=1;
-      else
+      else {
          signx[j]=-1;
+         X[j]=-X[j];
+         P[j]=-P[j];
+      }
       iy[j] = 0;
       y[j] = 0;
       sum = MAC16_16(sum, P[j],P[j]);
@@ -135,6 +138,29 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, const celt_norm_t *
    xy = yy = yp = 0;
 
    pulsesLeft = K;
+#if 0
+   if (K > (N>>1))
+   {
+      celt_word32_t sum=0;
+      j=0; do {
+         sum += X[j];
+      }  while (++j<N);
+      sum = DIV32(SHL32(EXTEND32(K),15),EPSILON+sum);
+      j=0; do {
+#ifdef FIXED_POINT
+         iy[j] = MULT16_32_Q15(X[j],sum);
+#else
+         iy[j] = floor(sum*X[j]);
+#endif
+         y[j] = SHL16(iy[j],yshift);
+         yy = MAC16_16(yy, y[j],y[j]);
+         xy = MAC16_16(xy, X[j],y[j]);
+         yp += P[j]*y[j];
+         y[j] *= 2;
+         pulsesLeft -= iy[j];
+      }  while (++j<N);
+   }
+#endif
    while (pulsesLeft > 1)
    {
       int pulsesAtOnce=1;
@@ -164,7 +190,7 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, const celt_norm_t *
       do {
          celt_word16_t Rxy, Ryy;
          /* Select sign based on X[j] alone */
-         s = MULT16_16(signx[j],magnitude);
+         s = magnitude;
          /* Temporary sums of the new pulse(s) */
          Rxy = EXTRACT16(SHR32(MAC16_16(xy, s,X[j]),rshift));
          /* We're multiplying y[j] by two so we don't have to do it here */
@@ -185,7 +211,7 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, const celt_norm_t *
       } while (++j<N);
       
       j = best_id;
-      is = MULT16_16(signx[j],pulsesAtOnce);
+      is = pulsesAtOnce;
       s = SHL16(is, yshift);
 
       /* Updating the sums of the new pulse(s) */
@@ -216,7 +242,7 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, const celt_norm_t *
          celt_word16_t Rxy, Ryy, Ryp;
          celt_word16_t num;
          /* Select sign based on X[j] alone */
-         s = MULT16_16(signx[j],magnitude);
+         s = magnitude;
          /* Temporary sums of the new pulse(s) */
          Rxy = ROUND16(MAC16_16(xy, s,X[j]), 14);
          /* We're multiplying y[j] by two so we don't have to do it here */
@@ -242,8 +268,15 @@ void alg_quant(celt_norm_t *X, celt_mask_t *W, int N, int K, const celt_norm_t *
             best_id = j;
          }
       } while (++j<N);
-      iy[best_id] += signx[best_id];
+      iy[best_id] += 1;
    }
+   j=0;
+   do {
+      P[j] = MULT16_16(signx[j],P[j]);
+      X[j] = MULT16_16(signx[j],X[j]);
+      if (signx[j] < 0)
+         iy[j] = -iy[j];
+   } while (++j<N);
    encode_pulses(iy, N, K, enc);
    
    /* Recompute the gain in one pass to reduce the encoder-decoder mismatch
@@ -304,58 +337,18 @@ static void fold(const CELTMode *m, int N, celt_norm_t *Y, celt_norm_t * restric
 
 #define KGAIN 6
 
-void intra_prediction(const CELTMode *m, celt_norm_t * restrict x, celt_mask_t *W, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int B, ec_enc *enc)
+void intra_fold(const CELTMode *m, celt_norm_t * restrict x, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int B)
 {
-   int j;
-   celt_word16_t s = 1;
-   int sign;
    celt_word16_t pred_gain;
-   celt_word32_t xy=0;
    const int C = CHANNELS(m);
 
-   pred_gain = celt_div((celt_word32_t)MULT16_16(Q15_ONE,N),(celt_word32_t)(N+KGAIN*K));
-
-   fold(m, N, Y, P, N0, B);
-
-   for (j=0;j<C*N;j++)
-      xy = MAC16_16(xy, P[j], x[j]);
-   if (xy<0)
-   {
-      s = -1;
-      sign = 1;
-   } else {
-      s = 1;
-      sign = 0;
-   }
-   ec_enc_bits(enc,sign,1);
-
-   renormalise_vector(P, s*pred_gain, C*N, 1);
-}
-
-void intra_unquant(const CELTMode *m, celt_norm_t *x, int N, int K, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int B, ec_dec *dec)
-{
-   celt_word16_t s;
-   celt_word16_t pred_gain;
-   const int C = CHANNELS(m);
-      
-   if (ec_dec_bits(dec, 1) == 0)
-      s = 1;
+   if (K==0)
+      pred_gain = Q15ONE;
    else
-      s = -1;
-   
-   pred_gain = celt_div((celt_word32_t)MULT16_16(Q15_ONE,N),(celt_word32_t)(N+KGAIN*K));
-   
-   fold(m, N, Y, P, N0, B);
-   
-   renormalise_vector(P, s*pred_gain, C*N, 1);
-}
-
-void intra_fold(const CELTMode *m, celt_norm_t *x, int N, celt_norm_t *Y, celt_norm_t * restrict P, int N0, int B)
-{
-   const int C = CHANNELS(m);
+      pred_gain = celt_div((celt_word32_t)MULT16_16(Q15_ONE,N),(celt_word32_t)(N+KGAIN*K));
 
    fold(m, N, Y, P, N0, B);
-   
-   renormalise_vector(P, Q15ONE, C*N, 1);
+
+   renormalise_vector(P, pred_gain, C*N, 1);
 }