NLMS Audio Echo Cancellation 2016 Code Modification

Not open for further replies.


New member
Hi All,

This is my first time posting to any forum so I apologize if I break any norms...

I am a mechanical engineer that is in way over his head by taking on a DSP project. I am trying to make a voice amplification device for my grandfather who has lost a lot of his volume due to a tracheostomy surgery. After looking online for voice amplifiers on the market, I was rather disappointed and felt I could design something that would look less "old-man", be easier to use and adjust, and provide better quality sound. I am not sure what the final package will look like (it might be something that goes around his neck, or if I can make it small enough possibly something he can hide in his breast pocket or something), but the electrical system is going to be a Teensy 4.0 w/ 2 audio shields controlling 2 cheap electret microphones, which will send the I2S output to a class D amplifier which will drive 2 speakers (my original thought is two but if I shrink the form factor down it might go to one). My goal is to basically mimic hearing aid designs where there will be two microphones close to each other, but one will be slightly closer to his mouth/throat to pick up more voice, and the other will be slightly further away to then cancel out the system output and any other noise.

I have been working on this for about a month using the audio library and am very comfortable adjusting the parameters of the microphones and using mixers to combine and invert the signals. My latest code attempt left me able to almost completely cancel out my voice (as a test to see if the inversion was working) however I was still getting an insane amount of audio howling. After doing a lot of research I came to the conclusion I need an adaptive algorithm to take on this issue, but I am not nearly skilled enough to implement anything I found in research papers into actual code. This led me to an old 2016 post on this site (that I read earlier on but it seemed too complicated at the time) which used NLMS Audio Echo Cancellation between two microphone-speaker setups a certain distance away, but used two Teensy's. I am guessing the reasoning for the two Teensy's was a long transmission distance, but where my project will only have transmission distance of a few inches I want to modify the code to accommodate 2 mics with 1 Teensy + 2 Audio Shields.

Here is the link to the 2016 Post:

Here is the link to the GitHub page:

After combing through the code I have a pretty good idea at what is going on, however I am completely clueless as to how to modify the I2S inputs so that I can add a microphone which will fill the [x] signal array to be cancelled out. Right now it just says it is pulling from the far end transmission, but in reading through the thread it doesn't seem like he ever implemented the second Teensy so I can't tell where it left off. Can anyone help me in figuring out how to add the second microphone input?

To anyone seeing this, I have been banging my head against the wall for the past 4 days, but i finally have the code to where I can compile without errors.

Now my issue is I am not getting audio out, so I believe I am doing something wrong with the queues and playing the buffer. Can someone please review and see if I am calling for something to play incorrectly?

Attached is the code and a screenshot from the audio design tool


View attachment NLMS2.h
View attachment MicAquire_Rev9.ino
2021-03-08 Audio Design Tool.jpg
Only had time to look for a couple min, but saw this:

      if(queue1.available() ==1) {// if availabe copy 128 block to array and get out of while loop

You probably should check for >= instead of ==. If the queue happens to accumulate more than 1 block available for you to read, your code will forever wait for a condition that can't become true because more incoming audio will only increase the number of queued blocks. Well, until all the AudioMemory you allocated is filled up.
Not open for further replies.