fixed residual echo estimation (for preprocessor), optional re-filtering
authorjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Thu, 15 Dec 2005 06:10:02 +0000 (06:10 +0000)
committerjm <jm@0101bb08-14d6-0310-b084-bc0e0c8e3800>
Thu, 15 Dec 2005 06:10:02 +0000 (06:10 +0000)
step using new filter (faster echo attenuation).

git-svn-id: http://svn.xiph.org/trunk/speex@10598 0101bb08-14d6-0310-b084-bc0e0c8e3800

libspeex/mdf.c

index 48f477a..ad47099 100644 (file)
@@ -92,6 +92,7 @@ struct SpeexEchoState_ {
    spx_word32_t *Yh;
    float Pey;
    float Pyy;
+   float *window;
    /*struct drft_lookup *fft_lookup;*/
    void *fft_table;
    spx_word16_t memX, memD, memE;
@@ -225,7 +226,10 @@ SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length)
    st->PHI = (spx_word16_t*)speex_alloc(M*N*sizeof(spx_word16_t));
    st->power = (spx_word32_t*)speex_alloc((frame_size+1)*sizeof(spx_word32_t));
    st->power_1 = (spx_float_t*)speex_alloc((frame_size+1)*sizeof(spx_float_t));
-   
+   st->window = (float*)speex_alloc(N*sizeof(float));
+   for (i=0;i<N;i++)
+      st->window[i] = .5-.5*cos(2*M_PI*i/N);
+
    for (i=0;i<N*M;i++)
    {
       st->W[i] = st->PHI[i] = 0;
@@ -282,6 +286,7 @@ void speex_echo_state_destroy(SpeexEchoState *st)
    speex_free(st->PHI);
    speex_free(st->power);
    speex_free(st->power_1);
+   speex_free(st->window);
 
    speex_free(st);
 }
@@ -335,26 +340,12 @@ void speex_echo_cancel(SpeexEchoState *st, short *ref, short *echo, short *out,
    
    spx_ifft(st->fft_table, st->Y, st->y);
 
-   /* Compute error signal (signal with echo removed) */ 
    for (i=0;i<st->frame_size;i++)
    {
-      spx_word32_t tmp_out;
-      tmp_out = SUB32(EXTEND32(st->d[i+st->frame_size]), EXTEND32(st->y[i+st->frame_size]));
-      
       st->e[i] = 0;
-      /* Do we need saturation? */
-      st->e[i+st->frame_size] = tmp_out;
-      tmp_out = PSHR32(tmp_out,1);
-      /* Saturation */
-      if (tmp_out>32767)
-         tmp_out = 32767;
-      else if (tmp_out<-32768)
-         tmp_out = -32768;
-      tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(st->preemph, st->memE)));
-      out[i] = tmp_out;
-      st->memE = tmp_out;
+      st->e[i+st->frame_size] = st->d[i+st->frame_size] - st->y[i+st->frame_size];
    }
-   
+
    /* Compute a bunch of correlations */
    See = inner_prod(st->e+st->frame_size, st->e+st->frame_size, st->frame_size);
    Syy = inner_prod(st->y+st->frame_size, st->y+st->frame_size, st->frame_size);
@@ -505,6 +496,33 @@ void speex_echo_cancel(SpeexEchoState *st, short *ref, short *echo, short *out,
       }
    }
 
+#if 1
+   spectral_mul_accum(st->X, st->W, st->Y, N, M);   
+   spx_ifft(st->fft_table, st->Y, st->e);
+   
+   /* Compute error signal (signal with echo removed) */ 
+   for (i=0;i<st->frame_size;i++)
+   {
+      spx_word32_t tmp_out;
+#if 0
+      spx_word16_t y = st->window[i]*st->e[i+st->frame_size] + st->window[i+st->frame_size]*st->y[i+st->frame_size];
+      tmp_out = SUB32(EXTEND32(st->d[i+st->frame_size]), EXTEND32(y));
+#else
+      tmp_out = SUB32(EXTEND32(st->d[i+st->frame_size]), EXTEND32(st->e[i+st->frame_size]));
+#endif
+
+      tmp_out = PSHR32(tmp_out,1);
+      /* Saturation */
+      if (tmp_out>32767)
+         tmp_out = 32767;
+      else if (tmp_out<-32768)
+         tmp_out = -32768;
+      tmp_out = ADD32(tmp_out, EXTEND32(MULT16_16_P15(st->preemph, st->memE)));
+      out[i] = tmp_out;
+      st->memE = tmp_out;
+   }
+#endif
+
    /* Compute spectrum of estimated echo for use in an echo post-filter (if necessary)*/
    if (Yout)
    {
@@ -514,7 +532,7 @@ void speex_echo_cancel(SpeexEchoState *st, short *ref, short *echo, short *out,
          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] = out[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++)
@@ -523,7 +541,7 @@ void speex_echo_cancel(SpeexEchoState *st, short *ref, short *echo, short *out,
       
       /* Apply hanning window (should pre-compute it)*/
       for (i=0;i<N;i++)
-         st->y[i] = (.5-.5*cos(2*M_PI*i/N))*st->last_y[i];
+         st->y[i] = st->window[i]*st->last_y[i];
       
       /* Compute power spectrum of the echo */
       spx_fft(st->fft_table, st->y, st->Y);