Attempting to remove high frequencies using I2S microphone INMP441 and the teensy 4.1 board

gbutiri

New member
Is there a way to completely silence frequencies within a certain range? For example, if I wanted to completely silence frequencies over 400 Hz (for an experimental project), how would I do it. My current setup won't work. I've tested it with a tone generator and I can still hear it come through. I know there are ways to remove low frequencies, like bass and other vibrations, but what's the secret to remove high pitch frequencies?
Is there a different way to do it other that biquad filters? I've heard of the Finite Impulse Response (FIR) filter, but I'm not sure how I can implement that to fix my problem to remove frequencies above 400 Hz. Can anyone help?

Code:
#include <Audio.h>

// Define the audio objects
AudioInputI2S           audioInput;     // Digital audio input via I2S
AudioFilterBiquad       biquad1;        // First Biquad filter for low-pass
AudioFilterBiquad       biquad2;        // Second Biquad filter for sharper roll-off
AudioOutputI2S          audioOutput;    // Audio output via I2S
AudioConnection         patchCord1(audioInput, 0, biquad1, 0);
AudioConnection         patchCord2(biquad1, 0, biquad2, 0);
AudioConnection         patchCord3(biquad2, 0, audioOutput, 0); // Left channel
AudioConnection         patchCord4(biquad2, 0, audioOutput, 1); // Right channel (duplicated mono signal)
AudioControlSGTL5000    sgtl5000_1;     // Control object for the SGTL5000 codec

void setup() {
  Serial.begin(9600);
  AudioMemory(60);
  Serial.println("Audio system ready");

  sgtl5000_1.enable();          // Enable the SGTL5000
  sgtl5000_1.volume(0.5);       // Set a moderate volume level

  // Configure both Biquad filters for low-pass, for a steeper roll-off
  biquad1.setLowpass(0, 500, 0.707); // Channel, frequency (Hz), Q
  biquad2.setLowpass(0, 500, 0.707); // Apply the same configuration to the second filter
}

void loop() {
  // No need to actively do anything in the loop
}
 
You have a lowpass filter with a corner frequency of 500Hz, so all frequencies <500 Hz will pass and due to not sufficient steep roll-off also some frequencies above 500 Hz.
In order to remove 400 Hz and above, you must reduce the corner frequencies.
I would start with 350, or 300 Hz
 
You have a lowpass filter with a corner frequency of 500Hz, so all frequencies <500 Hz will pass and due to not sufficient steep roll-off also some frequencies above 500 Hz.
In order to remove 400 Hz and above, you must reduce the corner frequencies.
I would start with 350, or 300 Hz
Ah yes, thanks. I did notice the numbers in the code don't match what I said. I was testing several different frequencies. My mistake.

Just so I understand, in order for me to not have 400 pass through, I would have to specify a lower pass frequency of 350, or 300 Hz?

I added more byquad filters which improved the reduction. Is there no way to completely remove frequencies above a certain value? I get that it's a gradual drop off, but what I need is to completely remove audio at specific frequencies. I'm new to this, but I thought that you could remove certain frequencies, just the same way you can remove them using an equalizer. Is that not the same?

Sorry if I misunderstood how this works in advance, and thanks for your prompt reply.
 
but what I need is to completely remove audio at specific frequencies.

Sadly, filters just aren't anywhere near this good. They attenuate rather than "remove". They also phase shift, which may or may not matter for you, but do keep in mind as you try to optimize how quickly it rolls off amplitude with frequency, the more it (might) be doing unpleasant things to the time response of the frequencies it is passing.

If you want to greatly attenuate 400 Hz but have little (amplitude) impact on a very close frequency like 500 Hz, you'll need a pretty incredible number of biquad stages or FIR taps! Even then, working with frequencies that close might turn out to be an unrealistic expectation. Filters have a lot of trade-offs and usually the main trade-off to be made is what one can reasonably expect.
 
Last edited:
Not necessarily, use a Cauer (elliptical) filter, rather than cascading 2nd order Butterworth stages. You can get much steeper filter skirts this way, although phase distortion is higher and there is pass-band ripple. This is 6th order Cauer with 1dB pass-band ripple and 60dB stop-band attenuation - so 3 biquad stages.
Screenshot 2024-02-21 at 20.40.49.png


The biquad stage values are:
[[ 2.57103134e-03 1.21850431e-03 2.57103134e-03 1.00000000e+00
-1.67617676e+00 7.29217698e-01]
[ 1.00000000e+00 -1.17883704e+00 1.00000000e+00 1.00000000e+00
-1.64816183e+00 8.48316629e-01]
[ 1.00000000e+00 -1.44180422e+00 1.00000000e+00 1.00000000e+00
-1.64856344e+00 9.56693851e-01]]

All done with a little Python (attached)
 

Attachments

  • cauer.py.txt
    318 bytes · Views: 12
use a Cauer (elliptical) filter,

Maybe we should extend the biquad filter with more configuration functions? Today I believe we have those functions for only fairly simple 1st and 2nd order filters. Anything more complicated requires the tedious functions to set all the coefficients (for multiple stages), which is probably too high a barrier for most people to get a working filter.
 
Just give some Python examples for generating sos (second-order-sections aka biquad sections) with scipy.signal, very flexible, mirrors the functionality in Matlab... You probably don't want to lump this functionalty on the Teensy itself, especially with the heavy-lifting needed for FIR filter design.
 
As you're using a T4, you can use floating point operations. This means that you can use one of the floating point extensions of the Audio library, like the OpenAudio or Tympan libraries. These have options for steeper filter cutoffs, including frequency-domain (ie. FFT->IFFT) filtering that, while not the most efficient way to do filtering, is a lot easier to understand as a new person.

Chip
 
If you were to use the OpenAudio library, you'd use this example...


It does a lowpass filter in the Frequency Domain. The example has the cutoff at 1000 Hz, but you can clearly see where you can change the value to whatever you want.

Chip
 
Back
Top