Allowing to add pulses on top of intra-band prediction
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Mon, 3 Dec 2007 04:24:11 +0000 (15:24 +1100)
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Mon, 3 Dec 2007 04:24:11 +0000 (15:24 +1100)
libcelt/bands.c
libcelt/vq.c

index 87055d8..98c7933 100644 (file)
 
 const int qbank[NBANDS+2] =   {0, 2, 4, 6, 8, 12, 16, 20, 24, 28, 36, 44, 52, 68, 84, 116, 128};
 
-const int qpulses[NBANDS  ] = {7, 5, 4, 4, 3,  3,  3,  3,  3,  4,  4,  4,  0,  0,  0};
+const int qpulses[NBANDS  ] = {7, 5, 4, 4, 3,  3,  3,  4,  4,  4, -2, -1, -1, -1,  0};
 //const int qpulses[NBANDS  ] = {17,15,14,14,13, 13, 13, 13, 13, 14, 14, 14, 10, 10, 10};
 
-#define WAVEFORM_END 52
+#define WAVEFORM_END 36
 
 /* Start frequency of each band */
 int pbank[] = {0, 4, 8, 12, 20, WAVEFORM_END, 128};
@@ -147,24 +147,28 @@ void quant_bands(float *X, int B, float *P)
 {
    int i, j;
    float norm[B*qbank[NBANDS+1]];
+   //float bits = 0;
    
    for (i=0;i<NBANDS;i++)
    {
       int q;
       q =qpulses[i];
-      if (q) {
+      if (q>0) {
          float n = sqrt(B*(qbank[i+1]-qbank[i]));
          alg_quant2(X+B*qbank[i], B*(qbank[i+1]-qbank[i]), q, P+B*qbank[i]);
          for (j=B*qbank[i];j<B*qbank[i+1];j++)
             norm[j] = X[j] * n;
+         //bits += log2(ncwrs(B*(qbank[i+1]-qbank[i]), q));
       } else {
          float n = sqrt(B*(qbank[i+1]-qbank[i]));
-         copy_quant(X+B*qbank[i], B*(qbank[i+1]-qbank[i]), q, norm, B, qbank[i]);
+         copy_quant(X+B*qbank[i], B*(qbank[i+1]-qbank[i]), -q, norm, B, qbank[i]);
          for (j=B*qbank[i];j<B*qbank[i+1];j++)
             norm[j] = X[j] * n;
+         //bits += 1+log2(qbank[i])+log2(ncwrs(B*(qbank[i+1]-qbank[i]), -q));
          //noise_quant(X+B*qbank[i], B*(qbank[i+1]-qbank[i]), q, P+B*qbank[i]);
       }
    }
+   //printf ("%f\n", bits);
    for (i=B*qbank[NBANDS];i<B*qbank[NBANDS+1];i++)
       X[i] = 0;
 }
@@ -189,9 +193,9 @@ void pitch_renormalise_bands(float *X, int B, float *P)
          Rxx += X[j]*X[j];
       }
       float arg = Rxp*Rxp + 1 - Rpp;
+      if (arg < 0)
+         arg = 0;
       gain1 = sqrt(arg)-Rxp;
-      if (Rpp>.9999)
-         Rpp = .9999;
       Rxx = 0;
       for (j=B*qbank[i];j<B*qbank[i+1];j++)
       {
index 1d0b6ee..45884f4 100644 (file)
@@ -219,6 +219,8 @@ void noise_quant(float *x, int N, int K, float *p)
    }
 }
 
+static const float pg[5] = {1.f, .82f, .75f, 0.7f, 0.6f};
+
 /* Finds the right offset into Y and copy it */
 void copy_quant(float *x, int N, int K, float *Y, int B, int N0)
 {
@@ -249,13 +251,33 @@ void copy_quant(float *x, int N, int K, float *Y, int B, int N0)
       }
    }
    //printf ("%d %f\n", best, best_score);
-   E = 1e-10;
-   for (j=0;j<N;j++)
+   if (K==0)
    {
-      x[j] = s*Y[best+j];
-      E += x[j]*x[j];
+      E = 1e-10;
+      for (j=0;j<N;j++)
+      {
+         x[j] = s*Y[best+j];
+         E += x[j]*x[j];
+      }
+      E = 1/sqrt(E);
+      for (j=0;j<N;j++)
+         x[j] *= E;
+   } else {
+      float P[N];
+      float pred_gain;
+      if (K>4)
+         pred_gain = .5;
+      else
+         pred_gain = pg[K];
+      E = 1e-10;
+      for (j=0;j<N;j++)
+      {
+         P[j] = s*Y[best+j];
+         E += P[j]*P[j];
+      }
+      E = .8/sqrt(E);
+      for (j=0;j<N;j++)
+         P[j] *= E;
+      alg_quant2(x, N, K, P);
    }
-   E = 1/sqrt(E);
-   for (j=0;j<N;j++)
-      x[j] *= E;
 }