doing the folding properly.
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Wed, 13 Feb 2008 05:00:10 +0000 (16:00 +1100)
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Wed, 13 Feb 2008 05:00:10 +0000 (16:00 +1100)
libcelt/bands.c
libcelt/quant_bands.c
libcelt/vq.c
libcelt/vq.h

index 0150cbf..329d7cf 100644 (file)
@@ -265,7 +265,7 @@ void quant_bands(const CELTMode *m, float *X, float *P, float *W, struct alloc_d
          q -= 1;
          alpha = 0;
          if (q<0)
-            intra_fold(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i]);
+            intra_fold(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), norm, P+B*eBands[i], B, eBands[i], eBands[m->nbEBands+1]);
          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 {
@@ -321,7 +321,7 @@ void unquant_bands(const CELTMode *m, float *X, float *P, struct alloc_data *all
          q -= 1;
          alpha = 0;
          if (q<0)
-            intra_fold(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i]);
+            intra_fold(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), norm, P+B*eBands[i], B, eBands[i], eBands[m->nbEBands+1]);
          else
             intra_unquant(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i], dec);
       } else {
index 1f65381..5ad7a9c 100644 (file)
@@ -66,6 +66,7 @@ static void quant_energy_mono(const CELTMode *m, float *eBands, float *oldEBands
       //   qi = -2;
       //ec_laplace_encode(enc, qi, i==0?11192:6192);
       //ec_laplace_encode(enc, qi, 8500-i*200);
+      /* If we don't have enough bits to encode all the energy, just assume something safe. */
       if (ec_enc_tell(enc, 0) - bits > budget)
          qi = -1;
       else
@@ -87,6 +88,7 @@ static void quant_energy_mono(const CELTMode *m, float *eBands, float *oldEBands
    {
       int q2;
       float offset = (error[i]+.5)*frac[i];
+      /* FIXME: Instead of giving up without warning, we should degrade everything gracefully */
       if (ec_enc_tell(enc, 0) - bits +ec_ilog(frac[i])> budget)
          break;
       q2 = (int)floor(offset);
@@ -124,6 +126,7 @@ static void unquant_energy_mono(const CELTMode *m, float *eBands, float *oldEBan
       float res;
       float mean = (1-coef)*eMeans[i];
       res = 6.;
+      /* If we didn't have enough bits to encode all the energy, just assume something safe. */
       if (ec_dec_tell(dec, 0) - bits > budget)
          qi = -1;
       else
index 83cb22d..fb2dd6e 100644 (file)
@@ -419,16 +419,28 @@ void intra_unquant(float *x, int N, int K, float *Y, float *P, int B, int N0, ec
    }
 }
 
-void intra_fold(float *x, int N, int K, float *Y, float *P, int B, int N0)
+void intra_fold(float *x, int N, float *Y, float *P, int B, int N0, int Nmax)
 {
-   int j;
+   int i, j;
    float E;
    
    E = 1e-10;
-   for (j=0;j<N;j++)
+   if (N0 >= Nmax/2)
    {
-      P[j] = Y[j];
-      E += P[j]*P[j];
+      for (i=0;i<B;i++)
+      {
+         for (j=0;j<N/B;j++)
+         {
+            P[j*B+i] = Y[(Nmax-N0-j-1)*B+i];
+            E += P[j*B+i]*P[j*B+i];
+         }
+      }
+   } else {
+      for (j=0;j<N;j++)
+      {
+         P[j] = Y[j];
+         E += P[j]*P[j];
+      }
    }
    E = 1.f/sqrt(E);
    for (j=0;j<N;j++)
index 29751a5..8ca25f8 100644 (file)
@@ -75,6 +75,7 @@ void intra_prediction(float *x, float *W, int N, int K, float *Y, float *P, int
 
 void intra_unquant(float *x, int N, int K, float *Y, float *P, int B, int N0, ec_dec *dec);
 
-void intra_fold(float *x, int N, int K, float *Y, float *P, int B, int N0);
+/** Encode the entire band as a "fold" from other parts of the spectrum. No bits required (only use is case of an emergency!) */
+void intra_fold(float *x, int N, float *Y, float *P, int B, int N0, int Nmax);
 
 #endif /* VQ_H */