[xiph-commits] r11947 - in trunk/speex: include/speex libspeex

jm at svn.xiph.org jm at svn.xiph.org
Wed Oct 25 09:08:20 PDT 2006


Author: jm
Date: 2006-10-25 09:08:15 -0700 (Wed, 25 Oct 2006)
New Revision: 11947

Modified:
   trunk/speex/include/speex/speex_echo.h
   trunk/speex/libspeex/mdf.c
Log:
added speex_echo_cancellation() without the last param, deprecated 
speex_echo_cancel().


Modified: trunk/speex/include/speex/speex_echo.h
===================================================================
--- trunk/speex/include/speex/speex_echo.h	2006-10-25 16:04:17 UTC (rev 11946)
+++ trunk/speex/include/speex/speex_echo.h	2006-10-25 16:08:15 UTC (rev 11947)
@@ -61,6 +61,9 @@
 void speex_echo_state_destroy(SpeexEchoState *st);
 
 /** Performs echo cancellation a frame */
+void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out);
+
+/** Performs echo cancellation a frame (deprecated) */
 void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out, spx_int32_t *Yout);
 
 /** Perform echo cancellation using internal playback buffer */

Modified: trunk/speex/libspeex/mdf.c
===================================================================
--- trunk/speex/libspeex/mdf.c	2006-10-25 16:04:17 UTC (rev 11946)
+++ trunk/speex/libspeex/mdf.c	2006-10-25 16:08:15 UTC (rev 11947)
@@ -102,7 +102,9 @@
 #define TOP16(x) (x)
 #endif
 
+void speex_echo_get_residual(SpeexEchoState *st, spx_int32_t *Yout, int len);
 
+
 /** Speex echo cancellation state. */
 struct SpeexEchoState_ {
    int frame_size;           /**< Number of samples processed each time */
@@ -116,6 +118,8 @@
    spx_word16_t beta0;
    spx_word16_t beta_max;
    spx_word32_t sum_adapt;
+   spx_word16_t leak_estimate;
+   
    spx_word16_t *e;
    spx_word16_t *x;
    spx_word16_t *X;
@@ -291,6 +295,7 @@
    st->beta0 = (2.0f*st->frame_size)/st->sampling_rate;
    st->beta_max = (.5f*st->frame_size)/st->sampling_rate;
 #endif
+   st->leak_estimate = 0;
 
    st->fft_table = spx_fft_init(N);
    
@@ -463,13 +468,19 @@
 }
 
 /** Performs echo cancellation on a frame */
-void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *ref, const spx_int16_t *echo, spx_int16_t *out, spx_int32_t *Yout)
+void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out, spx_int32_t *Yout)
 {
+   speex_echo_cancellation(st, in, far_end, out);
+   speex_echo_get_residual(st, Yout, 0);
+}
+
+/** Performs echo cancellation on a frame (deprecated, last arg now ignored) */
+void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *in, const spx_int16_t *far_end, spx_int16_t *out)
+{
    int i,j;
    int N,M;
    spx_word32_t Syy,See,Sxx;
    spx_word32_t Sey;
-   spx_word16_t leak_estimate;
    spx_word16_t ss, ss_1;
    spx_float_t Pey = FLOAT_ONE, Pyy=FLOAT_ONE;
    spx_float_t alpha, alpha_1;
@@ -487,14 +498,14 @@
    ss_1 = 1-ss;
 #endif
 
-   filter_dc_notch16(ref, st->notch_radius, st->d, st->frame_size, st->notch_mem);
+   filter_dc_notch16(in, st->notch_radius, st->d, st->frame_size, st->notch_mem);
    /* Copy input data to buffer */
    for (i=0;i<st->frame_size;i++)
    {
       spx_word16_t tmp;
       spx_word32_t tmp32;
       st->x[i] = st->x[i+st->frame_size];
-      tmp32 = SUB32(EXTEND32(echo[i]), EXTEND32(MULT16_16_P15(st->preemph, st->memX)));
+      tmp32 = SUB32(EXTEND32(far_end[i]), EXTEND32(MULT16_16_P15(st->preemph, st->memX)));
 #ifdef FIXED_POINT
       /*FIXME: If saturation occurs here, we need to freeze adaptation for M frames (not just one) */
       if (tmp32 > 32767)
@@ -509,7 +520,7 @@
       }      
 #endif
       st->x[i+st->frame_size] = EXTRACT16(tmp32);
-      st->memX = echo[i];
+      st->memX = far_end[i];
       
       tmp = st->d[i];
       st->d[i] = st->d[i+st->frame_size];
@@ -537,7 +548,7 @@
          st->X[(j+1)*N+i] = st->X[j*N+i];
    }
 
-   /* Convert x (echo input) to frequency domain */
+   /* Convert x (far end) to frequency domain */
    spx_fft(st->fft_table, st->x, &st->X[0]);
    
 #ifdef SMOOTH_BLOCKS
@@ -616,7 +627,7 @@
          tmp_out = -32768;
       tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(st->preemph, st->memE)));
       /* This is an arbitrary test for saturation */
-      if (ref[i] <= -32000 || ref[i] >= 32000)
+      if (in[i] <= -32000 || in[i] >= 32000)
       {
          tmp_out = 0;
          st->saturated = 1;
@@ -645,12 +656,12 @@
       st->y[i] = 0;
    spx_fft(st->fft_table, st->y, st->Y);
 
-   /* Compute power spectrum of echo (X), error (E) and filter response (Y) */
+   /* Compute power spectrum of far end (X), error (E) and filter response (Y) */
    power_spectrum(st->E, st->Rf, N);
    power_spectrum(st->Y, st->Yf, N);
    power_spectrum(st->X, st->Xf, N);
    
-   /* Smooth echo energy estimate over time */
+   /* Smooth far end energy estimate over time */
    for (j=0;j<=st->frame_size;j++)
       st->power[j] = MULT16_32_Q15(ss_1,st->power[j]) + 1 + MULT16_32_Q15(ss,st->Xf[j]);
    
@@ -706,17 +717,17 @@
    if (FLOAT_GT(st->Pey, st->Pyy))
       st->Pey = st->Pyy;
    /* leak_estimate is the linear regression result */
-   leak_estimate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIVU(st->Pey, st->Pyy),14));
+   st->leak_estimate = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIVU(st->Pey, st->Pyy),14));
    /* This looks like a stupid bug, but it's right (because we convert from Q14 to Q15) */
-   if (leak_estimate > 16383)
-      leak_estimate = 32767;
+   if (st->leak_estimate > 16383)
+      st->leak_estimate = 32767;
    else
-      leak_estimate = SHL16(leak_estimate,1);
-   /*printf ("%f\n", leak_estimate);*/
+      st->leak_estimate = SHL16(st->leak_estimate,1);
+   /*printf ("%f\n", st->leak_estimate);*/
    
    /* Compute Residual to Error Ratio */
 #ifdef FIXED_POINT
-   tmp32 = MULT16_32_Q15(leak_estimate,Syy);
+   tmp32 = MULT16_32_Q15(st->leak_estimate,Syy);
    tmp32 = ADD32(SHR32(Sxx,13), ADD32(tmp32, SHL32(tmp32,1)));
    /* Check for y in e (lower bound on RER) */
    {
@@ -731,7 +742,7 @@
       tmp32 = SHR32(See,1);
    RER = FLOAT_EXTRACT16(FLOAT_SHL(FLOAT_DIV32(tmp32,See),15));
 #else
-   RER = (.0001*Sxx + 3.*MULT16_32_Q15(leak_estimate,Syy)) / See;
+   RER = (.0001*Sxx + 3.*MULT16_32_Q15(st->leak_estimate,Syy)) / See;
    /* Check for y in e (lower bound on RER) */
    if (RER < Sey*Sey/(1+See*Syy))
       RER = Sey*Sey/(1+See*Syy);
@@ -751,7 +762,7 @@
       {
          spx_word32_t r, e;
          /* Compute frequency-domain adaptation mask */
-         r = MULT16_32_Q15(leak_estimate,SHL32(st->Yf[i],3));
+         r = MULT16_32_Q15(st->leak_estimate,SHL32(st->Yf[i],3));
          e = SHL32(st->Rf[i],3)+1;
 #ifdef FIXED_POINT
          if (r>SHR32(e,1))
@@ -788,49 +799,55 @@
       st->sum_adapt = ADD32(st->sum_adapt,adapt_rate);
    }
 
-   /* Compute spectrum of estimated echo for use in an echo post-filter (if necessary)*/
-   if (Yout)
+   if (st->adapted)
    {
-      spx_word16_t leak2;
-      if (st->adapted)
-      {
-         /* If the filter is adapted, take the filtered echo */
-         for (i=0;i<st->frame_size;i++)
-            st->last_y[i] = st->last_y[st->frame_size+i];
-         for (i=0;i<st->frame_size;i++)
-            st->last_y[st->frame_size+i] = ref[i]-out[i];
-      } else {
-         /* If filter isn't adapted yet, all we can do is take the echo signal directly */
-         for (i=0;i<N;i++)
-            st->last_y[i] = st->x[i];
-      }
-      
-      /* Apply hanning window (should pre-compute it)*/
+      /* If the filter is adapted, take the filtered echo */
+      for (i=0;i<st->frame_size;i++)
+         st->last_y[i] = st->last_y[st->frame_size+i];
+      for (i=0;i<st->frame_size;i++)
+         st->last_y[st->frame_size+i] = in[i]-out[i];
+   } else {
+      /* If filter isn't adapted yet, all we can do is take the far end signal directly */
       for (i=0;i<N;i++)
-         st->y[i] = MULT16_16_Q15(st->window[i],st->last_y[i]);
+         st->last_y[i] = st->x[i];
+   }
+
+}
+
+/* Compute spectrum of estimated echo for use in an echo post-filter */
+void speex_echo_get_residual(SpeexEchoState *st, spx_int32_t *Yout, int len)
+{
+   int i;
+   spx_word16_t leak2;
+   int N;
+   
+   N = st->window_size;
+
+   /* Apply hanning window (should pre-compute it)*/
+   for (i=0;i<N;i++)
+      st->y[i] = MULT16_16_Q15(st->window[i],st->last_y[i]);
       
-      /* Compute power spectrum of the echo */
-      spx_fft(st->fft_table, st->y, st->Y);
-      power_spectrum(st->Y, st->Yps, N);
+   /* Compute power spectrum of the echo */
+   spx_fft(st->fft_table, st->y, st->Y);
+   power_spectrum(st->Y, st->Yps, N);
       
 #ifdef FIXED_POINT
-      if (leak_estimate > 16383)
-         leak2 = 32767;
-      else
-         leak2 = SHL16(leak_estimate, 1);
+   if (st->leak_estimate > 16383)
+      leak2 = 32767;
+   else
+      leak2 = SHL16(st->leak_estimate, 1);
 #else
-      if (leak_estimate>.5)
-         leak2 = 1;
-      else
-         leak2 = 2*leak_estimate;
+   if (st->leak_estimate>.5)
+      leak2 = 1;
+   else
+      leak2 = 2*st->leak_estimate;
 #endif
-      /* Estimate residual echo */
-      for (i=0;i<=st->frame_size;i++)
-         Yout[i] = (spx_int32_t)MULT16_32_Q15(leak2,st->Yps[i]);
-   }
+   /* Estimate residual echo */
+   for (i=0;i<=st->frame_size;i++)
+      Yout[i] = (spx_int32_t)MULT16_32_Q15(leak2,st->Yps[i]);
+   
 }
 
-
 int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr)
 {
    switch(request)



More information about the commits mailing list