shithub: opus

Download patch

ref: 5c0c936d8f8ca65a44150f90ae0c583650ccb019
parent: f1c8fb106711362527442b897ce56bc176eb1211
author: Jean-Marc Valin <[email protected]>
date: Tue Aug 31 06:11:11 EDT 2010

Fine energy allocation cleanup

--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -839,7 +839,7 @@
    for (i=0;i<st->mode->nbEBands;i++)
       offsets[i] = 0;
    bits = nbCompressedBytes*8 - ec_enc_tell(enc, 0) - 1;
-   compute_allocation(st->mode, st->start, st->end, offsets, bits, pulses, fine_quant, fine_priority, C, M);
+   compute_allocation(st->mode, st->start, st->end, offsets, bits, pulses, fine_quant, fine_priority, C, LM);
 
    quant_fine_energy(st->mode, st->start, st->end, bandE, oldBandE, error, fine_quant, enc, C);
 
@@ -1509,7 +1509,7 @@
 
    bits = len*8 - ec_dec_tell(dec, 0) - 1;
    ALLOC(fine_quant, st->mode->nbEBands, int);
-   compute_allocation(st->mode, st->start, st->end, offsets, bits, pulses, fine_quant, fine_priority, C, M);
+   compute_allocation(st->mode, st->start, st->end, offsets, bits, pulses, fine_quant, fine_priority, C, LM);
    /*bits = ec_dec_tell(dec, 0);
    compute_fine_allocation(st->mode, fine_quant, (20*C+len*8/5-(ec_dec_tell(dec, 0)-bits))/C);*/
    
--- a/libcelt/rate.c
+++ b/libcelt/rate.c
@@ -136,7 +136,7 @@
 
 
 
-static inline void interp_bits2pulses(const CELTMode *m, int start, int end, int *bits1, int *bits2, int total, int *bits, int *ebits, int *fine_priority, int len, int _C, int M)
+static inline void interp_bits2pulses(const CELTMode *m, int start, int end, int *bits1, int *bits2, int total, int *bits, int *ebits, int *fine_priority, int len, int _C, int LM)
 {
    int psum;
    int lo, hi;
@@ -145,7 +145,7 @@
    const int C = CHANNELS(_C);
    SAVE_STACK;
 
-   logM = log2_frac(M, BITRES);
+   logM = LM<<BITRES;
    lo = 0;
    hi = 1<<BITRES;
    while (hi-lo != 1)
@@ -181,13 +181,18 @@
    {
       int N0, N, den;
       int offset;
+      int NClogN;
+
       N0 = m->eBands[j+1]-m->eBands[j];
-      N=M*N0;
+      N=N0<<LM;
+      NClogN = N*C*(m->logN[j] + logM);
+
       /* Compensate for the extra DoF in stereo */
       den=(C*N+ ((C==2 && N>2) ? 1 : 0));
 
-      /* Offset for the number of fine bits compared to their "fair share" of total/N */
-      offset = N*C*(((m->logN[j] + logM)>>1)-FINE_OFFSET);
+      /* Offset for the number of fine bits by log2(N)/2 + FINE_OFFSET
+         compared to their "fair share" of total/N */
+      offset = (NClogN>>1)-N*C*FINE_OFFSET;
 
       /* N=2 is the only point that doesn't match the curve */
       if (N==2)
@@ -195,10 +200,11 @@
 
       /* Changing the offset for allocating the second and third fine energy bit */
       if (bits[j] + offset < den*2<<BITRES)
-         offset += (m->logN[j] + logM)*N*C>>2;
+         offset += NClogN>>2;
       else if (bits[j] + offset < den*3<<BITRES)
-         offset += (m->logN[j] + logM)*N*C>>3;
+         offset += NClogN>>3;
 
+      /* Divide with rounding */
       ebits[j] = (bits[j] + offset + (den<<(BITRES-1))) / (den<<BITRES);
 
       /* If we rounded down, make it a candidate for final fine energy pass */
@@ -215,12 +221,11 @@
       if (C*ebits[j] > (bits[j]>>BITRES))
          ebits[j] = bits[j]/C >> BITRES;
 
+      /* More than that is useless because that's about as far as PVQ can go */
       if (ebits[j]>7)
          ebits[j]=7;
-      if (ebits[j]<0)
-         ebits[j]=0;
 
-      /* The bits used for fine allocation can't be used for pulses */
+      /* The other bits are assigned to PVQ */
       bits[j] -= C*ebits[j]<<BITRES;
       if (bits[j] < 0)
          bits[j] = 0;
@@ -228,7 +233,7 @@
    RESTORE_STACK;
 }
 
-void compute_allocation(const CELTMode *m, int start, int end, int *offsets, int total, int *pulses, int *ebits, int *fine_priority, int _C, int M)
+void compute_allocation(const CELTMode *m, int start, int end, int *offsets, int total, int *pulses, int *ebits, int *fine_priority, int _C, int LM)
 {
    int lo, hi, len, j;
    const int C = CHANNELS(_C);
@@ -249,7 +254,7 @@
       for (j=start;j<end;j++)
       {
          int N = m->eBands[j+1]-m->eBands[j];
-         bits1[j] = (C*M*N*m->allocVectors[mid*len+j] + offsets[j]);
+         bits1[j] = ((C*N*m->allocVectors[mid*len+j]<<LM) + offsets[j]);
          if (bits1[j] < 0)
             bits1[j] = 0;
          psum += bits1[j];
@@ -266,14 +271,14 @@
    for (j=start;j<end;j++)
    {
       int N = m->eBands[j+1]-m->eBands[j];
-      bits1[j] = C*M*N*m->allocVectors[lo*len+j] + offsets[j];
-      bits2[j] = C*M*N*m->allocVectors[hi*len+j] + offsets[j];
+      bits1[j] = (C*N*m->allocVectors[lo*len+j]<<LM) + offsets[j];
+      bits2[j] = (C*N*m->allocVectors[hi*len+j]<<LM) + offsets[j];
       if (bits1[j] < 0)
          bits1[j] = 0;
       if (bits2[j] < 0)
          bits2[j] = 0;
    }
-   interp_bits2pulses(m, start, end, bits1, bits2, total, pulses, ebits, fine_priority, len, C, M);
+   interp_bits2pulses(m, start, end, bits1, bits2, total, pulses, ebits, fine_priority, len, C, LM);
    RESTORE_STACK;
 }
 
--- a/libcelt/rate.h
+++ b/libcelt/rate.h
@@ -104,7 +104,7 @@
  @param pulses Number of pulses per band (returned)
  @return Total number of bits allocated
 */
-void compute_allocation(const CELTMode *m, int start, int end, int *offsets, int total, int *pulses, int *ebits, int *fine_priority, int _C, int M);
+void compute_allocation(const CELTMode *m, int start, int end, int *offsets, int total, int *pulses, int *ebits, int *fine_priority, int _C, int LM);
 
 
 #endif