[xiph-cvs] cvs commit: speex/libspeex mdf.c speex_echo.h

Jean-Marc Valin jm at xiph.org
Wed Aug 20 21:25:38 PDT 2003



jm          03/08/21 00:25:37

  Modified:    libspeex mdf.c speex_echo.h
  Log:
  did some cleanup. Still some work to do with adaptation rate adjustment
  and cross-talk detection.

Revision  Changes    Path
1.4       +84 -13    speex/libspeex/mdf.c

Index: mdf.c
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/mdf.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- mdf.c	19 Aug 2003 05:47:04 -0000	1.3
+++ mdf.c	21 Aug 2003 04:25:35 -0000	1.4
@@ -34,6 +34,9 @@
 #include "speex_echo.h"
 #include "smallft.h"
 #include <math.h>
+#include <stdio.h>
+
+#define BETA .65
 
 /** Creates a new echo canceller state */
 SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length)
@@ -46,6 +49,7 @@
    N = st->window_size;
    M = st->M = (filter_length+N-1)/frame_size;
    st->cancel_count=0;
+   st->adapt_rate = .01;
 
    drft_init(&st->fft_lookup, N);
    
@@ -59,6 +63,9 @@
    st->PHI = (float*)speex_alloc(N*sizeof(float));
    st->power = (float*)speex_alloc((frame_size+1)*sizeof(float));
    st->power_1 = (float*)speex_alloc((frame_size+1)*sizeof(float));
+   st->grad = (float*)speex_alloc(N*M*sizeof(float));
+   st->old_grad = (float*)speex_alloc(N*M*sizeof(float));
+   
    return st;
 }
 
@@ -76,6 +83,8 @@
    speex_free(st->PHI);
    speex_free(st->power);
    speex_free(st->power_1);
+   speex_free(st->grad);
+   speex_free(st->old_grad);
 
    speex_free(st);
 }
@@ -86,6 +95,7 @@
    int i,j,m;
    int N,M;
    float scale;
+   float powE=0, powY=0, powD=0;
 
    N = st->window_size;
    M = st->M;
@@ -146,6 +156,35 @@
 
    drft_forward(&st->fft_lookup, st->E);
 
+   for (i=0;i<st->frame_size;i++)
+   {
+      powD += N*ref[i]*ref[i];
+   }
+#if 0
+   for (i=1;i<N-1;i+=2)
+   {
+      float tmp;
+      tmp = st->Y[i]*st->Y[i] + st->Y[i+1]*st->Y[i+1];
+      powY += 1*tmp + 0*(st->E[i]*st->E[i] + st->E[i+1]*st->E[i+1]);
+      tmp = st->E[i]*st->E[i] + st->E[i+1]*st->E[i+1] - 4*tmp;
+      if (tmp<0)
+         tmp=0;
+      powE += tmp; 
+   }
+#else
+   for (i=3;i<N-3;i+=2)
+   {
+      float tmp;
+      tmp = .5*(st->Y[i]*st->Y[i] + st->Y[i+1]*st->Y[i+1]) + .25*
+      (st->Y[i-2]*st->Y[i-2] + st->Y[i-1]*st->Y[i-1] 
+       + st->Y[i+2]*st->Y[i+2] + st->Y[i+3]*st->Y[i+3]);
+      powY += 1*tmp + 0*(st->E[i]*st->E[i] + st->E[i+1]*st->E[i+1]);
+      tmp = st->E[i]*st->E[i] + st->E[i+1]*st->E[i+1] - .5*tmp;
+      if (tmp<0)
+         tmp=0;
+      powE += tmp; 
+   }
+#endif
 
    /* Compute input power in each band */
    {
@@ -162,19 +201,24 @@
          tmp=0;
          for (m=0;m<M;m++)
          {
-            tmp += st->X[m*N+i]*st->X[m*N+i] + st->X[m*N+i+1]*st->X[m*N+i+1];
+            float E = st->X[m*N+i]*st->X[m*N+i] + st->X[m*N+i+1]*st->X[m*N+i+1];
+            tmp += E;
+            if (st->power[j] < .2*E)
+               st->power[j] = .2*E;
+
          }
          tmp *= s;
          if (st->cancel_count<M)
             st->power[j] = tmp;
          else
-            st->power[j] = .8*st->power[j] + .2*tmp;
+            st->power[j] = BETA*st->power[j] + (1-BETA)*tmp;
       }
       tmp=tmp2=0;
       for (m=0;m<M;m++)
       {
          tmp += st->X[m*N]*st->X[m*N];
          tmp2 += st->X[(m+1)*N-1]*st->X[(m+1)*N-1];
+         /*FIXME: Should put a bound on energy like several lines above */
       }
       tmp *= s;
       tmp2 *= s;
@@ -183,12 +227,12 @@
          st->power[0] = tmp;
          st->power[st->frame_size] = tmp2;
       } else {
-         st->power[0] = .8*st->power[0] + .2*tmp;
-         st->power[st->frame_size] = .8*st->power[st->frame_size] + .2*tmp2;
+         st->power[0] = BETA*st->power[0] + (1-BETA)*tmp;
+         st->power[st->frame_size] = BETA*st->power[st->frame_size] + (1-BETA)*tmp2;
       }
       
       for (i=0;i<=st->frame_size;i++)
-         st->power_1[i] = 1.0/(1e-10+st->power[i]);
+         st->power_1[i] = 1.0/(1e6+st->power[i]);
    }
 
    /* Update filter weights */
@@ -202,16 +246,43 @@
       st->PHI[0] = st->X[j*N]*st->E[0];
       st->PHI[N-1] = st->X[(j+1)*N-1]*st->E[N-1];
 
-      /* Optionally perform some transform (normalization?) on PHI */
+#if 0
+      drft_backward(&st->fft_lookup, st->PHI);
+      for (i=0;i<N;i++)
+         st->PHI[i]*=scale;
+      for (i=st->frame_size;i<N;i++)
+        st->PHI[i]=0;
+      drft_forward(&st->fft_lookup, st->PHI);
+#endif
       
+#if 0
+      for (i=1,m=1;i<N-1;i+=2,m++)
+         st->W[j*N+i] += st->adapt_rate*st->PHI[i]*st->power_1[m];
+      st->W[j*N] += st->adapt_rate*st->PHI[0]*st->power_1[0];
+      st->W[(j+1)*N-1] += st->adapt_rate*st->PHI[N-1]*st->power_1[st->frame_size];
+#endif
+
+      for (i=0;i<N;i++)
+      {
+         st->old_grad[j*N+i] = st->PHI[i];
+         st->grad[j*N+i] = st->PHI[i];
+      }
+
+      
+   }
+
+   if (st->cancel_count>2*M)
+      st->adapt_rate = .01;
+   else
+      st->adapt_rate = .0;
+
+   for (j=0;j<M;j++)
+   {
       for (i=1,m=1;i<N-1;i+=2,m++)
-         st->W[j*N+i] += .1*st->PHI[i]*st->power_1[m];
-      st->W[j*N] += .1*st->PHI[0]*st->power_1[0];
-      st->W[(j+1)*N-1] += .1*st->PHI[N-1]*st->power_1[st->frame_size];
-      /*
-      for (i=0,j=0;i<=N;i++,j++)
-         st->W[j*N+i] += .001*st->PHI[i];
-      */
+         st->W[j*N+i] += st->adapt_rate*st->grad[j*N+i]*st->power_1[m];
+      st->W[j*N] += st->adapt_rate*st->grad[j*N]*st->power_1[0];
+      st->W[(j+1)*N-1] += st->adapt_rate*st->grad[(j+1)*N-1]*st->power_1[st->frame_size];
    }
+   /*fprintf (stderr, "%f %f %f %f\n", st->adapt_rate, powE, powY, powD);*/
 }
 

<p><p>1.3       +4 -1      speex/libspeex/speex_echo.h

Index: speex_echo.h
===================================================================
RCS file: /usr/local/cvsroot/speex/libspeex/speex_echo.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- speex_echo.h	19 Aug 2003 03:59:27 -0000	1.2
+++ speex_echo.h	21 Aug 2003 04:25:36 -0000	1.3
@@ -37,6 +37,7 @@
    int window_size;
    int M;
    int cancel_count;
+   float adapt_rate;
 
    float *x;
    float *X;
@@ -47,7 +48,9 @@
    float *W;
    float *power;
    float *power_1;
-   
+   float *grad;
+   float *old_grad;
+
    drft_lookup fft_lookup;
 
 

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list