mirror of
https://github.com/xiph/opus.git
synced 2025-05-29 14:49:14 +00:00
Fixes some overflows in the fixed-point pitch code
The overflows reported were: - Syy in find_best_pitch() in pitch.c - xy, xx and yy in remove_doubling() in pitch.c The fixes are: - Adaptive scaling in pitch_downsample() which also improves quality - Adding a missing downshift in find_best_pitch() - More conservative yshift when calling find_best_pitch()
This commit is contained in:
parent
cd539dfdcd
commit
178758b81a
2 changed files with 26 additions and 6 deletions
|
@ -128,6 +128,17 @@ static inline opus_val16 celt_maxabs16(opus_val16 *x, int len)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef OVERRIDE_CELT_MAXABS32
|
||||
static inline opus_val32 celt_maxabs32(opus_val32 *x, int len)
|
||||
{
|
||||
int i;
|
||||
opus_val32 maxval = 0;
|
||||
for (i=0;i<len;i++)
|
||||
maxval = MAX32(maxval, ABS32(x[i]));
|
||||
return maxval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Integer log in base2. Defined for zero, but not for negative numbers */
|
||||
static inline opus_int16 celt_zlog2(opus_val32 x)
|
||||
{
|
||||
|
|
21
celt/pitch.c
21
celt/pitch.c
|
@ -66,7 +66,7 @@ static void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len,
|
|||
best_pitch[0] = 0;
|
||||
best_pitch[1] = 1;
|
||||
for (j=0;j<len;j++)
|
||||
Syy = MAC16_16(Syy, y[j],y[j]);
|
||||
Syy = ADD32(Syy, SHR32(MULT16_16(y[j],y[j]), yshift));
|
||||
for (i=0;i<max_pitch;i++)
|
||||
{
|
||||
if (xcorr[i]>0)
|
||||
|
@ -104,14 +104,23 @@ void pitch_downsample(celt_sig * restrict x[], opus_val16 * restrict x_lp,
|
|||
opus_val32 ac[5];
|
||||
opus_val16 tmp=Q15ONE;
|
||||
opus_val16 lpc[4], mem[4]={0,0,0,0};
|
||||
#ifdef FIXED_POINT
|
||||
int shift;
|
||||
opus_val32 maxabs = celt_maxabs32(x[0], len);
|
||||
if (C==2)
|
||||
maxabs = MAX32(maxabs, celt_maxabs32(x[1], len));
|
||||
shift = IMAX(0,celt_ilog2(maxabs)-11);
|
||||
if (C==2)
|
||||
shift++;
|
||||
#endif
|
||||
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+3);
|
||||
x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), SIG_SHIFT+3);
|
||||
x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), shift);
|
||||
x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), shift);
|
||||
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+3);
|
||||
x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), SIG_SHIFT+3);
|
||||
x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), shift);
|
||||
x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), shift);
|
||||
}
|
||||
|
||||
_celt_autocorr(x_lp, ac, NULL, 0,
|
||||
|
@ -231,7 +240,7 @@ void pitch_search(const opus_val16 * restrict x_lp, opus_val16 * restrict y,
|
|||
}
|
||||
find_best_pitch(xcorr, y, len>>1, max_pitch>>1, best_pitch
|
||||
#ifdef FIXED_POINT
|
||||
, shift, maxcorr
|
||||
, shift+1, maxcorr
|
||||
#endif
|
||||
);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue