diff --git a/libcelt/rate.c b/libcelt/rate.c index 40ada6df..57bfff37 100644 --- a/libcelt/rate.c +++ b/libcelt/rate.c @@ -151,6 +151,10 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, const int C = CHANNELS(_C); int codedBands=-1; int alloc_floor; + int left, percoeff; + int force_skipping; + int unforced_skips; + int done; SAVE_STACK; alloc_floor = C<>1; psum = 0; + done = 0; for (j=start;j>ALLOC_STEPS); /* Don't allocate more than we can actually use */ - if (tmp >= thresh[j]) + if (tmp >= thresh[j] && !done) + { psum += tmp; - else if (tmp >= alloc_floor + (1<= alloc_floor) + psum += alloc_floor; + } } if (psum > (total<>ALLOC_STEPS); - if (tmp < thresh[j]) + if (tmp < thresh[j] || done) { - if (tmp >= alloc_floor + (1<= alloc_floor) + tmp = alloc_floor; else tmp = 0; } @@ -193,47 +204,69 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, bits[j] = tmp; psum += tmp; } - for (j=start;jstart;) { - *skip=0; - for (j=codedBands-1;j>=0;j--) + int band_width; + int band_bits; + int rem; + /*Figure out how many left-over bits we would be adding to this band. + This can include bits we've stolen back from higher, skipped bands.*/ + left = (total<eBands[codedBands]-m->eBands[start]); + left -= (m->eBands[codedBands]-m->eBands[start])*percoeff; + rem = IMAX(left-m->eBands[j],0); + band_width = m->eBands[codedBands]-m->eBands[j]; + band_bits = bits[j] + percoeff*band_width + rem; + /*As long as, even after adding these bits, we're below the threshold for + this band, it is force-skipped.*/ + force_skipping = force_skipping && band_bits < thresh[j]; + if (!force_skipping) { - if ((bits[j] > (7*(m->eBands[j+1]-m->eBands[j])<>4 && j (9*(m->eBands[j+1]-m->eBands[j])<>4)) + /*If we have enough for the fine energy, but not more than a full bit + beyond that, or no more than one bit total, then don't bother + skipping this band: there's no extra bits to redistribute.*/ + if ((band_bits >= alloc_floor && band_bits <= alloc_floor + (1< ((j>4) + break; + } else if(unforced_skips--<=0) + break; + (*skip)++; + /*Use a bit to skip this band.*/ + psum += 1<= alloc_floor + (1<= alloc_floor + (1<eBands[codedBands]-m->eBands[start]); + if (codedBands>start) { for (j=start;jeBands[j+1]-m->eBands[j]); - left = left-(m->eBands[codedBands]-m->eBands[start])*perband; + bits[j] += percoeff*(m->eBands[j+1]-m->eBands[j]); for (j=start;jeBands[j+1]-m->eBands[j]);