ref: a01106587cc06b6af7ec12c028f293558997f147
parent: 281c8b7e9988f4ffd077b16110c1ad2d3bdebf84
author: Jean-Marc Valin <[email protected]>
date: Wed Jun 23 11:22:54 EDT 2010
Improved quality of small frame sizes at low bitrate. Adding a temporal energy floor to prevent extremely small values when there's only one bin in the band.
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -717,6 +717,7 @@
int LM, M;
int tf_select;
celt_int32 vbr_rate=0;
+ celt_word16 max_decay;
int nbFilledBytes, nbAvailableBytes;
SAVE_STACK;
@@ -952,7 +953,13 @@
/* 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;
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -84,7 +84,7 @@
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 @@
/* 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);
--- a/libcelt/quant_bands.h
+++ b/libcelt/quant_bands.h
@@ -56,7 +56,7 @@
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);