Implemented a cleaner way to detect whether CWRS codebooks fit in 32 or 64 bits
authorJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Tue, 10 Jun 2008 06:25:45 +0000 (16:25 +1000)
committerJean-Marc Valin <Jean-Marc.Valin@csiro.au>
Tue, 10 Jun 2008 06:25:45 +0000 (16:25 +1000)
libcelt/cwrs.c
libcelt/cwrs.h
libcelt/rate.c
libcelt/testcelt.c

index c678578..0158b67 100644 (file)
 #include "cwrs.h"
 #include "mathops.h"
 
+int fits_in32(int _n, int _m)
+{
+   static const celt_int16_t maxN[15] = {
+      255, 255, 255, 255, 255, 238,  95,  53,
+       36,  27,  22,  18,  16,  15,  13};
+   static const celt_int16_t maxM[28] = {
+      255, 255, 255, 255, 255, 109,  60,  40,
+       29,  24,  20,  18,  16,  14,  13};
+   if (_n>=14)
+   {
+      if (_m>=14)
+         return 0;
+      else
+         return _n <= maxN[_m];
+   } else {
+      return _m <= maxM[_n];
+   }   
+}
+int fits_in64(int _n, int _m)
+{
+   static const celt_int16_t maxN[28] = {
+      255, 255, 255, 255, 255, 255, 255, 255, 
+      255, 255, 245, 166, 122,  94,  77,  64, 
+       56,  49,  44,  40,  37,  34,  32,  30,
+       29,  27,  26,  25};
+   static const celt_int16_t maxM[28] = {
+      255, 255, 255, 255, 255, 255, 255, 255,
+      255, 255, 178, 129, 100,  81,  68,  58,
+       51,  46,  42,  38,  36,  33,  31,  30,
+       28, 27, 26, 25};
+   if (_n>=27)
+   {
+      if (_m>=27)
+         return 0;
+      else
+         return _n <= maxN[_m];
+   } else {
+      return _m <= maxM[_n];
+   }
+}
+
 /*Computes the next row/column of any recurrence that obeys the relation
    u[i][j]=u[i-1][j]+u[i][j-1]+u[i-1][j-1].
   _ui0 is the base case for the new row/column.*/
@@ -337,7 +378,7 @@ void encode_pulses(int *_y, int N, int K, ec_enc *enc)
 
    pulse2comb(N, K, comb, signs, _y);
    /* Simple heuristic to figure out whether it fits in 32 bits */
-   if((N+4)*(K+4)<250 || (celt_ilog2(N)+1)*K<31)
+   if(fits_in32(N,K))
    {
       encode_comb32(N, K, comb, signs, enc);
    } else {
@@ -371,7 +412,7 @@ void decode_pulses(int *_y, int N, int K, ec_dec *dec)
    ALLOC(comb, K, int);
    ALLOC(signs, K, int);
    /* Simple heuristic to figure out whether it fits in 32 bits */
-   if((N+4)*(K+4)<250 || (celt_ilog2(N)+1)*K<31)
+   if(fits_in32(N,K))
    {
       decode_comb32(N, K, comb, signs, dec);
    } else {
index bbb432f..5585709 100644 (file)
 #include "entenc.h"
 #include "entdec.h"
 
+/* Whether the CWRS codebook will fit into 32 bits */
+int fits_in32(int _n, int _m);
+/* Whether the CWRS codebook will fit into 64 bits */
+int fits_in64(int _n, int _m);
+
 /* 32-bit versions */
 celt_uint32_t ncwrs_u32(int _n,int _m,celt_uint32_t *_u);
 
index dbf2ca4..97546b1 100644 (file)
@@ -44,7 +44,7 @@
 
 #define BITRES 4
 #define BITROUND 8
-#define BITOVERFLOW 10000
+#define BITOVERFLOW 30000
 
 #ifndef STATIC_MODES
 #if 0
@@ -131,11 +131,10 @@ celt_int16_t **compute_alloc_cache(CELTMode *m, int C)
                bits[i][j] = 0;
             else {
                celt_uint64_t nc;
+               if (!fits_in64(N, pulses))
+                  break;
                nc=pulses?ncwrs_unext64(N, u):ncwrs_u64(N, 0, u);
                bits[i][j] = log2_frac64(nc,BITRES);
-               /* FIXME: Could there be a better test for the max number of pulses that fit in 64 bits? */
-               if (bits[i][j] > (60<<BITRES))
-                  done = 1;
                /* Add the intra-frame prediction sign bit */
                if (eBands[i] >= m->pitchEnd)
                   bits[i][j] += (1<<BITRES);
index a22be79..6e33a39 100644 (file)
@@ -79,9 +79,9 @@ int main(int argc, char *argv[])
    }
    
    bytes_per_packet = atoi(argv[5]);
-   if (bytes_per_packet < 0 || bytes_per_packet > 120)
+   if (bytes_per_packet < 0 || bytes_per_packet > 200)
    {
-      fprintf (stderr, "bytes per packet must be between 10 and 120\n");
+      fprintf (stderr, "bytes per packet must be between 10 and 200\n");
       return 1;
    }
    inFile = argv[6];