Close

Back to single-precision with ‘Second-Order Sections’

A project log for ESP32-I2S-SLM

Sound Level Meter with Arduino IDE, ESP32 and I2S MEMS microphone

Ivan KostoskiIvan Kostoski 11/22/2019 at 16:130 Comments

It turns out that if you 'breakup' the higher order IIR filters into series of Second-Order Sections (i.e. biquads), the filtering error does not accumulate as much. With 24-bit data, broken down filters and single-precision, the error induced by the A-weighting filter should be less than 0.5dB in worst case (20Hz). The monolithic 6th order ‘B/A’ transfer function had >7dB error at 20Hz with single-precision. 

As we are here to hack stuff, It is more likely that parts of this project will be integrated into other more complex projects, with many more sensors and functionality, instead of being used as standalone SLM, so I set my (over)optimization goal to leave as much as possible CPU time for other tasks. And instead of fighting with GCC to produce the code that I know is possible, the end result is going all the way to ESP32/Xtensa assembler...

Well, now you can lower the frequency of ESP32 down to 80MHz (i.e. for battery operation) and filtering and summation of I2S data will still take less than 15% of single core processing time. At 240MHz, filtering 1/8sec worth of samples with 2 x 6th-order IIR filters takes less than 5ms. The ESP32/GCC assembler implementation is in ‘sos-iir-filter.h’ and in the comments you can find more or less equivalent C code. The sources from esp-dsp were quite helpful. The CPU ISAs these days… let’s just say that my beginnings involved writing 6502 assembler…

Support for Knowles SPH0645LM4H-B 

I received a sample of this microphone so I decided to try it out. First, it is not quite compatible with ESP32 I2S peripheral and you need to apply ‘dirty hack’ (directly manipulating ESP32 registers, see the code) to even receive the MSB of I2S data. Additionally, the received values have ‘DC bias’ (or offset) so calculating SPL RMS directly is not possible. If you apply DC-blocker filter (or more specifically, DC-Blocker SOS section), this bias can be filtered out.

While it finally works, in my humble opinion, this microphone is not very well suited for sound level measurement, mostly due to its limited dynamic range (18 valid bits in I2S data) and the errors that will be added by any IIR filters at lower amplitudes, no matter what kind of arithmetic precision you use.

Discussions