Enabling "plain folding" in case we don't even have enough bits for intra-frame
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Mon, 11 Feb 2008 04:33:53 +0000 (15:33 +1100)
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Mon, 11 Feb 2008 04:33:53 +0000 (15:33 +1100)
prediction

libcelt/bands.c
libcelt/rate.c
libcelt/testcelt.c
libcelt/vq.c
libcelt/vq.h

index 599e7fb..c7ffc10 100644 (file)
@@ -259,10 +259,16 @@ void quant_bands(const CELTMode *m, float *X, float *P, float *W, struct alloc_d
       theta = .007*(B*(eBands[i+1]-eBands[i]))/(.1f+abs(q));
 
       /* If pitch isn't available, use intra-frame prediction */
-      if (eBands[i] >= m->pitchEnd)
-         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);
-
-      if (q != 0)
+      if (eBands[i] >= m->pitchEnd || q<=0)
+      {
+         q -= 1;
+         if (q<0)
+            intra_fold(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i]);
+         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);
+      }
+      
+      if (q > 0)
       {
          exp_rotation(P+B*eBands[i], B*(eBands[i+1]-eBands[i]), theta, -1, B, 8);
          exp_rotation(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), theta, -1, B, 8);
@@ -305,10 +311,16 @@ void unquant_bands(const CELTMode *m, float *X, float *P, struct alloc_data *all
       theta = .007*(B*(eBands[i+1]-eBands[i]))/(.1f+abs(q));
 
       /* If pitch isn't available, use intra-frame prediction */
-      if (eBands[i] >= m->pitchEnd)
-         intra_unquant(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i], dec);
-
-      if (q != 0)
+      if (eBands[i] >= m->pitchEnd || q<=0)
+      {
+         q -= 1;
+         if (q<0)
+            intra_fold(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i]);
+         else
+            intra_unquant(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, norm, P+B*eBands[i], B, eBands[i], dec);
+      }
+      
+      if (q > 0)
       {
          exp_rotation(P+B*eBands[i], B*(eBands[i+1]-eBands[i]), theta, -1, B, 8);
          alg_unquant(X+B*eBands[i], B*(eBands[i+1]-eBands[i]), q, P+B*eBands[i], 0.7, dec);
index 788c64c..a727931 100644 (file)
@@ -118,19 +118,27 @@ void alloc_init(struct alloc_data *alloc, const CELTMode *m)
          for (j=0;j<MAX_PULSES;j++)
          {
             int done = 0;
-            alloc->bits[i][j] = log2_frac64(ncwrs64(N, j),BITRES);
-            /* FIXME: Could there be a better test for the max number of pulses that fit in 64 bits? */
-            if (alloc->bits[i][j] > (60<<BITRES))
-               done = 1;
-            /* Add the intra-frame prediction bits */
+            int pulses = j;
+            /* For bands where there's no pitch, id 1 corresponds to intra prediction 
+               with no pulse. id 2 means intra prediction with one pulse, and so on.*/
             if (eBands[i] >= m->pitchEnd)
-            {
-               int max_pos = 2*eBands[i]-eBands[i+1];
-               if (max_pos > 32)
-                  max_pos = 32;
-               alloc->bits[i][j] += (1<<BITRES) + log2_frac(max_pos,BITRES);
+               pulses -= 1;
+            if (pulses < 0)
+               alloc->bits[i][j] = 0;
+            else {
+               alloc->bits[i][j] = log2_frac64(ncwrs64(N, pulses),BITRES);
+               /* FIXME: Could there be a better test for the max number of pulses that fit in 64 bits? */
+               if (alloc->bits[i][j] > (60<<BITRES))
+                  done = 1;
+               /* Add the intra-frame prediction bits */
+               if (eBands[i] >= m->pitchEnd)
+               {
+                  int max_pos = 2*eBands[i]-eBands[i+1];
+                  if (max_pos > 32)
+                     max_pos = 32;
+                  alloc->bits[i][j] += (1<<BITRES) + log2_frac(max_pos,BITRES);
+               }
             }
-            /* We could just update rev_bits here */
             if (done)
                break;
          }
index fa24621..d097489 100644 (file)
@@ -66,9 +66,9 @@ int main(int argc, char *argv[])
    }
    
    bytes_per_packet = atoi(argv[2]);
-   if (bytes_per_packet < 20 || bytes_per_packet > 120)
+   if (bytes_per_packet < 15 || bytes_per_packet > 120)
    {
-      fprintf (stderr, "bytes per packet must be between 20 and 120\n");
+      fprintf (stderr, "bytes per packet must be between 15 and 120\n");
       return 1;
    }
    inFile = argv[3];
index 0c3406c..f22e528 100644 (file)
@@ -372,3 +372,22 @@ void intra_unquant(float *x, int N, int K, float *Y, float *P, int B, int N0, ec
          x[j] = P[j];
    }
 }
+
+void intra_fold(float *x, int N, int K, float *Y, float *P, int B, int N0)
+{
+   int j;
+   float E;
+   
+   E = 1e-10;
+   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++)
+      P[j] *= E;
+   for (j=0;j<N;j++)
+      x[j] = P[j];
+}
+
index 56e0000..29751a5 100644 (file)
@@ -75,4 +75,6 @@ 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);
+
 #endif /* VQ_H */