diff --git a/libcelt/celt.c b/libcelt/celt.c index 68dd6041..db446442 100644 --- a/libcelt/celt.c +++ b/libcelt/celt.c @@ -717,6 +717,7 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c int LM, M; int tf_select; celt_int32 vbr_rate=0; + celt_word16 max_decay; int nbFilledBytes, nbAvailableBytes; SAVE_STACK; @@ -952,7 +953,13 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c /* Bit allocation */ ALLOC(error, C*st->mode->nbEBands, celt_word16); - coarse_needed = quant_coarse_energy(st->mode, st->start, bandLogE, st->oldBandE, nbAvailableBytes*4-8, intra_ener, st->mode->prob, error, enc, C); + +#ifdef FIXED_POINT + max_decay = MIN32(QCONST16(16,DB_SHIFT), SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3)); +#else + max_decay = .125*nbAvailableBytes; +#endif + coarse_needed = quant_coarse_energy(st->mode, st->start, bandLogE, st->oldBandE, nbAvailableBytes*4-8, intra_ener, st->mode->prob, error, enc, C, max_decay); coarse_needed = ((coarse_needed*3-1)>>3)+1; if (coarse_needed > nbAvailableBytes) coarse_needed = nbAvailableBytes; diff --git a/libcelt/quant_bands.c b/libcelt/quant_bands.c index d3fcb300..52340db1 100644 --- a/libcelt/quant_bands.c +++ b/libcelt/quant_bands.c @@ -84,7 +84,7 @@ void quant_prob_free(int *freq) celt_free(freq); } -unsigned quant_coarse_energy(const CELTMode *m, int start, celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C) +unsigned quant_coarse_energy(const CELTMode *m, int start, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay) { int i, c; unsigned bits_used = 0; @@ -121,6 +121,12 @@ unsigned quant_coarse_energy(const CELTMode *m, int start, celt_word16 *eBands, /* Rounding to nearest integer here is really important! */ qi = (int)floor(.5f+f); #endif + if (qi < 0 && x < oldEBands[i+c*m->nbEBands]-max_decay) + { + qi += SHR16(oldEBands[i+c*m->nbEBands]-max_decay-x, DB_SHIFT); + if (qi > 0) + qi = 0; + } /* If we don't have enough bits to encode all the energy, just assume something safe. We allow slightly busting the budget here */ bits_used=ec_enc_tell(enc, 0); diff --git a/libcelt/quant_bands.h b/libcelt/quant_bands.h index 75843570..68cccd96 100644 --- a/libcelt/quant_bands.h +++ b/libcelt/quant_bands.h @@ -56,7 +56,7 @@ void compute_fine_allocation(const CELTMode *m, int *bits, int budget); int intra_decision(celt_word16 *eBands, celt_word16 *oldEBands, int len); -unsigned quant_coarse_energy(const CELTMode *m, int start, celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C); +unsigned quant_coarse_energy(const CELTMode *m, int start, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay); void quant_fine_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, ec_enc *enc, int _C);