tags:

views:

318

answers:

4

How to subtract one audio wave from another? In general and in C# (or if we cannot do it in C# in C/C++)

I have sound wave A and sound wave B (BTW: they are in PCM) I want to subtract B from A

What do I need? Open Source Libs (NOT GPL, but LGPL will be ok) Tutorials on how to do such operation (with or without using libs) Articles on this topic

PS: it’s all about AEC…

A: 

Try this

BostonLogan
I don't think this answers the question. Seems like Ole Jak is asking about this: http://en.wikipedia.org/wiki/Acoustic_Echo_Cancelling
Fred Larson
A: 

http://stackoverflow.com/questions/1723563/acoustic-echo-cancellation-aec-in-wpf-with-c Asks a similar question and has an accepted answer. The suggested library does have some sort of Echo Cancellation I think.

Unfortunately I don't haven't used any open source audio libraries. I have used Fmod to process audio before, I don't remember there being any AEC in it, but you can get access to the raw audio as it processes it and run your own code on it.

Glenn Condron
The linked question is by the same person...
dtb
Serves me right for not looking at the poster. Sorry about that.
Glenn Condron
I guess he's after the *Taxonomist* badge: http://stackoverflow.com/questions/tagged/aec
dtb
+4  A: 

If the samples are normalised to the same level, and are stored in a signed format such that the "zero level" is 0 or 0.0, the answer is fairly simple:

S_C = (S_A / 2) - (S_B / 2);

for each sample S_A and S_B in A and B.

If you are using unsigned values for the samples then you will need to do more work: first, you need to convert them to a signed value with a zero centre (eg, if you have 16 bit unsigned samples, subtract 32768 from each), then apply the formula, then convert them back to the unsigned format. Be careful of overflow - here's an example of how to do the conversions for the aforementioned 16 bit samples:

#define PCM_16U_ZERO 32768

short pcm_16u_to_16s(unsigned short u)
{
    /* Ensure that we never overflow a signed integer value */
    return (u < PCM_16U_ZERO) ? (short)u - PCM_16U_ZERO : (short)(u - PCM_16U_ZERO);
}

unsigned short pcm_16s_to_16u(short s)
{
    /* As long as we convert to unsigned before the addition, unsigned arithmetic
       does the right thing */
    return (unsigned short)s + PCM_16U_ZERO;
}
caf
Just curious: why `/ 2`?
dtb
Subtracting two signals is the same as adding one signal to a 180-degree phase-shifted version of the other. The division by two keeps the power (level) of the resulting signal the same as the individual input signals - if you don't do it, then your resulting signal will be effectively amplified by 6dB (and is likely to clip).
caf
+1  A: 

http://www.mega-nerd.com/libsndfile/

snlee