[xiph-commits] r11996 - trunk/speex/libspeex

jm at svn.xiph.org jm at svn.xiph.org
Thu Nov 2 06:22:26 PST 2006


Author: jm
Date: 2006-11-02 06:22:24 -0800 (Thu, 02 Nov 2006)
New Revision: 11996

Modified:
   trunk/speex/libspeex/preprocess.c
Log:
linear frequency loop now entirely in fixed-point.


Modified: trunk/speex/libspeex/preprocess.c
===================================================================
--- trunk/speex/libspeex/preprocess.c	2006-11-02 13:24:07 UTC (rev 11995)
+++ trunk/speex/libspeex/preprocess.c	2006-11-02 14:22:24 UTC (rev 11996)
@@ -277,23 +277,24 @@
    which multiplied by xi/(1+xi) is the optimal gain
    in the loudness domain ( sqrt[amplitude] )
 */
-static inline float hypergeom_gain(float x)
+static inline spx_word32_t hypergeom_gain(spx_word32_t xx)
 {
    int ind;
    float integer, frac;
+   float x;
    static const float table[21] = {
       0.82157f, 1.02017f, 1.20461f, 1.37534f, 1.53363f, 1.68092f, 1.81865f,
       1.94811f, 2.07038f, 2.18638f, 2.29688f, 2.40255f, 2.50391f, 2.60144f,
       2.69551f, 2.78647f, 2.87458f, 2.96015f, 3.04333f, 3.12431f, 3.20326f};
-      
+   x = EXPIN_SCALING_1*xx;
    integer = floor(2*x);
    ind = (int)integer;
    if (ind<0)
-      return 1;
+      return FRAC_SCALING;
    if (ind>19)
-      return 1+.1296/x;
+      return FRAC_SCALING*(1+.1296/x);
    frac = 2*x-integer;
-   return ((1-frac)*table[ind] + frac*table[ind+1])/sqrt(x+.0001f);
+   return FRAC_SCALING*((1-frac)*table[ind] + frac*table[ind+1])/sqrt(x+.0001f);
 }
 
 static inline float qcurve(spx_word16_t x)
@@ -733,7 +734,7 @@
    for (i=N;i<N+M;i++)
    {
       spx_word32_t theta;
-      float MM;
+      spx_word32_t MM;
       spx_word16_t prior_ratio;
       float q;
       float P1;
@@ -743,10 +744,9 @@
       prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT)));
       theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT));
 
-      MM = hypergeom_gain(EXPIN_SCALING_1*theta);
+      MM = hypergeom_gain(theta);
       /* Gain with bound */
-      st->gain[i] = MIN16(FRAC_SCALING, prior_ratio * MM);
-      
+      st->gain[i] = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM)));
       /* Save old Bark power spectrum */
       st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]);
 
@@ -769,28 +769,28 @@
       /* Compute gain according to the Ephraim-Malah algorithm -- linear frequency */
       for (i=0;i<N;i++)
       {
-         float MM;
+         spx_word32_t MM;
          spx_word32_t theta;
          spx_word16_t prior_ratio;
-         float p;
-         float g;
+         spx_word16_t tmp;
+         spx_word16_t p;
+         spx_word16_t g;
          
          /* Wiener filter gain */
          prior_ratio = PDIV32_16(SHL32(EXTEND32(st->prior[i]), 15), ADD16(st->prior[i], SHL32(1,SNR_SHIFT)));
          theta = MULT16_32_P15(prior_ratio, QCONST32(1.f,EXPIN_SHIFT)+SHL32(EXTEND32(st->post[i]),EXPIN_SHIFT-SNR_SHIFT));
 
          /* Optimal estimator for loudness domain */
-         MM = hypergeom_gain(EXPIN_SCALING_1*theta);
+         MM = hypergeom_gain(theta);
          /* EM gain with bound */
-         g = MIN16(FRAC_SCALING, prior_ratio * MM);
-
+         g = EXTRACT16(MIN32(Q15_ONE, MULT16_32_Q15(prior_ratio, MM)));
          /* Interpolated speech probability of presence */
-         p = FRAC_SCALING_1*st->gain2[i];
+         p = st->gain2[i];
                   
          /* Constrain the gain to be close to the Bark scale gain */
-         if (g > 3.f*st->gain[i])
-            g = 3.f*st->gain[i];
-         st->gain[i] = MIN16(Q15_ONE, g);
+         if (MULT16_16_Q15(QCONST16(.333f,15),g) > st->gain[i])
+            g = MULT16_16(3,st->gain[i]);
+         st->gain[i] = g;
          
          /* Save old power spectrum */
          st->old_ps[i] = MULT16_32_P15(QCONST16(.2f,15),st->old_ps[i]) + MULT16_32_P15(MULT16_16_P15(QCONST16(.8f,15),SQR16_Q15(st->gain[i])),ps[i]);
@@ -803,7 +803,9 @@
          /*st->reverb_estimate[i] = st->reverb_decay*st->reverb_estimate[i] + st->reverb_decay*st->reverb_level*st->gain[i]*st->gain[i]*st->ps[i];*/
          
          /* Take into account speech probability of presence (loudness domain MMSE estimator) */
-         st->gain2[i]=FRAC_SCALING*SQR(p*sqrt(FRAC_SCALING_1*st->gain[i])+sqrt(FRAC_SCALING_1*st->gain_floor[i])*(1-p));
+         /* gain2 = [p*sqrt(gain)+(1-p)*sqrt(gain _floor) ]^2 */
+         tmp = MULT16_16_P15(p,spx_sqrt(SHL32(EXTEND32(st->gain[i]),15))) + MULT16_16_P15(SUB16(Q15_ONE,p),spx_sqrt(SHL32(EXTEND32(st->gain_floor[i]),15)));
+         st->gain2[i]=SQR16_Q15(tmp);
 
          /* Use this if you want a log-domain MMSE estimator instead */
          /*st->gain2[i] = pow(st->gain[i], p) * pow(st->gain_floor[i],1.f-p);*/



More information about the commits mailing list