shithub: opus

Download patch

ref: c9cc6d3e346e1bbf6b3f656f314c6099586487b1
parent: cc4d3dda74eea53f1e48a3e7e74aa981fb98216a
author: Jean-Marc Valin <[email protected]>
date: Wed Feb 13 06:37:41 EST 2008

Introducing a (very) crude budget for the energy encoder.

--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -283,7 +283,7 @@
    //for (i=0;i<st->mode->nbEBands;i++)printf("%f ", bandE[i]);printf("\n");
    //for (i=0;i<N*B*C;i++)printf("%f ", X[i]);printf("\n");
 
-   quant_energy(st->mode, bandE, st->oldBandE, &st->enc);
+   quant_energy(st->mode, bandE, st->oldBandE, nbCompressedBytes*8/3, &st->enc);
 
    if (C==2)
    {
@@ -556,7 +556,7 @@
    ec_dec_init(&dec,&buf);
    
    /* Get band energies */
-   unquant_energy(st->mode, bandE, st->oldBandE, &dec);
+   unquant_energy(st->mode, bandE, st->oldBandE, len*8/3, &dec);
    
    /* Get the pitch gains */
    has_pitch = unquant_pitch(gains, st->mode->nbPBands, &dec);
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -39,14 +39,16 @@
 
 const int frac[24] = {8, 6, 5, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
 
-static void quant_energy_mono(const CELTMode *m, float *eBands, float *oldEBands, ec_enc *enc)
+static void quant_energy_mono(const CELTMode *m, float *eBands, float *oldEBands, int budget, ec_enc *enc)
 {
    int i;
+   int bits;
    float prev = 0;
    float coef = m->ePredCoef;
    float error[m->nbEBands];
    /* The .7 is a heuristic */
    float beta = .7*coef;
+   bits = ec_enc_tell(enc, 0);
    for (i=0;i<m->nbEBands;i++)
    {
       int qi;
@@ -76,10 +78,14 @@
       
       prev = mean+prev+(1-beta)*q;
    }
+   //bits = ec_enc_tell(enc, 0) - bits;
+   //printf ("%d\n", bits);
    for (i=0;i<m->nbEBands;i++)
    {
       int q2;
       float offset = (error[i]+.5)*frac[i];
+      if (ec_enc_tell(enc, 0) - bits +ec_ilog(frac[i])> budget)
+         break;
       q2 = (int)floor(offset);
       if (q2 > frac[i]-1)
          q2 = frac[i]-1;
@@ -87,6 +93,9 @@
       offset = ((q2+.5)/frac[i])-.5;
       oldEBands[i] += 6.*offset;
       //printf ("%f ", error[i] - offset);
+   }
+   for (i=0;i<m->nbEBands;i++)
+   {
       eBands[i] = pow(10, .05*oldEBands[i])-.3;
       if (eBands[i] < 0)
          eBands[i] = 0;
@@ -96,13 +105,15 @@
    //printf ("\n");
 }
 
-static void unquant_energy_mono(const CELTMode *m, float *eBands, float *oldEBands, ec_dec *dec)
+static void unquant_energy_mono(const CELTMode *m, float *eBands, float *oldEBands, int budget, ec_dec *dec)
 {
    int i;
+   int bits;
    float prev = 0;
    float coef = m->ePredCoef;
    /* The .7 is a heuristic */
    float beta = .7*coef;
+   bits = ec_dec_tell(dec, 0);
    for (i=0;i<m->nbEBands;i++)
    {
       int qi;
@@ -121,9 +132,14 @@
    {
       int q2;
       float offset;
+      if (ec_dec_tell(dec, 0) - bits +ec_ilog(frac[i])> budget)
+         break;
       q2 = ec_dec_uint(dec, frac[i]);
       offset = ((q2+.5)/frac[i])-.5;
       oldEBands[i] += 6.*offset;
+   }
+   for (i=0;i<m->nbEBands;i++)
+   {
       //printf ("%f ", error[i] - offset);
       eBands[i] = pow(10, .05*oldEBands[i])-.3;
       if (eBands[i] < 0)
@@ -134,7 +150,7 @@
 
 
 
-void quant_energy(const CELTMode *m, float *eBands, float *oldEBands, ec_enc *enc)
+void quant_energy(const CELTMode *m, float *eBands, float *oldEBands, int budget, ec_enc *enc)
 {
    int C;
    
@@ -141,7 +157,7 @@
    C = m->nbChannels;
 
    if (C==1)
-      quant_energy_mono(m, eBands, oldEBands, enc);
+      quant_energy_mono(m, eBands, oldEBands, budget, enc);
    else 
 #if 1
    {
@@ -152,7 +168,7 @@
          float E[m->nbEBands];
          for (i=0;i<m->nbEBands;i++)
             E[i] = eBands[C*i+c];
-         quant_energy_mono(m, E, oldEBands+c*m->nbEBands, enc);
+         quant_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, enc);
          for (i=0;i<m->nbEBands;i++)
             eBands[C*i+c] = E[i];
       }
@@ -195,13 +211,13 @@
 
 
 
-void unquant_energy(const CELTMode *m, float *eBands, float *oldEBands, ec_dec *dec)
+void unquant_energy(const CELTMode *m, float *eBands, float *oldEBands, int budget, ec_dec *dec)
 {
    int C;   
    C = m->nbChannels;
 
    if (C==1)
-      unquant_energy_mono(m, eBands, oldEBands, dec);
+      unquant_energy_mono(m, eBands, oldEBands, budget, dec);
    else {
       int c;
       for (c=0;c<C;c++)
@@ -208,7 +224,7 @@
       {
          int i;
          float E[m->nbEBands];
-         unquant_energy_mono(m, E, oldEBands+c*m->nbEBands, dec);
+         unquant_energy_mono(m, E, oldEBands+c*m->nbEBands, budget/C, dec);
          for (i=0;i<m->nbEBands;i++)
             eBands[C*i+c] = E[i];
       }
--- a/libcelt/quant_bands.h
+++ b/libcelt/quant_bands.h
@@ -36,8 +36,8 @@
 #include "entenc.h"
 #include "entdec.h"
 
-void quant_energy(const CELTMode *m, float *eBands, float *oldEBands, ec_enc *enc);
+void quant_energy(const CELTMode *m, float *eBands, float *oldEBands, int budget, ec_enc *enc);
 
-void unquant_energy(const CELTMode *m, float *eBands, float *oldEBands, ec_dec *dec);
+void unquant_energy(const CELTMode *m, float *eBands, float *oldEBands, int budget, ec_dec *dec);
 
 #endif /* QUANT_BANDS */
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -118,7 +118,9 @@
             //if (x[j]>0) sign=1; else sign=-1;
             for (sign=-1;sign<=1;sign+=2)
             {
-               /* All pulses at one location must have the same size */
+               /* All pulses at one location must have the same sign. Also,
+                  only consider sign in the same direction as x[j], except for the
+                  last pulses */
                if (iy[m][j]*sign < 0 || (x[j]*sign<0 && pulsesLeft>((K+1)>>1)))
                   continue;
                //fprintf (stderr, "%d/%d %d/%d %d/%d\n", i, K, m, L2, j, N);