Fixed potential overflow in gradient computation. Need to make sure it really
can't happen anymore.
git-svn-id: http://svn.xiph.org/trunk/speex@12066 0101bb08-14d6-0310-b084-bc0e0c8e3800
diff --git a/libspeex/mdf.c b/libspeex/mdf.c
index 611cc45..b689f8d 100644
--- a/libspeex/mdf.c
+++ b/libspeex/mdf.c
@@ -262,16 +262,20 @@
#endif
/** Compute weighted cross-power spectrum of a half-complex (packed) vector with conjugate */
-static inline void weighted_spectral_mul_conj(const spx_float_t *w, const spx_word16_t *X, const spx_word16_t *Y, spx_word32_t *prod, int N)
+static inline void weighted_spectral_mul_conj(const spx_float_t *w, const spx_float_t p, const spx_word16_t *X, const spx_word16_t *Y, spx_word32_t *prod, int N)
{
int i, j;
- prod[0] = FLOAT_MUL32(w[0],MULT16_16(X[0],Y[0]));
+ spx_float_t W;
+ W = FLOAT_AMULT(p, w[0]);
+ prod[0] = FLOAT_MUL32(W,MULT16_16(X[0],Y[0]));
for (i=1,j=1;i<N-1;i+=2,j++)
{
- prod[i] = FLOAT_MUL32(w[j],MAC16_16(MULT16_16(X[i],Y[i]), X[i+1],Y[i+1]));
- prod[i+1] = FLOAT_MUL32(w[j],MAC16_16(MULT16_16(-X[i+1],Y[i]), X[i],Y[i+1]));
+ W = FLOAT_AMULT(p, w[j]);
+ prod[i] = FLOAT_MUL32(W,MAC16_16(MULT16_16(X[i],Y[i]), X[i+1],Y[i+1]));
+ prod[i+1] = FLOAT_MUL32(W,MAC16_16(MULT16_16(-X[i+1],Y[i]), X[i],Y[i+1]));
}
- prod[i] = FLOAT_MUL32(w[j],MULT16_16(X[i],Y[i]));
+ W = FLOAT_AMULT(p, w[j]);
+ prod[i] = FLOAT_MUL32(W,MULT16_16(X[i],Y[i]));
}
@@ -580,11 +584,11 @@
{
for (j=M-1;j>=0;j--)
{
- weighted_spectral_mul_conj(st->power_1, &st->X[(j+1)*N], st->E, st->PHI, N);
+ weighted_spectral_mul_conj(st->power_1, FLOAT_SHL(PSEUDOFLOAT(st->prop[j]),-15), &st->X[(j+1)*N], st->E, st->PHI, N);
for (i=0;i<N;i++)
- st->W[j*N+i] += MULT16_32_Q15(st->prop[j], st->PHI[i]);
+ st->W[j*N+i] = ADD32(st->W[j*N+i], st->PHI[i]);
- }
+ }
}
st->saturated = 0;
diff --git a/libspeex/pseudofloat.h b/libspeex/pseudofloat.h
index 6b75245..7b7f98c 100644
--- a/libspeex/pseudofloat.h
+++ b/libspeex/pseudofloat.h
@@ -205,6 +205,14 @@
return r;
}
+static inline spx_float_t FLOAT_AMULT(spx_float_t a, spx_float_t b)
+{
+ spx_float_t r;
+ r.m = (spx_int16_t)((spx_int32_t)(a).m*(b).m>>15);
+ r.e = (a).e+(b).e+15;
+ return r;
+}
+
static inline spx_float_t FLOAT_SHL(spx_float_t a, int b)
{
@@ -368,6 +376,7 @@
#define FLOAT_HALF 0.5f
#define PSEUDOFLOAT(x) (x)
#define FLOAT_MULT(a,b) ((a)*(b))
+#define FLOAT_AMULT(a,b) ((a)*(b))
#define FLOAT_MUL32(a,b) ((a)*(b))
#define FLOAT_DIV32(a,b) ((a)/(b))
#define FLOAT_EXTRACT16(a) (a)