[Speex-dev] Echo Cancellation

zmorris at mac.com zmorris at mac.com
Mon Jun 25 15:15:08 PDT 2007

Hi All, I have tried using echo cancellation, and I think it doesn't  
work well, because of how I resample.  I take the raw 44100 Hz on my  
mac and just do a loop averaging every 5.5 samples to 1 sample to get  
8018.18 Hz, and feed that to speex in 160 sample buffers.  I realize  
that this introduces some aliasing, and I may try the new speex  
resampler, but I find it hard to believe that the noise intruduced  
would be higher than normal background anyway, and it sounds clear  
enough when I just do playthrough for testing.

The problem is, this uses nibbling, which means the input jitters in  
time in relation to the output.  I also don't know what Apple does  
under the hood for playback, they almost certainly nibble as well.   
This means that the echo canceler will nearly always see a different  
time offset for the current buffer pair, than for the previous ones.

So it seems to me that in order for echo cancellation to work, it has  
to tolerate nibbling up to roughly 160/8000 or 1/50th of a second.   
Assuming that 2 nibbles can happen, one on input and one on output,  
this becomes 1/25th of a second.  In other words, feeding the input  
and output buffers shifted in time +/- 1/25th of a second to the echo  
canceler should always give roughly the same output, but I think that  
may not be happening right now.

Is this issue addressed?  Perhaps PCs can set their sampler to run at  
an exact clock speed to avoid nibbling, on the same sound card as  
output, but that doesn't seem to be available easily on the Mac.   
Because of all the latencies and nibbling that can happen in various  
sound engines/hardware, I think matched input/output is a pipe dream.

Off the top of my head, there are other methods, like finding the  
maximum covariance, that can determine the phase of 2 sounds fairly  
easily.  Also, it might work to keep track of 4 phases in the echo  
canceler instead of 1, to account for the 4 types of lag seen on each  
input/output buffer pair:

input	output
0	0
0	nibbled
nibbled	0
nibbled	nibbled

However, this will not work when the nibbling is a non-even  
multiple.  For example nibbling 160 sample speex buffers from 256  
sample hardware buffers.  Which makes me think that each buffer  
should be analyzed with something like covariance to find the phase,  
or else it should adapt somehow to find what type of nibbling is  
occurring, if it's going to keep a running average for phase.  It  
could also queue up several buffers to do this more accurately (which  
introduces lag), perhaps it already does this.

I have not yet tried the new 1.2 beta.



More information about the Speex-dev mailing list