-4

I built a noise cancellation setup with two microphones and two different microphone preamplifiers that go to two different channels of a stereo recording.

Here is a sample

http://filestore.to/?d=U5FN2IH96K

I tried

char  ergebnis[80];                                                  
sprintf(ergebnis, "%s.neu.raw", Datei);
FILE* ausgabe = fopen(ergebnis, "wb");
FILE* f = fopen(Datei, "rb");

if (f == NULL) 
{
    return;
}

int i   = -1;
int r1  =  0;
int r2  =  0;
int l1  =  0;
int l2  =  0;
int l   =  0;
int r   =  0;
int wo  =  0;
int dif =  0;

while (wo != EOF) 
{
    wo = getc(f);  
    i++;

    if (i == 0) 
    {
        r1 = (unsigned)wo;
    }

    if (i == 1) 
    {
        r2 = (unsigned)wo;
        r = (r2 << 8) + r1;   //r1 | r2 << 8;  
    }

    if (i == 2) 
    {
        l1 = (unsigned)wo;
    }

    if (i == 3) 
    {
        l2  = (unsigned)wo;
        l   = (l2 << 8) + l1;   //l1 | l2 << 8;   
        dif = r - (l * 2);
        putc((char)( (unsigned)dif       & 0xff), ausgabe);
        putc((char)(((unsigned)dif >> 8) & 0xff), ausgabe); 
        i = -1;
    }
} 

when the magic happens in

dif = r - (l * 2);

But this does not eliminate the noise surrounding it, all it does is create crackling sounds.

How could I approach this task with my setup instead? I prefer practical solutions over "read this paper only the author of the paper understands".

While we are at it, how do I normalize the final mono output to make it as loud as possible without clipping?

Brutus Cruciatus
  • 404
  • 3
  • 18

1 Answers1

2

I don't know why you would expect this

dif = r - (l * 2);

to cancel noise, but I can tell you why it "create[s] crackling sounds". The value in dif is often going to be out of range of 16-bit audio. When this happens, your simple conversion function:

    putc((char)( (unsigned)dif       & 0xff), ausgabe);
    putc((char)(((unsigned)dif >> 8) & 0xff), ausgabe); 

will fail. Instead of a smooth curve, your audio will jump from large positive to large negative values. If that confuses you, maybe this post will help.

Even if you solve that problem, a few things aren't clear, not the least of which is that for active noise canceling to work you usually assume that one mike provides a source of noise and the other provides signal + noise. Which is which in this case? Did you just place two mikes next to each other and hope to hear some sound source with less ambient noise after some simple arithmetic? That won't work, since they are both hearing different combinations of signal and noise (not just in amplitude, but time as well). So you need to answer 1. which mike is the source of signal and which is the source of noise? 2. what kind of noise are you trying to cancel? 3. what distinguishes the mikes in their ability to hear signal and noise? 4. etc.

Update: I'm still not clear on your setup, but here's something that might help:

You might have a setup where your signal is strong in one mike and weak in the other, and a noise is applied to both mikes. In all likelyhood, there will be signal leak into both mikes. Nevertheless, we will assume

l = noise1
r = signal + noise2

Note that I have not assumed the same noise values for l and r, this reflects the reality that the two mikes will be picking up different noise values due to time delays and other factors. However, it is often the case (and may or may not be the case in your setup) that noise1 and noise2 are correlated at low frequencies. Thus, if we have a low pass filter, lp, we can achieve some noise reduction in the low frequencies as follows:

out = r - lp(l) = signal + noise2 - lp(noise1)

This, of course, assumes that the noise level at l and r is the same, which it may or may not be, depending on your setup. You may want to leave a manual parameter for this purpose for manual tuning at the end:

out = r - g*lp(l)

where g is your tuning parameter and close to 1. I believe in some high-end noise reduction systems, g is constantly tuned automatically.

Selecting a cutoff frequency for your lp filter is all that remains. An approximation you could use is that the highest frequency you can cancel has a wavelength equal to 1/4 the distance between the mikes. Of course, I'm REALLY waving my arms with that, because it depends a lot on where the sound is coming from, how directional your mikes are and so on, but it's a starting point.

Sample calculation for mikes that are 3 inches apart:

Speed of sound = 13 397 inches / sec
desired wavelength = 4*3 inches = 12 inches
frequency = 13,397 / 12 = 1116 Hz

So your filter should have a cutoff frequency of 1116 Hz if the mikes are 3 inches apart.

Expect this setup to cancel a significant amount of your signal below the cutoff frequency as well, if there is bleed.

Bjorn Roche
  • 11,279
  • 6
  • 36
  • 58
  • Further more, the OP's original approach takes no account of phase relationships between the two signals - which will occur due to the spacial placement of the two mics and the resultant different path lengths to the audio. Here it is assumed that noise signal is incident on both microphones in the same sample. For this to be the case, the pathlegnth difference would have to be somewhat less than 7mm. – marko Jul 19 '13 at 15:22
  • As I said "not just in amplitude, but time as well". – Bjorn Roche Jul 19 '13 at 18:34
  • @BjornRoche "Which is which in this case?" l = noise, r = source + noise. Setup is like this: http://zuz.mimekunst.com/Nutzerbilder/1374261145.png The kind of noise is water falling down on ceramics. What is your recommendation for dealing with the crackling sounds? – Brutus Cruciatus Jul 19 '13 at 19:22
  • @Marko I agree. I did not include the phase difference. Given the raw file I attached how would you determine it. It should stay constant once figured out I presume given a fixed setup but slightly moving voice source. – Brutus Cruciatus Jul 19 '13 at 19:26
  • @BjornRoche The amplitude should be fixed by the 2 in dif = r - (l * 2); – Brutus Cruciatus Jul 19 '13 at 19:28
  • @PeakReconstructionWavelength correlation might be one way of determining the delay between signals. However, the premise you based your code on above (e.g. super-position with one signal inverted) is totally broken, and no amount of delay compensation is going to help with that. Please go and read the literature on the subject, and if necessary learn the theory necessary - you are not going to get a silver bullet here on StackOverflow. And any solution you do get will not be a few lines of code. – marko Jul 19 '13 at 19:42
  • @Marko Okay, which paper is the closest to my problem that you can recommend? – Brutus Cruciatus Jul 19 '13 at 20:59
  • @PeakReconstructionWavelength the diagram you link makes no sense. Also, your formula most definitely does NOT fix the amplitude; it causes the problem. – Bjorn Roche Jul 19 '13 at 23:12
  • @PeakReconstructionWavelength: marko is right. There are a number of techniques for this but they are all complex, and I'm not aware of any libraries. Assuming your mikes really do represent l=noise and r=signal+noise, (eg one mike right next to the source, one mike further away or directional mikes pointing in different directions, etc), the noise will likely be more correlated in the low frequencies (the cuttoff will depend on, among other things, how far apart the mikes are). You could low-pass the l signal and subtract it from r and you might get something, but it depends on your setup. – Bjorn Roche Jul 19 '13 at 23:30
  • @BjornRoche "the diagram you link makes no sense" aka "I don't get it but I would never look for the reason in myself. If I don't get it, it must make no sense". No, sir, it makes sense, it just doesn't make sense to you. If you write something like that you need to clarify, why you don't understand it. – Brutus Cruciatus Jul 20 '13 at 00:16
  • Im glad the diagram makes sense to you, but the onus is on you, as the person who wants free help, to make yourself clear and understood, and that diagram does so little you are best off starting over. – Bjorn Roche Jul 20 '13 at 13:13
  • @BjornRoche Tell me what you don't understand, I am willing to elaborate but right now I cannot understand why anyone wouldn't understand it so I have no idea what to explain. But for the sake of improving matters look at this photo http://i.imgur.com/b5NWdF4.jpg As it is badly lit I drew some lines to make the box' position clear. You see microphone1(circle above, equals r) and microphone2(circle below, equals l). – Brutus Cruciatus Jul 21 '13 at 22:27
  • It appears you have a box of some sort with one mike on top, and one mike on the side. We still don't know what kind of mikes these are, where your noise source is, or where your signal source is. After 12 comments and not enough info to answer this, I'm just going to update my answer with something general. – Bjorn Roche Jul 22 '13 at 00:00
  • @BjornRoche Electret-microphones. The noise source is about 1.5 metres away from microphone2(l), facing microphone2(l), the signal source is about 10 centimetres away from microphone1(r), facing microphone1(r). "After 12 comments and not enough info to answer this, I'm just going to update my answer with something general." Listen, tone it down. You need to ask the right questions to get answers. You started doing this and I replied to every real question of yours. The microphones look like http://elektronikhandel-online.net/.media/145108546997.png they are not designed to be directional mikes – Brutus Cruciatus Jul 22 '13 at 01:18
  • @BjornRoche Diagonal distance between the mikes is 7 centimeters aka 2,75 inches. According to your calculation I have a cutoff frequency of 1215 Hz. So what you mean is: create a software lowpass filter with a cutoff-frequency of 1215 Hz, then use dif = r - g*lp(l) instead of dif = r - (l * 2);. Would you use http://stackoverflow.com/questions/13882038/implementing-simple-high-and-low-pass-filters-in-c for that with float RC = 1.0/(1215*2*3.14);? – Brutus Cruciatus Jul 22 '13 at 01:29
  • You could use that filter. Better to use a higher order filter. Second order should do. http://blog.bjornroche.com/2012/08/basic-audio-eqs.html – Bjorn Roche Jul 22 '13 at 13:33
  • With the mikes that close and the sound sources that far, especially if they are omni-directional, the assumption of l = noise1 & r = signal + noise2 is violated. – Bjorn Roche Jul 22 '13 at 13:36
  • @BjornRoche As I could not understand your code I used my link. I don't hear much difference but at least no clipping. Here's my code: http://pastebin.com/TkxgtXZP Please tell me whether it's doing what it's supposed to do according to my goal in this thread. PS: How to normalize the output? What's the max value for dif (+ and -) without clipping? – Brutus Cruciatus Jul 26 '13 at 13:45