shithub: opus

Download patch

ref: 7f1c9427e530afd9274ea381603d2eee44608ad4
parent: 5f633543c722f6aa990d2959f6885f1b175aeff5
author: Jean-Marc Valin <[email protected]>
date: Thu Apr 29 07:24:11 EDT 2010

Allocation table stored with BITRES accuracy based on the short block size

--- a/libcelt/modes.c
+++ b/libcelt/modes.c
@@ -117,16 +117,11 @@
    };
 #endif
 
-static celt_int16 *compute_ebands(celt_int32 Fs, int frame_size, int nbShortMdcts, int *nbEBands)
+static celt_int16 *compute_ebands(celt_int32 Fs, int frame_size, int res, int *nbEBands)
 {
    celt_int16 *eBands;
-   int i, res, min_width, lin, low, high, nBark, offset=0;
+   int i, lin, low, high, nBark, offset=0;
 
-   frame_size /= nbShortMdcts;
-   nbShortMdcts = 1;
-   res = (Fs+frame_size)/(2*frame_size);
-   min_width = res;
-
    /* Find the number of critical bands supported by our sampling rate */
    for (nBark=1;nBark<BARK_BANDS;nBark++)
     if (bark_freq[nBark+1]*2 >= Fs)
@@ -134,7 +129,7 @@
 
    /* Find where the linear part ends (i.e. where the spacing is more than min_width */
    for (lin=0;lin<nBark;lin++)
-      if (bark_freq[lin+1]-bark_freq[lin] >= min_width)
+      if (bark_freq[lin+1]-bark_freq[lin] >= res)
          break;
 
    low = (bark_freq[lin]+res/2)/res;
@@ -180,7 +175,7 @@
    return eBands;
 }
 
-static void compute_allocation_table(CELTMode *mode, int res, int M)
+static void compute_allocation_table(CELTMode *mode, int res)
 {
    int i, j, nBark;
    celt_int16 *allocVectors;
@@ -204,11 +199,11 @@
          int edge, low, high;
          celt_int32 alloc;
 
-         alloc = mode->mdctSize*band_allocation[i*BARK_BANDS+j];
+         alloc = mode->shortMdctSize*band_allocation[i*BARK_BANDS+j];
          low = bark_freq[j];
          high = bark_freq[j+1];
 
-         edge = M*mode->eBands[eband+1]*res;
+         edge = mode->eBands[eband+1]*res;
          while (edge <= high && eband < mode->nbEBands)
          {
             celt_int32 num;
@@ -217,8 +212,11 @@
             den = high-low;
             /* Divide with rounding */
             bits = (2*num+den)/(2*den);
-            allocVectors[i*mode->nbEBands+eband] = (current+bits+128)>>8;
-
+            allocVectors[i*mode->nbEBands+eband] = (current+bits+128)>>(8-BITRES);
+            /* Remove one bit from every band -- FIXME: this is just a temporary hack*/
+            allocVectors[i*mode->nbEBands+eband] -= 1<<BITRES;
+            if (allocVectors[i*mode->nbEBands+eband]<0)
+               allocVectors[i*mode->nbEBands+eband]=0;
             /* Remove the part of the band we just allocated */
             low = edge;
             alloc -= bits;
@@ -226,12 +224,18 @@
             /* Move to next eband */
             current = 0;
             eband++;
-            edge = M*mode->eBands[eband+1]*res;
+            edge = mode->eBands[eband+1]*res;
          }
          current += alloc;
       }
       if (eband < mode->nbEBands)
-         allocVectors[i*mode->nbEBands+eband] = (current+128)>>8;
+      {
+         allocVectors[i*mode->nbEBands+eband] = (current+128)>>(8-BITRES);
+         /* Same hack as above FIXME: again */
+         allocVectors[i*mode->nbEBands+eband] -= 1<<BITRES;
+         if (allocVectors[i*mode->nbEBands+eband]<0)
+            allocVectors[i*mode->nbEBands+eband]=0;
+      }
    }
    mode->allocVectors = allocVectors;
 }
@@ -312,7 +316,6 @@
          *error = CELT_BAD_ARG;
       return NULL;
    }
-   res = (Fs+frame_size)/(2*frame_size);
    
    mode = celt_alloc(sizeof(CELTMode));
    if (mode==NULL)
@@ -348,7 +351,10 @@
      mode->nbShortMdcts = 1;
    }
 
-   mode->eBands = compute_ebands(Fs, frame_size, mode->nbShortMdcts, &mode->nbEBands);
+   mode->shortMdctSize = mode->mdctSize/mode->nbShortMdcts;
+   res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize);
+
+   mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
    if (mode->eBands==NULL)
       goto failure;
 
@@ -360,7 +366,8 @@
    else
       mode->overlap = (frame_size>>3)<<2;
 
-   compute_allocation_table(mode, res, mode->nbShortMdcts);
+
+   compute_allocation_table(mode, res);
    if (mode->allocVectors==NULL)
       goto failure;
    
@@ -392,7 +399,6 @@
 
    clt_mdct_init(&mode->mdct, 2*mode->mdctSize);
 
-   mode->shortMdctSize = mode->mdctSize/mode->nbShortMdcts;
    clt_mdct_init(&mode->shortMdct, 2*mode->shortMdctSize);
 
    mode->prob = quant_prob_alloc(mode);
--- a/libcelt/rate.c
+++ b/libcelt/rate.c
@@ -116,7 +116,7 @@
       int mid = (lo+hi)>>1;
       psum = 0;
       for (j=start;j<len;j++)
-         psum += ((1<<BITRES)-mid)*bits1[j] + mid*bits2[j];
+         psum += (((1<<BITRES)-mid)*bits1[j] + mid*bits2[j])>>BITRES;
       if (psum > (total<<BITRES))
          hi = mid;
       else
@@ -126,7 +126,7 @@
    /*printf ("interp bisection gave %d\n", lo);*/
    for (j=start;j<len;j++)
    {
-      bits[j] = ((1<<BITRES)-lo)*bits1[j] + lo*bits2[j];
+      bits[j] = (((1<<BITRES)-lo)*bits1[j] + lo*bits2[j])>>BITRES;
       psum += bits[j];
    }
    /* Allocate the remaining bits */
@@ -193,7 +193,7 @@
       int mid = (lo+hi) >> 1;
       for (j=start;j<len;j++)
       {
-         bits1[j] = (C*m->allocVectors[mid*len+j] + offsets[j])<<BITRES;
+         bits1[j] = (C*M*m->allocVectors[mid*len+j] + offsets[j]);
          if (bits1[j] < 0)
             bits1[j] = 0;
          psum += bits1[j];
@@ -209,8 +209,8 @@
    /*printf ("interp between %d and %d\n", lo, hi);*/
    for (j=start;j<len;j++)
    {
-      bits1[j] = C*m->allocVectors[lo*len+j] + offsets[j];
-      bits2[j] = C*m->allocVectors[hi*len+j] + offsets[j];
+      bits1[j] = C*M*m->allocVectors[lo*len+j] + offsets[j];
+      bits2[j] = C*M*m->allocVectors[hi*len+j] + offsets[j];
       if (bits1[j] < 0)
          bits1[j] = 0;
       if (bits2[j] < 0)