# Digital filter implementation in C (embedded)

I am a recent grad and my new project at work deals with taking the signal from an electret microphone and getting SPL values for 10 standard frequency bands.

The analog amplification/conditioning is completed so I am now trying to figure out what do in terms of sampling/filtering. My frequency bands are:

• 31.5, 63, 125, 250, 500, 1000, 2000, 4000, 8000, and 16000 Hz

I decided that I should be able to use a 160kHz sampling rate (apparently 5-10 * Nyquist rate is recommended according to my old notes) and use 10 2nd order Butterworth bandpass filters that were designed using mkfilter. After this point I am unsure how to proceed.

Would I simply use the 16kHz filter every sample, the 8kHz filter every 2 samples, the 4kHz filter every 4 samples and so on? ( I am getting these numbers by using 5*Nyquist rate for each band, e.g. 1/(8000Hz*2*5)/(1/160000Hz) ) ? Then I would then convert the values to a pressure and do the math necessary for a SPL measurement. Is there a better way to approach this? Is my understanding correct?

The hardware I am working with has a 48MHz clock and 32kB of flash and 4kB of RAM.

• Maybe have a look at FFT and/or the Goertzel algorithm. Commented Apr 25, 2016 at 11:35
• "has a 48MHz clock" - And how much time do you have to perform the calculations? At what frequency do you need new output values? Commented Apr 25, 2016 at 11:38

No, if you feed in a signal containing frequencies to 16 kHz, your filter will need to sample at at least 2*16 kHz for all bands. If you sample only at 160 kHz, you'll have to design each filter for that sampling rate.

You could use a lower sampling rate for the lower frequency filters, while keeping the sampling rate above the highest frequency present (16 kHz ?). Thus, taking every 2nd sample and using the 16 kHz (160 kHz sampling) would work for 8 kHz -- but conflicts with the rationale for choosing 5x oversampling in the 1st place (that's not strictly necessary -- it depends on the highest frequency components in the signal).

Note that if you extended this thought to the 31.5 Hz band, you'd use every 500th sample == 160k/500 = 320 Hz, which wouldn't work with the whole signal since it contains components to (and beyond ?) 16 kHz.

• Designing each filter for the specific band is not an issue for me because it is fairly easy to do with the software I mentioned. Do you think you could explain your last paragraph more? Why is it not okay to use a 320Hz sampling rate if I am trying to pass only the 32.5 Hz frequency? Commented Apr 25, 2016 at 1:48
• Because if you provide that filter with an input signal containing components above 160 Hz, they will alias down. So, for example, if there are any input signals at (320+32.5 = 352.5 Hz), they will be indistinguishable from real signals at 32.5 Hz. Your filter has to sample at 2x the INPUT signals, not the output. Commented Apr 25, 2016 at 3:41
• @LPace; If you used a bank of FIR filters, you could just use a low pass to always extract the highest octave, get the SPL from that, down sample one octave, and repeat. However, I'm afraid 32kb RAM might not be enough memory for that.
– Timo
Commented Apr 25, 2016 at 6:42
• @jp314 That was extremely helpful, thanks for clearing that up for me. So I guess I will have to store at least (1/32.5Hz or ~30ms) worth of data at 160kHz sampling in order to get an accurate RMS value of the slowest pressure wave (required for SPL measurement). That would amount to almost 5000 samples. Commented Apr 25, 2016 at 15:21
• @Timo Yes the RAM constraint made me learn towards the IIR implementation I have currently. Commented Apr 25, 2016 at 15:22