[Speex-dev] Re: aec

Duane Storey duane at counterpath.com
Fri Nov 11 12:00:31 PST 2005

Actualy, most sound cards I've used (including DSPs) support sample-accurate
resolutions..  you might have to use diectsound on windows to get at it (as
most companies don't focus as much on their winmm drivers anymore).

Also, I'm not that familiar with ASIO, but if it's anything like kernel
streaming, it has the end-user disadvantage of disconnecting the windows
mixer from the sound card, which means they can only use audio in your
application, and won't hear anything else on the system while it's

-----Original Message-----
From: speex-dev-bounces at xiph.org [mailto:speex-dev-bounces at xiph.org] On
Behalf Of Thorvald Natvig
Sent: Friday, November 11, 2005 10:01 AM
To: speex-dev at xiph.org
Subject: Re: [Speex-dev] Re: aec

> To everyone on the list: do *NOT* attempt to do echo cancellation with
> signals sampled using different clocks. This will *NOT* work. Just a
> 0.1% difference between the two sampling rates (it's sometimes worse
> than that) means that the impulse response drifts by 8 samples every
> second. There's just no way to efficiently track this.  Or at least no
> way that doesn't involve something 100x more complex than what I have
> now. So if you want to use two different soundcards, you should either:
> 1) Have professionals cards connected with a clock sync
> 2) Have an atomic clock in both cards
> 3) Forget about echo cancellation

On Win32, the proper solution is to use ASIO. This, unfortunately, 
requires a high end card.

However, I've had some limited success using two identical soundblaster 
live cards, card A (mic) and card B (output card which samples speakers). 
On each event (sampling capture position passed a marker in the buffer):

- Fetch hardware sample-accurate sampling position of card A and B as PosA 
and PosB.
- Copy 320 samples from buffer of card A at offset WantPosA into "mic
- Calculate "negative offset" SampOfs = PosA-WantPosA.
- Copy 320 samples from card B at offset PosB-SampOfs into "speaker
- WantPosA += 320
- Wait for next event and repeat.

This means that even if the cards drift a little (and they do, even with 
identical cards), the drift is compensated for. Kind of.

The downside of this "solution" is that it requires the ability to read 
the *hardware* sampling position at sample-accurate resolution, something 
few cards support (you can basically forget any kind of USB mic and most 
onboard soundcards).

It works, but every 20 minutes or so the AEC gets confused and 
has to be manually reset. And while I don't have any "hard data" to back 
it up, it is my perception that users with ASIO (all sampled on one card 
with synchronous clock) get much better echo cancellation.

PS: Unless it was made clear earlier; you don't need to sample the 
speakers unless you want to also cancel out sounds made by other programs. 
If all you want is to cancel out the sound of the "remote end", just feed 
the AEC the last frame you decoded and sent to the speakers.

Speex-dev mailing list
Speex-dev at xiph.org

More information about the Speex-dev mailing list