Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 6 of 6

Thread: Issue Subtracting Left Line-In from Right Line-in on Audio Shield to Noise Cancel

Hybrid View

  1. #1
    Junior Member
    Join Date
    Jan 2020
    Posts
    4

    Issue Subtracting Left Line-In from Right Line-in on Audio Shield to Noise Cancel

    Hey All,

    I am been searching the forums and did not see this issue discussed relating to my project. Maybe I missed it, but your help would be appreciated.

    My project is to remove ambient noise from a mic input, so that the output is *nearly* voice only. I have two mics, one that is for my voice and one is for background noise. I am using a custom preamp board to bring the sound into Line-in Left and Right on the Audio Shield from the mics. I have a Teensy 4.0 performing the math to subtract the ambient noise mic (Line-in Left) from the voice mic (Line-in Right) and my output is through the headphone jack on the Audio Shield. See block diagram below for set up. Also picture below for actual board setup. Code is also below.

    My issue:
    I cannot seem to get Line-in Left (background noise) to subtract from Line-in Right (voice + background noise) to produce my voice only output.

    What I have verified:
    1. I verified receiving sound through both mics independently to my headphones using Audio Shield and Teensy.
    2. I verified reducing output to zero volume (verified by rms1) via subtraction if: (1) I use just one channel (e.g. ch0 of i2s1) as the source to both inputs to Mixer 1 (0 and 1).


    #2 tells me that what I am trying to do is possible. So that is encouraging.

    What I am having trouble with:
    1. See above - Pass
    2. See above - Pass
    3. Using the same sound through both mics to reduce output to zero volume via subtraction - Fail
    4. Using one mic for voice + background sound and the other for background sound to output voice only via subtraction
    5. Testing outside in real world


    I would appreciate any direction or help in this manner to solve issue #3. I will do the homework to figure this out, just need to know where to look.

    Thanks.

    Block diagram
    Click image for larger version. 

Name:	BackgroundNoiseRemovalSetup.jpg 
Views:	9 
Size:	50.7 KB 
ID:	18854

    Actual board setup
    Click image for larger version. 

Name:	actualsetup2.jpg 
Views:	10 
Size:	71.8 KB 
ID:	18855

    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioInputI2S            i2s1;           
    AudioAmplifier           amp1;           
    AudioMixer4              mixer1;         
    AudioOutputI2S           i2s2;
    AudioAnalyzeRMS          rms1;
    AudioAnalyzePeak         peak1;
    AudioConnection          patchCord1(i2s1, 0, amp1, 0);
    //AudioConnection          patchCord2(i2s1, 0, mixer1, 1);   //same Channel, test cancelation
    AudioConnection          patchCord2(i2s1, 1, mixer1, 1); //Two channels
    AudioConnection          patchCord3(amp1, 0, mixer1, 0);
    AudioConnection          patchCord4(mixer1, 0, i2s2, 0);
    AudioConnection          patchCord5(mixer1, 0, i2s2, 1);
    AudioConnection          patchCord6(mixer1, rms1);
    AudioConnection          patchCord7(mixer1, peak1);
    AudioControlSGTL5000     sgtl5000_1; 
    // GUItool: end automatically generated code
    
    void setup() {
      // Audio connections require memory to work.  For more
      // detailed information, see the MemoryAndCpuUsage example
      AudioMemory(15);
      Serial.begin(9600);
    
      // Enable the audio shield, select input, and enable output
      sgtl5000_1.enable();
      sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);
      sgtl5000_1.volume(0.5);
    
      //Amplify channel 0
      amp1.gain(-0.5);
    
      //Mixer setting
      mixer1.gain(0, 0.5);
      mixer1.gain(1, 0.5);
      
    }
    
    elapsedMillis volmsec=0;
    String amp_text;
    float amp_value;
    
    float rms_amp;
    float peak_amp;
    
    void loop() {
      // Adjust amp of background noise coming in
      // Keyboard input for amp value
      // Run every 50 msecs
      if (volmsec > 50) 
      {
        if (Serial.available())
        {
            amp_text = Serial.readStringUntil('\n');
            Serial.print(amp_text + " ");
            amp_value = amp_text.toFloat();
            Serial.println(-amp_value);
            amp1.gain(-amp_value);
        }
        
        // Result - verify cancelation of sound
        rms_amp = rms1.read() * 30.0;
        Serial.print(rms_amp);
        Serial.print(" ");
        peak_amp = peak1.read() * 30.0;
        Serial.println(peak_amp);
        volmsec = 0;
      }
    }
    Last edited by enphoti; 01-24-2020 at 08:23 PM. Reason: Clarification

  2. #2
    Hello I've no experience here, but the first thing that comes to my mind is - is there a time difference between left and right signals? This could be introduced any where in the signal path including processing on the Teensy. How about amp1? Could this introduce a delay or are the sample blocks invariant at this point, after i2s1, and dealt with together? Can you analyse the signals just before they go into the audio board? Is the background noise going into both mics the same? A 1m position difference is 3ms at the speed of sound. I think what you're doing may be quite hard to achieve physically rather than electronically. Noise-cancelling headphones have mics and transducers right next to each other, your mics presumably aren't.
    Last edited by UHF; 01-25-2020 at 01:15 AM.

  3. #3
    Junior Member
    Join Date
    Jan 2020
    Posts
    4
    Quote Originally Posted by UHF View Post
    Hello I've no experience here, but the first thing that comes to my mind is - is there a time difference between left and right signals?
    UHF, this is what I am thinking also, I think the sampling of two channels happens sequentially, resulting in a large enough time delay where the same point is not being canceled. However, I should experience some cancellation, even with milliseconds of delay...I need to measure things more closely.

    This could be introduced any where in the signal path including processing on the Teensy. How about amp1? Could this introduce a delay or are the sample blocks invariant at this point, after i2s1, and dealt with together?
    I don't think that there is delay after i2s1 because of what I experienced in #2. Seems like once the signal passes through i2s1, the math is pretty quick, resulting in no practical time delay.

    Can you analyse the signals just before they go into the audio board? Is the background noise going into both mics the same? A 1m position difference is 3ms at the speed of sound. I think what you're doing may be quite hard to achieve physically rather than electronically. Noise-cancelling headphones have mics and transducers right next to each other, your mics presumably aren't.
    What you say is very interesting. There will be a delay if the mics are far apart. In my testing of #3 though, I actually have a speaker playing music with both mics inches apart, so I don't think the problem is mic distance at this point. I think I need to measure both channels separately and then measure my output to see if I can measure the time delay between the left and the right channels. Maybe it is as easy as adding a delay in the math.

  4. #4
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,252
    amp1 reduces the amplitude of the inverted signal by 0.5 but the non-inverted signal isn't attenuated at all.
    Try adding an amp in the non-inverted path and set it to 0.5. This should also ensure that there's no processing delay between the two paths.

    Pete

  5. #5
    Junior Member
    Join Date
    Jan 2020
    Posts
    4
    Pete, I don't think amp is causing the delay, as #2 indicates. When the same signal goes through both paths, I can achieve cancellation. But I will give it a try to see if I am missing something.

  6. #6
    Junior Member
    Join Date
    Jan 2020
    Posts
    4
    Update #1

    I did find two issues, but was only able to resolve Issue #1. Any thoughts on Issue #2?

    Issue #1. There was not a delay in i2s1, but looking at RMS graph (shown below), my mics were not equal. I added a 1.6 amp to make the amplitudes equal before the mixer. (solved)
    Issue #2. Mixer1 is not performing the math correctly. See graph below. I expected a cancellation to happen (mixer_out on graph), but rms5 (mixer output) equals rms2 (channel 1 input). very confusing. Any help here? (Technically RMS3 reads positive, but I assume that the inversion makes the signal negative, as shown in the graph. I could also be wrong here).

    Graph
    Click image for larger version. 

Name:	graph.png 
Views:	13 
Size:	124.4 KB 
ID:	18873

    Audio System set up
    Click image for larger version. 

Name:	audio system design setup.png 
Views:	12 
Size:	70.4 KB 
ID:	18874

    Code
    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // GUItool: begin automatically generated code
    AudioInputI2S            i2s1;           //xy=232.74998474121094,244
    AudioAnalyzeRMS          rms1;           //xy=414.1999969482422,111.19999694824219
    AudioAmplifier           amp1;           //xy=416.5000305175781,199
    AudioAmplifier           amp2;           //xy=422.20001220703125,314.20001220703125
    AudioAnalyzeRMS          rms2;           //xy=425.20001220703125,404.20001220703125
    AudioAnalyzePeak         peak1;          //xy=442.1999969482422,52.19999694824219
    AudioAnalyzePeak         peak2;          //xy=455.1999969482422,468.1999969482422
    AudioMixer4              mixer1;         //xy=591.5000610351562,300.25
    AudioAnalyzeRMS          rms3;           //xy=645.1999969482422,118.19999694824219
    AudioAnalyzeRMS          rms4;           //xy=660.1999969482422,417.1999969482422
    AudioOutputI2S           i2s2;           //xy=801.4999961853027,356.49999618530273
    AudioAnalyzePeak         peak3;          //xy=830.1999969482422,168.1999969482422
    AudioAnalyzeRMS          rms5;           //xy=831.1999969482422,230.1999969482422
    AudioConnection          patchCord1(i2s1, 0, amp1, 0);
    AudioConnection          patchCord2(i2s1, 0, rms1, 0);
    AudioConnection          patchCord3(i2s1, 0, peak1, 0);
    AudioConnection          patchCord4(i2s1, 1, amp2, 0);
    AudioConnection          patchCord5(i2s1, 1, rms2, 0);
    AudioConnection          patchCord6(i2s1, 1, peak2, 0);
    AudioConnection          patchCord7(amp1, 0, mixer1, 0);
    AudioConnection          patchCord8(amp1, rms3);
    AudioConnection          patchCord9(amp2, 0, mixer1, 1);
    AudioConnection          patchCord10(amp2, rms4);
    AudioConnection          patchCord11(mixer1, 0, i2s2, 0);
    AudioConnection          patchCord12(mixer1, 0, i2s2, 1);
    AudioConnection          patchCord13(mixer1, rms5);
    AudioConnection          patchCord14(mixer1, peak3);
    AudioControlSGTL5000     sgtl5000_1;     //xy=354.5,533.25
    // GUItool: end automatically generated code
    
    
    
    void setup() {
      // Audio connections require memory to work.  For more
      // detailed information, see the MemoryAndCpuUsage example
      AudioMemory(15);
      Serial.begin(9600);
    
      // Enable the audio shield, select input, and enable output
      sgtl5000_1.enable();
      sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);
      sgtl5000_1.volume(0.5);
    
      //Set amplification
      amp1.gain(-1.0); //Inversion
      amp2.gain(1.6); //Amplification per mics
    
      //Mixer setting to invert signal
      mixer1.gain(0, 0.3);
      mixer1.gain(1, 0.3);
    }
    
    elapsedMillis volmsec=0;
    String amp_text;
    float amp_value;
    
    float out_peak1;
    float out_peak2;
    float out_peak3;
    
    float out_rms1;
    float out_rms2;
    float out_rms3;
    float out_rms4;
    float out_rms5;
    float outrmsvar;
    
    
    void loop() {
      // Adjust amp of background noise coming in
      // Keyboard input for amp value
      // Run every 10 msecs
      if (volmsec > 10)
      {
        if (Serial.available())
        {
            amp_text = Serial.readStringUntil('\n');
            Serial.print(amp_text + " ");
            amp_value = amp_text.toFloat();
            Serial.println(-amp_value);
            amp1.gain(-amp_value);
        }
      
        //Adjust Signal 0 to be identical in amplitude to signal 1
        out_rms1 = rms1.read() * 30.0; // Signal 0
        out_rms2 = rms2.read() * 30.0; // Signal 1
        out_rms3 = rms3.read() * 30.0; // Signal 1
        out_rms4 = rms4.read() * 30.0; // Signal 1
        out_rms5 = rms5.read() * 30.0; // Signal 1
    
        Serial.print(out_rms1);
        Serial.print(" ");
        Serial.print(out_rms2);
        Serial.print(" ");
        Serial.print(out_rms3);
        Serial.print(" ");
        Serial.print(out_rms4);
        Serial.print(" ");
        Serial.print(out_rms5);
        Serial.print(" ");
    
        if(out_rms1>(out_rms2+.1) || out_rms1<(out_rms2-.1)) {
          outrmsvar = out_rms1/out_rms2;
          Serial.print(outrmsvar);
          Serial.print(" ");
        }
      
        // Result - verify
        out_peak1 = peak1.read() * 30.0; // Signal 0
        out_peak2 = peak2.read() * 30.0; // Signal 1
        out_peak3 = peak3.read() * 30.0; // Output
        Serial.print(out_peak1);
        Serial.print(" ");
        Serial.print(out_peak2);
        Serial.print(" ");
        Serial.println(out_peak3);
        volmsec = 0;
      }
    }
    Raw Data
    Time rms1 rms2 rms3 -rms3 rms4 rms5 Mixer_out
    7.5 1.95 1.07 1.95 -1.95 1.71 1.09 -0.072
    7.51 1.65 0.92 1.65 -1.65 1.46 0.93 -0.057
    7.52 1.68 0.92 1.68 -1.68 1.47 0.94 -0.063
    7.53 1.77 0.96 1.77 -1.77 1.54 0.98 -0.069
    7.54 1.4 0.76 1.4 -1.4 1.22 0.78 -0.054
    7.55 1.32 0.71 1.32 -1.32 1.14 0.73 -0.054
    7.56 1.15 0.65 1.15 -1.15 1.04 0.65 -0.033
    7.57 0.98 0.57 0.98 -0.98 0.91 0.56 -0.021
    7.58 1.02 0.58 1.02 -1.02 0.93 0.58 -0.027
    7.59 1.16 0.65 1.16 -1.16 1.04 0.66 -0.036
    7.6 1.1 0.61 1.1 -1.1 0.97 0.62 -0.039
    7.61 1.04 0.64 1.04 -1.04 1.02 0.61 -0.006
    7.62 1.19 0.65 1.19 -1.19 1.05 0.67 -0.042
    7.63 1.2 0.63 1.2 -1.2 1.01 0.66 -0.057
    7.64 1.95 1.1 1.95 -1.95 1.76 1.11 -0.057
    7.65 2.17 1.23 2.17 -2.17 1.97 1.23 -0.06
    7.66 2.5 1.37 2.5 -2.5 2.18 1.39 -0.096
    7.67 2.18 1.16 2.18 -2.18 1.85 1.2 -0.099
    7.68 2.1 1.18 2.1 -2.1 1.88 1.19 -0.066
    7.69 1.76 1 1.76 -1.76 1.6 0.99 -0.048
    7.7 1.82 1.11 1.82 -1.82 1.77 1.07 -0.015
    7.71 2.1 1.24 2.1 -2.1 1.98 1.22 -0.036
    7.72 2.04 1.24 2.04 -2.04 1.98 1.2 -0.018
    7.73 1.81 1.1 1.81 -1.81 1.76 1.06 -0.015
    7.74 2.09 1.23 2.09 -2.09 1.96 1.2 -0.039
    7.75 1.96 1.09 1.96 -1.96 1.74 1.1 -0.066
    7.76 1.79 1.05 1.79 -1.79 1.67 1.03 -0.036
    7.77 1.44 0.83 1.44 -1.44 1.33 0.82 -0.033
    7.78 1.55 0.94 1.55 -1.55 1.51 0.91 -0.012
    7.79 1.64 0.99 1.64 -1.64 1.58 0.96 -0.018
    7.8 1.58 0.93 1.58 -1.58 1.49 0.92 -0.027
    7.81 1.65 1 1.65 -1.65 1.6 0.97 -0.015
    7.82 1.79 1.03 1.79 -1.79 1.64 1.02 -0.045
    7.83 1.87 1.05 1.87 -1.87 1.69 1.06 -0.054
    7.84 1.95 1.1 1.95 -1.95 1.76 1.11 -0.057
    7.85 1.77 1.04 1.77 -1.77 1.66 1.02 -0.033
    7.86 1.8 1.06 1.8 -1.8 1.69 1.04 -0.033
    7.87 1.66 0.99 1.66 -1.66 1.59 0.97 -0.021
    7.88 1.82 1.08 1.82 -1.82 1.72 1.06 -0.03
    7.89 1.85 1.08 1.85 -1.85 1.72 1.06 -0.039
    7.9 1.55 0.85 1.55 -1.55 1.37 0.86 -0.054
    7.91 1.35 0.67 1.35 -1.35 1.08 0.71 -0.081
    7.92 1.24 0.64 1.24 -1.24 1.02 0.66 -0.066
    7.93 1.19 0.65 1.19 -1.19 1.04 0.65 -0.045
    7.94 0.94 0.49 0.94 -0.94 0.78 0.5 -0.048
    7.95 0.87 0.42 0.87 -0.87 0.68 0.44 -0.057
    7.96 0.75 0.36 0.75 -0.75 0.57 0.37 -0.054
    7.97 1.18 0.64 1.18 -1.18 1.02 0.65 -0.048
    7.98 1.47 0.8 1.47 -1.47 1.28 0.82 -0.057
    7.99 1.71 0.98 1.71 -1.71 1.57 0.98 -0.042
    8 1.71 0.96 1.71 -1.71 1.53 0.97 -0.054
    Last edited by enphoti; 01-26-2020 at 12:46 AM. Reason: Assumption

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •