X-Git-Url: http://git.xiph.org/?p=opus.git;a=blobdiff_plain;f=libcelt%2Frate.c;h=58c863e474c3f1597648aa0db5387c9b027e37d2;hp=acb539b2892dac0e2bd717fda99cc5810e72dd5d;hb=665da0ba4ddad2b35a9be0e00e70e318a1d98fdb;hpb=c40addcb043ea33528d4f15e16143c74f3ac4a7d diff --git a/libcelt/rate.c b/libcelt/rate.c index acb539b2..58c863e4 100644 --- a/libcelt/rate.c +++ b/libcelt/rate.c @@ -44,7 +44,15 @@ #include "rate.h" -#ifndef STATIC_MODES +static const unsigned char LOG2_FRAC_TABLE[24]={ + 0, + 8,13, + 16,19,21,23, + 24,26,27,28,29,30,31,32, + 32,33,34,34,35,36,36,37,37 +}; + +#ifdef CUSTOM_MODES /*Determines if V(N,K) fits in a 32-bit unsigned integer. N and K are themselves limited to 15 bits.*/ @@ -69,7 +77,9 @@ static int fits_in32(int _n, int _k) void compute_pulse_cache(CELTMode *m, int LM) { + int C; int i; + int j; int curr=0; int nbEntries=0; int entryN[100], entryK[100], entryI[100]; @@ -77,6 +87,7 @@ void compute_pulse_cache(CELTMode *m, int LM) PulseCache *cache = &m->cache; celt_int16 *cindex; unsigned char *bits; + unsigned char *cap; cindex = celt_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2)); cache->index = cindex; @@ -84,7 +95,6 @@ void compute_pulse_cache(CELTMode *m, int LM) /* Scan for all unique band sizes */ for (i=0;i<=LM+1;i++) { - int j; for (j=0;jnbEBands;j++) { int k; @@ -125,7 +135,6 @@ void compute_pulse_cache(CELTMode *m, int LM) /* Compute the cache for all unique sizes */ for (i=0;icaps = cap = celt_alloc(sizeof(cache->caps[0])*(LM+1)*2*m->nbEBands); + for (i=0;i<=LM;i++) + { + for (C=1;C<=2;C++) + { + int shift; + shift = C+i+BITRES-2; + for (j=0;jnbEBands;j++) + { + int N0; + int max_bits; + int rmask; + N0 = m->eBands[j+1]-m->eBands[j]; + rmask = N0==1 ? (1< 4 && !(N0&1)) + { + N0>>=1; + LM0--; + } + /* N0=1 and N0=2 bands can't be split down to N=2. */ + else if (N0 <= 2) + { + LM0=IMIN(i,3-N0); + N0<<=LM0; + } + /* Compute the cost for the lowest-level PVQ of a fully split + band. */ + pcache = bits + cindex[(LM0+1)*m->nbEBands+j]; + max_bits = pcache[pcache[0]]+1; + /* Add in the cost of coding regular splits. */ + N = N0; + for(k=0;klogN[j]+(LM0+k<>1)-QTHETA_OFFSET; + /* The number of qtheta bits we'll allocate if the remainder + is to be max_bits. */ + num=(celt_int32)((2*N-1)*offset+max_bits)<<9; + den=((celt_int32)(2*N-1)<<9)-495; + qb = IMIN((num+(den>>1))/den, 8<= 0); + /* The average cost for theta when qn==256 is + 7.73246 bits for the triangular PDF. */ + max_bits += qb*495+256>>9; + N <<= 1; + } + /* Add in the cost of a stereo split, if necessary. */ + if (C==2) + { + max_bits <<= 1; + offset = (m->logN[j]+(i<>1)-QTHETA_OFFSET_STEREO; + ndof = 2*N-1-(N==2); + num = (celt_int32)(max_bits+ndof*offset)<<7; + den = ((celt_int32)ndof<<7)-(N==2?128:125); + qb = IMIN((num+(den>>1))/den, 8<= 0); + /* The average cost for theta when qn==256, N>2 is + 7.8174 bits for the step PDF. */ + max_bits += N==2 ? qb : (qb*125+64>>7); + } + /* Add the fine bits we'll use. */ + /* Compensate for the extra DoF in stereo */ + ndof = C*N + ((C==2 && N>2) ? 1 : 0); + /* Offset the number of fine bits by log2(N)/2 + FINE_OFFSET + compared to their "fair share" of total/N */ + offset = (m->logN[j] + (i<>1)-FINE_OFFSET; + /* N=2 is the only point that doesn't match the curve */ + if (N==2) + offset += 1<>2; + /* The number of fine bits we'll allocate if the remainder is + to be max_bits. */ + num = max_bits+ndof*offset; + den = ndof-1<>1))/den, MAX_FINE_BITS); + celt_assert(qb >= 0); + max_bits += C*qb<>shift < 256); + *cap++ = (unsigned char)(max_bits+rmask>>shift); + } + } + } } -#endif /* !STATIC_MODES */ +#endif /* !CUSTOM_MODES */ #define ALLOC_STEPS 6 -static inline int 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) +static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start, + const int *bits1, const int *bits2, const int *thresh, const int *cap, int total, int skip_rsv, + int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits, + int *ebits, int *fine_priority, int _C, int LM, void *ec, int encode, int prev) { int psum; int lo, hi; int i, j; int logM; const int C = CHANNELS(_C); + int stereo; int codedBands=-1; - VARDECL(int, thresh); + int alloc_floor; + int left, percoeff; + int done; + int balance; SAVE_STACK; - ALLOC(thresh, len, int); + alloc_floor = C<1; - /* Threshold: don't allow any band to go below 3/8 bit/sample */ - for (j=start;jeBands[j+1]-m->eBands[j])<>3; logM = LM<>1; psum = 0; - for (j=start;jstart;) { int tmp = bits1[j] + (mid*bits2[j]>>ALLOC_STEPS); - if (tmp >= thresh[j]) - psum += tmp; - else if (tmp >= 1<= thresh[j] || done) + { + done = 1; + /* Don't allocate more than we can actually use */ + psum += IMIN(tmp, cap[j]); + } else { + if (tmp >= alloc_floor) + psum += alloc_floor; + } } - if (psum > (total< total) hi = mid; else lo = mid; } psum = 0; /*printf ("interp bisection gave %d\n", lo);*/ - for (j=start;jstart;) { int tmp = bits1[j] + (lo*bits2[j]>>ALLOC_STEPS); - if (tmp >= thresh[j]) + if (tmp < thresh[j] && !done) { - bits[j] = tmp; - codedBands = j; - } else if (tmp >= 1<= alloc_floor) + tmp = alloc_floor; + else + tmp = 0; + } else + done = 1; + /* Don't allocate more than we can actually use */ + tmp = IMIN(tmp, cap[j]); + bits[j] = tmp; + psum += tmp; + } + + /* Decide which bands to skip, working backwards from the end. */ + for (codedBands=end;;codedBands--) + { + int band_width; + int band_bits; + int rem; + j = codedBands-1; + /* Never skip the first band, nor a band that has been boosted by + dynalloc. + In the first case, we'd be coding a bit to signal we're going to waste + all the other bits. + In the second case, we'd be coding a bit to redistribute all the bits + we just signaled should be cocentrated in this band. */ + if (j<=skip_start) + { + /* Give the bit we reserved to end skipping back. */ + total += skip_rsv; + break; + } + /*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-psum; + percoeff = left/(m->eBands[codedBands]-m->eBands[start]); + left -= (m->eBands[codedBands]-m->eBands[start])*percoeff; + rem = IMAX(left-(m->eBands[j]-m->eBands[start]),0); + band_width = m->eBands[codedBands]-m->eBands[j]; + band_bits = bits[j] + percoeff*band_width + rem; + /*Only code a skip decision if we're above the threshold for this band. + Otherwise it is force-skipped. + This ensures that we have enough bits to code the skip flag.*/ + if (band_bits >= IMAX(thresh[j], alloc_floor+(1< ((j>4) + { + ec_enc_bit_logp((ec_enc *)ec, 1, 1); + break; + } + ec_enc_bit_logp((ec_enc *)ec, 0, 1); + } else if (ec_dec_bit_logp((ec_dec *)ec, 1)) { + break; + } + /*We used a bit to skip this band.*/ + psum += 1< 0) + intensity_rsv = LOG2_FRAC_TABLE[j-start]; + psum += intensity_rsv; + if (band_bits >= alloc_floor) + { + /*If we have enough for a fine energy bit per channel, use it.*/ + psum += alloc_floor; + bits[j] = alloc_floor; + } else { + /*Otherwise this band gets nothing at all.*/ bits[j] = 0; - psum += bits[j]; + } + } + + celt_assert(codedBands > start); + /* Code the intensity and dual stereo parameters. */ + if (intensity_rsv > 0) + { + if (encode) + { + *intensity = IMIN(*intensity, codedBands); + ec_enc_uint((ec_enc *)ec, *intensity-start, codedBands+1-start); + } + else + *intensity = start+ec_dec_uint((ec_dec *)ec, codedBands+1-start); + } + else + *intensity = 0; + if (*intensity <= start) + { + total += dual_stereo_rsv; + dual_stereo_rsv = 0; + } + if (dual_stereo_rsv > 0) + { + if (encode) + ec_enc_bit_logp((ec_enc *)ec, *dual_stereo, 1); + else + *dual_stereo = ec_dec_bit_logp((ec_dec *)ec, 1); } - codedBands++; + else + *dual_stereo = 0; + /* Allocate the remaining bits */ - if (codedBands) { - int left, perband; - left = (total<eBands[codedBands]-m->eBands[start]); + left -= (m->eBands[codedBands]-m->eBands[start])*percoeff; + for (j=start;jeBands[j+1]-m->eBands[j]); + for (j=start;jeBands[j+1]-m->eBands[j]); + bits[j] += tmp; + left -= tmp; } - for (j=start;j= 0); N0 = m->eBands[j+1]-m->eBands[j]; N=N0<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 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) - offset += N*C<>2; - - /* Changing the offset for allocating the second and third fine energy bit */ - if (bits[j] + offset < den*2<>2; - else if (bits[j] + offset < den*3<>3; - - /* Divide with rounding */ - ebits[j] = (bits[j] + offset + (den<<(BITRES-1))) / (den<= bits[j]+offset; - - /* For N=1, all bits go to fine energy except for a single sign bit */ - if (N==1) - ebits[j] = (bits[j]/C >> BITRES)-1; - /* Make sure the first bit is spent on fine energy */ - if (ebits[j] < 1) - ebits[j] = 1; - - /* Make sure not to bust */ - if (C*ebits[j] > (bits[j]>>BITRES)) - ebits[j] = bits[j]/C >> BITRES; + if (N>1) + { + /* Compensate for the extra DoF in stereo */ + den=(C*N+ ((C==2 && N>2) ? 1 : 0)); + + NClogN = den*(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)-den*FINE_OFFSET; + + /* N=2 is the only point that doesn't match the curve */ + if (N==2) + offset += den<>2; + + /* Changing the offset for allocating the second and third + fine energy bit */ + if (bits[j] + offset < den*2<>2; + else if (bits[j] + offset < den*3<>3; + + /* Divide with rounding */ + ebits[j] = IMAX(0, (bits[j] + offset + (den<<(BITRES-1))) / (den< (bits[j]>>BITRES)) + ebits[j] = bits[j] >> stereo >> BITRES; + + /* More than that is useless because that's about as far as PVQ can go */ + ebits[j] = IMIN(ebits[j], MAX_FINE_BITS); + + /* If we rounded down or capped this band, make it a candidate for the + final fine energy pass */ + fine_priority[j] = ebits[j]*(den<= bits[j]+offset; + + } else { + /* For N=1, all bits go to fine energy except for a single sign bit */ + ebits[j] = IMIN(IMAX(0,(bits[j] >> stereo >> BITRES)-1),MAX_FINE_BITS); + fine_priority[j] = (ebits[j]+1)*C<= (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<7) - ebits[j]=7; + /* Sweep any bits over the cap into the first band. + They'll be reallocated by the normal rebalancing code, which gives + them the best chance to be used _somewhere_. */ + { + int tmp = IMAX(bits[j]-cap[j],0); + bits[j] -= tmp; + bits[start] += tmp; + } - /* The other bits are assigned to PVQ */ + /* Remove the allocated fine bits; the other bits are assigned to PVQ */ bits[j] -= C*ebits[j]<= 0); + celt_assert(ebits[j] >= 0); + } + /* The skipped bands use all their bits for fine energy. */ + for (;j> stereo >> BITRES; + celt_assert(C*ebits[j]<nbEBands; + skip_start = start; + /* Reserve a bit to signal the end of manually skipped bands. */ + skip_rsv = total >= 1<total) + intensity_rsv = 0; + else + { + total -= intensity_rsv; + dual_stereo_rsv = total>=1<eBands[j+1]-m->eBands[j])<>3; - for (j=start;jeBands[j+1]-m->eBands[j])*(alloc_trim-3)*(m->nbEBands-j-1) - <<(LM+BITRES)>>5; - - lo = 0; - hi = m->nbAllocVectors - 1; - while (hi-lo != 1) { + /* Below this threshold, we're sure not to allocate any PVQ bits */ + thresh[j] = IMAX((C)<eBands[j+1]-m->eBands[j])<>4); + /* Tilt of the allocation curve */ + trim_offset[j] = C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(m->nbEBands-j-1) + <<(LM+BITRES)>>6; + /* Giving less resolution to single-coefficient bands because they get + more benefit from having one coarse value per coefficient*/ + if ((m->eBands[j+1]-m->eBands[j])<nbAllocVectors - 2; + do + { + int done = 0; int psum = 0; int mid = (lo+hi) >> 1; - for (j=start;jstart;) { int N = m->eBands[j+1]-m->eBands[j]; bits1[j] = C*N*m->allocVectors[mid*len+j]<>2; if (bits1[j] > 0) - bits1[j] += trim_offset[j]; - if (bits1[j] < 0) - bits1[j] = 0; + bits1[j] = IMAX(0, bits1[j] + trim_offset[j]); bits1[j] += offsets[j]; - if (bits1[j] >= thresh[j]) - psum += bits1[j]; - else if (bits1[j] >= 1<= thresh[j] || done) + { + done = 1; + /* Don't allocate more than we can actually use */ + psum += IMIN(bits1[j], cap[j]); + } else { + if (bits1[j] >= C< (total< total) + hi = mid - 1; else - lo = mid; + lo = mid + 1; /*printf ("lo = %d, hi = %d\n", lo, hi);*/ } + while (lo <= hi); + hi = lo--; /*printf ("interp between %d and %d\n", lo, hi);*/ for (j=start;jeBands[j+1]-m->eBands[j]; - bits1[j] = (C*N*m->allocVectors[lo*len+j]<>2); - bits2[j] = (C*N*m->allocVectors[hi*len+j]<>2) - bits1[j]; + bits1[j] = C*N*m->allocVectors[lo*len+j]<>2; + bits2[j] = C*N*m->allocVectors[hi*len+j]<>2; if (bits1[j] > 0) - bits1[j] += trim_offset[j]; - if (bits1[j] < 0) - bits1[j] = 0; - bits1[j] += offsets[j]; + bits1[j] = IMAX(0, bits1[j] + trim_offset[j]); + if (bits2[j] > 0) + bits2[j] = IMAX(0, bits2[j] + trim_offset[j]); + if (lo > 0) + bits1[j] += offsets[j]; + bits2[j] += offsets[j]; + if (offsets[j]>0) + skip_start = j; + bits2[j] -= bits1[j]; } - codedBands = interp_bits2pulses(m, start, end, bits1, bits2, total, pulses, ebits, fine_priority, len, C, LM); + codedBands = interp_bits2pulses(m, start, end, skip_start, bits1, bits2, thresh, cap, + total, skip_rsv, intensity, intensity_rsv, dual_stereo, dual_stereo_rsv, + pulses, ebits, fine_priority, C, LM, ec, encode, prev); RESTORE_STACK; return codedBands; }