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

jm at svn.xiph.org jm at svn.xiph.org
Sun Nov 12 05:40:17 PST 2006


Author: jm
Date: 2006-11-12 05:40:14 -0800 (Sun, 12 Nov 2006)
New Revision: 12092

Modified:
   trunk/speex/libspeex/mdf.c
   trunk/speex/libspeex/preprocess.c
Log:
Added some checks to detect if the echo canceller has gone unstable (shouldn't
happen, but it's good to check), in which case we reset it.


Modified: trunk/speex/libspeex/mdf.c
===================================================================
--- trunk/speex/libspeex/mdf.c	2006-11-12 11:26:03 UTC (rev 12091)
+++ trunk/speex/libspeex/mdf.c	2006-11-12 13:40:14 UTC (rev 12092)
@@ -113,6 +113,7 @@
    int cancel_count;
    int adapted;
    int saturated;
+   int screwed_up;
    spx_int32_t sampling_rate;
    spx_word16_t spec_average;
    spx_word16_t beta0;
@@ -289,6 +290,7 @@
    st->cancel_count=0;
    st->sum_adapt = 0;
    st->saturated = 0;
+   st->screwed_up = 0;
    /* This is the default sampling rate */
    st->sampling_rate = 8000;
    st->spec_average = DIV32_16(SHL32(EXTEND32(st->frame_size), 15), st->sampling_rate);
@@ -381,6 +383,7 @@
 {
    int i, M, N;
    st->cancel_count=0;
+   st->screwed_up = 0;
    N = st->window_size;
    M = st->M;
    for (i=0;i<N*M;i++)
@@ -404,7 +407,8 @@
       st->x[i] = 0;
    }
    st->notch_mem[0] = st->notch_mem[1] = 0;
-  
+   st->memX=st->memD=st->memE=0;
+
    st->saturated = 0;
    st->adapted = 0;
    st->sum_adapt = 0;
@@ -509,7 +513,7 @@
 {
    int i,j;
    int N,M;
-   spx_word32_t Syy,See,Sxx;
+   spx_word32_t Syy,See,Sxx,Sdd;
    spx_word32_t Sey;
    spx_word16_t ss, ss_1;
    spx_float_t Pey = FLOAT_ONE, Pyy=FLOAT_ONE;
@@ -676,23 +680,39 @@
    /* Compute a bunch of correlations */
    Sey = mdf_inner_prod(st->e+st->frame_size, st->y+st->frame_size, st->frame_size);
    See = mdf_inner_prod(st->e+st->frame_size, st->e+st->frame_size, st->frame_size);
-   See = MAX32(See, SHR32(MULT16_16(N, 100),6));
    Syy = mdf_inner_prod(st->y+st->frame_size, st->y+st->frame_size, st->frame_size);
    Sxx = mdf_inner_prod(st->x+st->frame_size, st->x+st->frame_size, st->frame_size);
-
-   /* Just in case something went really wrong */
-#ifdef FIXED_POINT
-   if (Syy<0)
+   Sdd = mdf_inner_prod(st->input, st->input, st->frame_size);
+   
+   /* Do some sanity check */
+   if (!(Syy>=0 && Sxx>=0 && See >= 0)
+#ifndef FIXED_POINT
+       || !(See < N*1e9 && Syy < N*1e9 && Sxx < N*1e9)
+#endif
+      )
    {
-      speex_warning_int ("Syy is negative: ", Syy);
-      Syy = 0;
+      /* Things have gone really bad */
+      st->screwed_up += 50;
+      for (i=0;i<st->frame_size;i++)
+         out[i] = 0;
+   } else if (SHR32(See, 2) > ADD32(Sdd, SHR32(MULT16_16(N, 100),6)))
+   {
+      /* AEC seems to add lots of echo instead of removing it, let's see if it will improve */
+      st->screwed_up++;
+   } else {
+      /* Everything's fine */
+      st->screwed_up=0;
    }
-   if (Sxx<0)
+   if (st->screwed_up>=50)
    {
-      speex_warning_int ("Sxx is negative: ", Sxx);
-      Sxx = 0;
+      speex_warning("The echo canceller started acting funny and got slapped (reset). It swears it will behave now.");
+      speex_echo_state_reset(st);
+      return;
    }
-#endif
+
+   /* Add a small noise floor to make sure not to have problems when dividing */
+   See = MAX32(See, SHR32(MULT16_16(N, 100),6));
+
    /* Convert error to frequency domain */
    spx_fft(st->fft_table, st->e, st->E);
    for (i=0;i<st->frame_size;i++)

Modified: trunk/speex/libspeex/preprocess.c
===================================================================
--- trunk/speex/libspeex/preprocess.c	2006-11-12 11:26:03 UTC (rev 12091)
+++ trunk/speex/libspeex/preprocess.c	2006-11-12 13:40:14 UTC (rev 12092)
@@ -736,6 +736,14 @@
    if (st->echo_state)
    {
       speex_echo_get_residual(st->echo_state, st->residual_echo, N);
+#ifndef FIXED_POINT
+      /* If there are NaNs or ridiculous values, it'll show up in the DC and we just reset everything to zero */
+      if (!(st->residual_echo[0] >=0 && st->residual_echo[0]<N*1e9f))
+      {
+         for (i=0;i<N;i++)
+            st->residual_echo[i] = 0;
+      }
+#endif
       for (i=0;i<N;i++)
          st->echo_noise[i] = MAX32(MULT16_32_Q15(QCONST16(.6f,15),st->echo_noise[i]), st->residual_echo[i]);
       filterbank_compute_bank32(st->bank, st->echo_noise, st->echo_noise+N);



More information about the commits mailing list