Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/celt.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>2010-11-07 05:02:32 +0300
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>2010-11-07 05:02:32 +0300
commit1ad93cf485b344abc9f8c67e4120fdb29536ea03 (patch)
tree11bf7230e9e5e2db0fa36ebc5d4cd5964d9254b9
parente53c4bc59bdfb69299371c75ccd743d05dd147ae (diff)
Fixes several fixed-point overflows in the PLC code
-rw-r--r--libcelt/celt.c11
-rw-r--r--libcelt/mathops.c7
-rw-r--r--libcelt/plc.c2
3 files changed, 12 insertions, 8 deletions
diff --git a/libcelt/celt.c b/libcelt/celt.c
index fe92075..450bde5 100644
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -1458,13 +1458,15 @@ static void celt_decode_lost(CELTDecoder * restrict st, celt_word16 * restrict p
/* Copy excitation, taking decay into account */
for (i=0;i<len+st->mode->overlap;i++)
{
+ celt_word16 tmp;
if (offset+i >= MAX_PERIOD)
{
offset -= pitch_index;
decay = MULT16_16_Q15(decay, decay);
}
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++)
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;
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 */
#ifdef FIXED_POINT
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));
for (i=0;i<len+overlap;i++)
- e[i] = MULT16_16_Q15(ratio, e[i]);
+ e[i] = MULT16_32_Q15(ratio, e[i]);
}
}
diff --git a/libcelt/mathops.c b/libcelt/mathops.c
index 1dca101..494649e 100644
--- a/libcelt/mathops.c
+++ b/libcelt/mathops.c
@@ -74,10 +74,9 @@ celt_word32 frac_div32(celt_word32 a, celt_word32 b)
{
celt_word16 rcp;
celt_word32 result, rem;
- int shift = 29-celt_ilog2(b);
- a = SHL32(a,shift);
- b = SHL32(b,shift);
-
+ int shift = celt_ilog2(b)-29;
+ a = VSHR32(a,shift);
+ b = VSHR32(b,shift);
/* 16-bit reciprocal */
rcp = ROUND16(celt_rcp(ROUND16(b,16)),3);
result = SHL32(MULT16_32_Q15(rcp, a),2);
diff --git a/libcelt/plc.c b/libcelt/plc.c
index cadad2b..b93fd6a 100644
--- a/libcelt/plc.c
+++ b/libcelt/plc.c
@@ -172,7 +172,7 @@ void _celt_autocorr(
ac0 += SHR32(MULT16_16(xx[i],xx[i]),8);
ac0 += 1+n;
- shift = celt_ilog2(ac0)-30+8;
+ shift = celt_ilog2(ac0)-30+9;
shift = (shift+1)/2;
for(i=0;i<n;i++)
xx[i] = VSHR32(xx[i], shift);