Home grown digital sub filter

I need some brain gymnastics this weekend, so I was thinking of designing (from scratch, of course) a digital sub filter for the sub woofer I'm currently working on. I have a Teensy4.1 with an audio shield that should be up to the job.

My DSP-fu is a bit rusty, though, so maybe someone can do a sanity check?

Filter. I want to use a FIR due to its linear pass band phase (and therefore constant group delay). Unfortunately, very low frequency LP filters require extremely long FIRs, so I'm going to use the old decimate-filter-interpolate trick. I first decimate by 5, apply my filter, but with a 5 times higher relative cutoff frequency. Then I filter it again to interpolate. I experimented a bit it Octave, and it looks like 100 taps for the first filter and 50 for the second one yields decent results without using too much compute power. I'm not too worried about the aliasing bumps in the stop band, as they sit at about -55dB.
IMG_1955.jpg

1749822536526.png


Next I need some kind of phase correction. And correct (no pun intended) me if I'm wrong, but it's really the group delay and not the phase I want to correct. So instead of fiddling with all-pass filters, I should just use a simple digital delay, right?

And yes, I know I can buy a perfectly good module for this at AliExpress for less than a the price of a cup of coffee. But what's the fun and learning experience in that?
 
That basically means you allow intermodulation products between the signal and the lower sample rate to be about 0.18 % of the desired signal. Most people here would not even allow 0.18 % if it were mere harmonic distortion.
Just to clarify one thing: That's a filter curve, so those frequencies won't be present unless they're present in the content. So there will no new frequencies introduced. Just some of the higher frequency content leaking through the filter at very low levels. So it's quite different from intermodulation products.
 
You decimate the signal, producing spectral copies around all multiples of the reduced sample rate. When the interpolating filter only suppresses those by 55 dB, you have products at multiples of the lower sample rate plus and minus the signal frequency added to the signal. The system is not time-invariant anymore once you decimate, at least not with imperfect decimation and reconstruction filters.
 
The phase response is really only important in the passband, and a bit of the transition band. Phase response in the stopband can go totally haywire and you won't care because the amplitude is so low. So perhaps consider IIR with passband phase correction. There are threads here on diyAudio about exactly that.
 
I experimented with FIR filters, and they had to be ridiculously long to perform OK. So I settled for an SOS (Sections of Second Order) array Butterworth filters. Right now I'm using 4th order filters, but I can easily increase that. One issue I ran into is that coefficients in higher order SOS tend to get very small, so I ran out of integer precision and decided to do it using floats instead. The Teensy 4.1 I'm using has an FPU, so that wasn't a problem. I precalculated the filter parameters for cutoff frequencies from 50-250Hz in 1Hz increments, so changing frequencies is very easy.

I attached a simple FIFO-based delay at the end of it and called it good.

Demo time!



Here's the code. Not much to it. Based on AudioLib, but with my own filter code (because of the floating point thing).
https://github.com/prydin/sub_filter/tree/main/dsp/sub_filter/src