[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