ref: 79afa9c605fa740d0180d34c5ed526deabccfa15
parent: 02ad779f5f0f09b1e194a8d9cb7c7ce844873663
author: Jean-Marc Valin <[email protected]>
date: Thu Jan 27 05:46:01 EST 2011
Fixes fixed-point overflow on really low energy Makes celt_exp2() use Q10 input to avoid problems on very low energy. Also makes the pitch downsampling more conservative on gain to avoid problems later.
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -231,7 +231,7 @@
depth = (1+pulses[i])/(m->eBands[i+1]-m->eBands[i]<<LM);
#ifdef FIXED_POINT
- thresh = MULT16_32_Q15(QCONST16(0.5f, 15), MIN32(32767,SHR32(celt_exp2(-SHL16(depth, 11-BITRES)),1) ));
+ thresh = MULT16_32_Q15(QCONST16(0.5f, 15), MIN32(32767,SHR32(celt_exp2(-SHL16(depth, 10-BITRES)),1) ));
{
celt_word32 t;
t = N0<<LM;
@@ -254,7 +254,7 @@
#ifdef FIXED_POINT
if (Ediff < 16384)
- r = 2*MIN16(16383,SHR32(celt_exp2(-SHL16(Ediff, 11-DB_SHIFT)),1));
+ r = 2*MIN16(16383,SHR32(celt_exp2(-Ediff),1));
else
r = 0;
if (LM==3)
--- a/libcelt/mathops.h
+++ b/libcelt/mathops.h
@@ -175,17 +175,17 @@
#define D1 22804
#define D2 14819
#define D3 10204
-/** Base-2 exponential approximation (2^x). (Q11 input, Q16 output) */
+/** Base-2 exponential approximation (2^x). (Q10 input, Q16 output) */
static inline celt_word32 celt_exp2(celt_word16 x)
{
int integer;
celt_word16 frac;
- integer = SHR16(x,11);
+ integer = SHR16(x,10);
if (integer>14)
return 0x7f000000;
else if (integer < -15)
return 0;
- frac = SHL16(x-SHL16(integer,11),3);
+ frac = SHL16(x-SHL16(integer,10),4);
frac = ADD16(D0, MULT16_16_Q15(frac, ADD16(D1, MULT16_16_Q15(frac, ADD16(D2 , MULT16_16_Q15(D3,frac))))));
return VSHR32(EXTEND32(frac), -integer-2);
}
--- a/libcelt/pitch.c
+++ b/libcelt/pitch.c
@@ -107,13 +107,13 @@
celt_word16 lpc[4], mem[4]={0,0,0,0};
const int C = CHANNELS(_C);
for (i=1;i<len>>1;i++)
- x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), SIG_SHIFT+2);
- x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), SIG_SHIFT+2);
+ x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), SIG_SHIFT+3);
+ x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), SIG_SHIFT+3);
if (C==2)
{
for (i=1;i<len>>1;i++)
- x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), SIG_SHIFT+2);
- x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), SIG_SHIFT+2);
+ x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), SIG_SHIFT+3);
+ x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), SIG_SHIFT+3);
}
_celt_autocorr(x_lp, ac, NULL, 0,
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -186,7 +186,7 @@
do {
int bits_left;
int qi, qi0;
- celt_word16 q;
+ celt_word32 q;
celt_word16 x;
celt_word32 f, tmp;
celt_word16 oldE;
@@ -246,15 +246,14 @@
qi = -1;
error[i+c*m->nbEBands] = PSHR32(f,7) - SHL16(qi,DB_SHIFT);
badness += abs(qi0-qi);
- q = SHL16(qi,DB_SHIFT);
+ q = SHL32(EXTEND32(qi),DB_SHIFT);
- tmp = PSHR32(MULT16_16(coef,oldE),8) + prev[c] + SHL32(EXTEND32(q),7);
+ tmp = PSHR32(MULT16_16(coef,oldE),8) + prev[c] + SHL32(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);
-
+ prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8));
} while (++c < C);
}
return badness;
@@ -451,7 +450,7 @@
c=0;
do {
int qi;
- celt_word16 q;
+ celt_word32 q;
celt_word32 tmp;
tell = ec_dec_tell(dec, 0);
if(budget-tell>=15)
@@ -472,15 +471,15 @@
}
else
qi = -1;
- q = SHL16(qi,DB_SHIFT);
+ q = SHL32(EXTEND32(qi),DB_SHIFT);
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);
+ tmp = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]),8) + prev[c] + SHL32(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);
+ prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8));
} while (++c < C);
}
}
@@ -549,9 +548,9 @@
eBands[i+c*m->nbEBands] = 0;
for (;i<end;i++)
{
- celt_word16 lg = oldEBands[i+c*m->nbEBands]
- + SHL16((celt_word16)eMeans[i],6);
- eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(SHL16(lg,11-DB_SHIFT)),4);
+ celt_word16 lg = ADD16(oldEBands[i+c*m->nbEBands],
+ SHL16((celt_word16)eMeans[i],6));
+ eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(lg),4);
}
for (;i<m->nbEBands;i++)
eBands[i+c*m->nbEBands] = 0;