Fix totally broken bit allocation for non-mainstream modes (e.g. powers of two).
authorJean-Marc Valin <jean-marc.valin@octasic.com>
Wed, 1 Dec 2010 21:11:38 +0000 (16:11 -0500)
committerJean-Marc Valin <jean-marc.valin@octasic.com>
Wed, 1 Dec 2010 21:11:38 +0000 (16:11 -0500)
Also, making per-band dynamic allocation less aggressive.

libcelt/celt.c
libcelt/modes.c

index 3c11061..2f2cf3a 100644 (file)
@@ -896,7 +896,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, i
       offsets[i] = 0;
    /* Dynamic allocation code */
    /* Make sure that dynamic allocation can't make us bust the budget */
-   if (nbCompressedBytes > 30 && LM>=1)
+   if (nbCompressedBytes > 50 && LM>=1)
    {
       int t1, t2;
       if (LM <= 1)
index 86f597c..e8665fa 100644 (file)
@@ -215,50 +215,29 @@ static void compute_allocation_table(CELTMode *mode, int res)
       return;
    }
    /* If not the standard mode, interpolate */
-
    /* Compute per-codec-band allocation from per-critical-band matrix */
    for (i=0;i<BITALLOC_SIZE;i++)
    {
-      celt_int32 current = 0;
-      int eband = 0;
-      /* We may be looping over too many bands, but eband will stop being
-         incremented once we reach the last band */
-      for (j=0;j<maxBands;j++)
+      for (j=0;j<mode->nbEBands;j++)
       {
-         int edge, low, high;
-         celt_int32 alloc;
-         alloc = band_allocation[i*maxBands + j]*(mode->eBands[eband+1]-mode->eBands[eband])<<4;
-         low = eband5ms[j]*200;
-         high = eband5ms[j+1]*200;
-         edge = mode->eBands[eband+1]*res;
-         while (edge <= high && eband < mode->nbEBands)
+         int k;
+         for (k=0;k<maxBands;k++)
          {
-            celt_int32 num;
-            int den, bits;
-            int N = (mode->eBands[eband+1]-mode->eBands[eband]);
-            num = alloc * (edge-low);
-            den = high-low;
-            /* Divide with rounding */
-            bits = (2*num+den)/(2*den);
-            allocVectors[i*mode->nbEBands+eband] = (2*(current+bits)+(N<<4))/(2*N<<4);
-            /* Remove the part of the band we just allocated */
-            low = edge;
-            alloc -= bits;
-
-            /* Move to next eband */
-            current = 0;
-            eband++;
-            if (eband < mode->nbEBands)
-               edge = mode->eBands[eband+1]*res;
+            if (400*(celt_int32)eband5ms[k] > mode->eBands[j]*(celt_int32)mode->Fs/mode->shortMdctSize)
+               break;
+         }
+         if (k>mode->nbEBands-1)
+            allocVectors[i*mode->nbEBands+j] = band_allocation[i*maxBands + maxBands-1];
+         else {
+            celt_int32 a0, a1;
+            a1 = mode->eBands[j]*(celt_int32)mode->Fs/mode->shortMdctSize - 400*(celt_int32)eband5ms[k-1];
+            a0 = 400*(celt_int32)eband5ms[k] - mode->eBands[j]*(celt_int32)mode->Fs/mode->shortMdctSize;
+            allocVectors[i*mode->nbEBands+j] = (a0*band_allocation[i*maxBands+k-1]
+                                             + a1*band_allocation[i*maxBands+k])/(a0+a1);
          }
-         current += alloc;
-      }
-      if (eband < mode->nbEBands)
-      {
-         int N = (mode->eBands[eband+1]-mode->eBands[eband]);
-         allocVectors[i*mode->nbEBands+eband] = (2*current+(N<<4))/(2*N<<4);
       }
    }
+
    /*printf ("\n");
    for (i=0;i<BITALLOC_SIZE;i++)
    {