Improved quality of small frame sizes at low bitrate.
authorJean-Marc Valin <jean-marc.valin@octasic.com>
Wed, 23 Jun 2010 19:22:54 +0000 (15:22 -0400)
committerJean-Marc Valin <jean-marc.valin@octasic.com>
Wed, 23 Jun 2010 19:22:54 +0000 (15:22 -0400)
Adding a temporal energy floor to prevent extremely small values when there's
only one bin in the band.

libcelt/celt.c
libcelt/quant_bands.c
libcelt/quant_bands.h

index 68dd604..db44644 100644 (file)
@@ -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;
index d3fcb30..52340db 100644 (file)
@@ -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);
index 7584357..68cccd9 100644 (file)
@@ -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);