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)