[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.
Thanx,
--Zack
More information about the Speex-dev
mailing list