ref: 495114b755d157f45a48bb8304d9d7f2f9f2bd91
parent: 6ec2ca56cf92418734e6b4029de2202eac73c2a9
author: Jean-Marc Valin <[email protected]>
date: Mon Jan 24 10:53:17 EST 2011
Moving energy floor to coarse quantization By moving the energy floor to the encoder, we can use a different floor for prediction than for the decay level. Also, the fixed-point dynamic range has been increased to avoid overflows when a fixed-point decoder is used on a stream encoded in floating-point.
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -1379,11 +1379,6 @@
st->prefilter_gain = gain1;
st->prefilter_tapset = prefilter_tapset;
- /* Clamp the band energy used for prediction */
- for (i=0;i<C*st->mode->nbEBands;i++)
- if (oldBandE[i] < -QCONST16(28.f,DB_SHIFT))
- oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
-
/* In case start or end were to change */
c=0; do
{
@@ -2185,11 +2180,6 @@
st->postfilter_gain = postfilter_gain;
st->postfilter_tapset = postfilter_tapset;
#endif /* ENABLE_POSTFILTER */
-
- /* Clamp the band energy used for prediction */
- for (i=0;i<C*st->mode->nbEBands;i++)
- if (oldBandE[i] < -QCONST16(28.f,DB_SHIFT))
- oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
/* In case start or end were to change */
c=0; do
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -188,22 +188,28 @@
int qi, qi0;
celt_word16 q;
celt_word16 x;
- celt_word32 f;
+ celt_word32 f, tmp;
+ celt_word16 oldE;
+ celt_word16 decay_bound;
x = eBands[i+c*m->nbEBands];
+ oldE = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]);
#ifdef FIXED_POINT
- f = SHL32(EXTEND32(x),15) -MULT16_16(coef,oldEBands[i+c*m->nbEBands])-prev[c];
+ f = SHL32(EXTEND32(x),7) - PSHR32(MULT16_16(coef,oldE), 8) - prev[c];
/* Rounding to nearest integer here is really important! */
- qi = (f+QCONST32(.5,DB_SHIFT+15))>>(DB_SHIFT+15);
+ qi = (f+QCONST32(.5,DB_SHIFT+7))>>(DB_SHIFT+7);
+ decay_bound = EXTRACT16(MAX32(-QCONST16(28.f,DB_SHIFT),
+ SUB32((celt_word32)oldEBands[i+c*m->nbEBands],max_decay)));
#else
- f = x-coef*oldEBands[i+c*m->nbEBands]-prev[c];
+ f = x-coef*oldE-prev[c];
/* Rounding to nearest integer here is really important! */
qi = (int)floor(.5f+f);
+ decay_bound = MAX16(-QCONST16(28.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]) - max_decay;
#endif
/* Prevent the energy from going down too quickly (e.g. for bands
that have just one bin) */
- if (qi < 0 && x < oldEBands[i+c*m->nbEBands]-max_decay)
+ if (qi < 0 && x < decay_bound)
{
- qi += (int)SHR16(oldEBands[i+c*m->nbEBands]-max_decay-x, DB_SHIFT);
+ qi += (int)SHR16(SUB16(decay_bound,x), DB_SHIFT);
if (qi > 0)
qi = 0;
}
@@ -238,12 +244,19 @@
}
else
qi = -1;
- error[i+c*m->nbEBands] = PSHR32(f,15) - SHL16(qi,DB_SHIFT);
+ error[i+c*m->nbEBands] = PSHR32(f,7) - SHL16(qi,DB_SHIFT);
badness += abs(qi0-qi);
q = SHL16(qi,DB_SHIFT);
- oldEBands[i+c*m->nbEBands] = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]) + prev[c] + SHL32(EXTEND32(q),15), 15);
- prev[c] = prev[c] + SHL32(EXTEND32(q),15) - MULT16_16(beta,q);
+ //oldEBands[i+c*m->nbEBands] = PSHR32(MULT16_16(coef,oldE) + prev[c] + SHL32(EXTEND32(q),15), 15);
+ //prev[c] = prev[c] + SHL32(EXTEND32(q),15) - MULT16_16(beta,q);
+ tmp = PSHR32(MULT16_16(coef,oldE),8) + prev[c] + SHL32(EXTEND32(q),7);
+#ifdef FIXED_POINT
+ tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp);
+#endif
+ oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7);
+ prev[c] = prev[c] + SHL32(EXTEND32(q),7) - PSHR32(MULT16_16(beta,q),8);
+
} while (++c < C);
}
return badness;
@@ -441,6 +454,7 @@
do {
int qi;
celt_word16 q;
+ celt_word32 tmp;
tell = ec_dec_tell(dec, 0);
if(budget-tell>=15)
{
@@ -462,8 +476,13 @@
qi = -1;
q = SHL16(qi,DB_SHIFT);
- oldEBands[i+c*m->nbEBands] = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]) + prev[c] + SHL32(EXTEND32(q),15), 15);
- prev[c] = prev[c] + SHL32(EXTEND32(q),15) - MULT16_16(beta,q);
+ oldEBands[i+c*m->nbEBands] = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]);
+ tmp = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]),8) + prev[c] + SHL32(EXTEND32(q),7);
+#ifdef FIXED_POINT
+ tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp);
+#endif
+ oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7);
+ prev[c] = prev[c] + SHL32(EXTEND32(q),7) - PSHR32(MULT16_16(beta,q),8);
} while (++c < C);
}
}