Fixes several fixed-point overflows in the PLC code
This commit is contained in:
parent
e53c4bc59b
commit
1ad93cf485
3 changed files with 12 additions and 8 deletions
|
@ -1458,13 +1458,15 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
|
||||||
/* Copy excitation, taking decay into account */
|
/* Copy excitation, taking decay into account */
|
||||||
for (i=0;i<len+st->mode->overlap;i++)
|
for (i=0;i<len+st->mode->overlap;i++)
|
||||||
{
|
{
|
||||||
|
celt_word16 tmp;
|
||||||
if (offset+i >= MAX_PERIOD)
|
if (offset+i >= MAX_PERIOD)
|
||||||
{
|
{
|
||||||
offset -= pitch_index;
|
offset -= pitch_index;
|
||||||
decay = MULT16_16_Q15(decay, decay);
|
decay = MULT16_16_Q15(decay, decay);
|
||||||
}
|
}
|
||||||
e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
|
e[i] = SHL32(EXTEND32(MULT16_16_Q15(decay, exc[offset+i])), SIG_SHIFT);
|
||||||
S1 += SHR32(MULT16_16(out_mem[c][offset+i],out_mem[c][offset+i]),8);
|
tmp = ROUND16(out_mem[c][offset+i],SIG_SHIFT);
|
||||||
|
S1 += SHR32(MULT16_16(tmp,tmp),8);
|
||||||
}
|
}
|
||||||
for (i=0;i<LPC_ORDER;i++)
|
for (i=0;i<LPC_ORDER;i++)
|
||||||
mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
|
mem[i] = ROUND16(out_mem[c][MAX_PERIOD-1-i], SIG_SHIFT);
|
||||||
|
@ -1475,7 +1477,10 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
|
||||||
{
|
{
|
||||||
celt_word32 S2=0;
|
celt_word32 S2=0;
|
||||||
for (i=0;i<len+overlap;i++)
|
for (i=0;i<len+overlap;i++)
|
||||||
S2 += SHR32(MULT16_16(e[i],e[i]),8);
|
{
|
||||||
|
celt_word16 tmp = ROUND16(e[i],SIG_SHIFT);
|
||||||
|
S2 += SHR32(MULT16_16(tmp,tmp),8);
|
||||||
|
}
|
||||||
/* This checks for an "explosion" in the synthesis */
|
/* This checks for an "explosion" in the synthesis */
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
if (!(S1 > SHR32(S2,2)))
|
if (!(S1 > SHR32(S2,2)))
|
||||||
|
@ -1490,7 +1495,7 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
|
||||||
{
|
{
|
||||||
celt_word16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
|
celt_word16 ratio = celt_sqrt(frac_div32(SHR32(S1,1)+1,S2+1));
|
||||||
for (i=0;i<len+overlap;i++)
|
for (i=0;i<len+overlap;i++)
|
||||||
e[i] = MULT16_16_Q15(ratio, e[i]);
|
e[i] = MULT16_32_Q15(ratio, e[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,10 +74,9 @@ celt_word32 frac_div32(celt_word32 a, celt_word32 b)
|
||||||
{
|
{
|
||||||
celt_word16 rcp;
|
celt_word16 rcp;
|
||||||
celt_word32 result, rem;
|
celt_word32 result, rem;
|
||||||
int shift = 29-celt_ilog2(b);
|
int shift = celt_ilog2(b)-29;
|
||||||
a = SHL32(a,shift);
|
a = VSHR32(a,shift);
|
||||||
b = SHL32(b,shift);
|
b = VSHR32(b,shift);
|
||||||
|
|
||||||
/* 16-bit reciprocal */
|
/* 16-bit reciprocal */
|
||||||
rcp = ROUND16(celt_rcp(ROUND16(b,16)),3);
|
rcp = ROUND16(celt_rcp(ROUND16(b,16)),3);
|
||||||
result = SHL32(MULT16_32_Q15(rcp, a),2);
|
result = SHL32(MULT16_32_Q15(rcp, a),2);
|
||||||
|
|
|
@ -172,7 +172,7 @@ void _celt_autocorr(
|
||||||
ac0 += SHR32(MULT16_16(xx[i],xx[i]),8);
|
ac0 += SHR32(MULT16_16(xx[i],xx[i]),8);
|
||||||
ac0 += 1+n;
|
ac0 += 1+n;
|
||||||
|
|
||||||
shift = celt_ilog2(ac0)-30+8;
|
shift = celt_ilog2(ac0)-30+9;
|
||||||
shift = (shift+1)/2;
|
shift = (shift+1)/2;
|
||||||
for(i=0;i<n;i++)
|
for(i=0;i<n;i++)
|
||||||
xx[i] = VSHR32(xx[i], shift);
|
xx[i] = VSHR32(xx[i], shift);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue