ref: 66c5ab4f070335ec03f80337761f613851139237
parent: 405e6a99e3131a7b6e79065bd2f95870b3333246
author: Timothy B. Terriberry <[email protected]>
date: Thu Dec 16 03:39:37 EST 2010
Rebalance N=1 allocations during interp_bits2pulses(). Excess fractions of a bit can't be re-used in N=1 bands during quant_all_bands() because there's no shape, only a sign bit. This meant that all the fractional bits in these bands accumulated, often up to 5 or 6 bits for stereo, until the first band with N>1, where they were dumped all at once. This patch moves the rebalancing for N=1 bands to interp_bits2pulses() instead, where excess bits still have a chance to be moved into fine energy.
--- a/libcelt/rate.c
+++ b/libcelt/rate.c
@@ -153,6 +153,7 @@
int alloc_floor;
int left, percoeff;
int done;
+ int balance;
SAVE_STACK;
alloc_floor = C<<BITRES;
@@ -275,6 +276,8 @@
}
}
/*for (j=0;j<end;j++)printf("%d ", bits[j]);printf("\n");*/
+
+ balance = 0;
for (j=start;j<codedBands;j++)
{
int N0, N, den;
@@ -284,44 +287,58 @@
celt_assert(bits[j] >= 0);
N0 = m->eBands[j+1]-m->eBands[j];
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));
+ if (N>1)
+ {
+ NClogN = N*C*(m->logN[j] + logM);
- /* 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;
+ /* Compensate for the extra DoF in stereo */
+ den=(C*N+ ((C==2 && N>2) ? 1 : 0));
- /* N=2 is the only point that doesn't match the curve */
- if (N==2)
- offset += N*C<<BITRES>>2;
+ /* 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;
- /* Changing the offset for allocating the second and third fine energy bit */
- if (bits[j] + offset < den*2<<BITRES)
- offset += NClogN>>2;
- else if (bits[j] + offset < den*3<<BITRES)
- offset += NClogN>>3;
+ /* N=2 is the only point that doesn't match the curve */
+ if (N==2)
+ offset += N*C<<BITRES>>2;
- /* Divide with rounding */
- ebits[j] = IMAX(0, (bits[j] + offset + (den<<(BITRES-1))) / (den<<BITRES));
+ /* Changing the offset for allocating the second and third
+ fine energy bit */
+ if (bits[j] + offset < den*2<<BITRES)
+ offset += NClogN>>2;
+ else if (bits[j] + offset < den*3<<BITRES)
+ offset += NClogN>>3;
- /* If we rounded down, make it a candidate for final fine energy pass */
- fine_priority[j] = ebits[j]*(den<<BITRES) >= bits[j]+offset;
+ /* Divide with rounding */
+ ebits[j] = IMAX(0, (bits[j] + offset + (den<<(BITRES-1))) / (den<<BITRES));
- /* For N=1, all bits go to fine energy except for a single sign bit */
- if (N==1)
- {
- ebits[j] = IMAX(0,(bits[j]/C >> BITRES)-1);
- fine_priority[j] = (ebits[j]+1)*C<<BITRES >= bits[j];
- }
- /* Make sure not to bust */
- if (C*ebits[j] > (bits[j]>>BITRES))
- ebits[j] = bits[j]/C >> BITRES;
+ /* If we rounded down, make it a candidate for final
+ fine energy pass */
+ fine_priority[j] = ebits[j]*(den<<BITRES) >= bits[j]+offset;
- /* More than that is useless because that's about as far as PVQ can go */
- if (ebits[j]>7)
- ebits[j]=7;
+ /* Make sure not to bust */
+ if (C*ebits[j] > (bits[j]>>BITRES))
+ ebits[j] = bits[j]/C >> BITRES;
+
+ /* More than 7 is useless because that's about as far as PVQ can go */
+ if (ebits[j]>7)
+ ebits[j]=7;
+
+ } else {
+ /* For N=1, all bits go to fine energy except for a single sign bit */
+ ebits[j] = IMIN(IMAX(0,(bits[j]/C >> BITRES)-1),7);
+ fine_priority[j] = (ebits[j]+1)*C<<BITRES >= (bits[j]-balance);
+ /* N=1 bands can't take advantage of the re-balancing in
+ quant_all_bands() because they don't have shape, only fine energy.
+ Instead, do the re-balancing here.*/
+ balance = IMAX(0,bits[j] - ((ebits[j]+1)*C<<BITRES));
+ if (j+1<codedBands)
+ {
+ bits[j] -= balance;
+ bits[j+1] += balance;
+ }
+ }
/* The other bits are assigned to PVQ */
bits[j] -= C*ebits[j]<<BITRES;