This project was a spinoff of a workshop I created for MIT's Campus Preview Weekend, a 4 day event where admitted high school students get to visit MIT's campus and participate in a variety of activities. The workshop kit goal was to provide prospective students a taste of what embedded electronics is like by building their own audio spectrum visualizer. The visualizer consists of a microphone, microcontroller, and LED strip. Each LED on the LED strip shows the audio power spectral density around some frequency. To align with human perception of music, the frequency spacing between LEDs is logarithmic. To prototype the workshop kits, I ordered a strip of 120 individually addressable RGB LEDs. Due to the Fourier uncertainty principle, for acceptible temporal resolution, logarithmic spacing of frequency leaves disappointingly low frequency resolution for lower frequencies (given how many LEDs there are in the strip). To address this, I added a multiresolution FFT (which trades off additional latency / poor temporal resolution for lower frequency content to achieve better frequency resolution, while keeping the high temporal resolution for higher frequencies which don't need the frequency resolution boost).
The heavy lifting of this work is done by the KISS FFT library and PicoLED library. The data from the microphone is sampled at 48kHz with one of the ADCs onboard the Pi Pico, which transfers the samples to a sample buffer in memory with DMA. The main core (core0) of the Pi Pico is responsible for computing a "short" (default 512-point) and "medium" (default 2048-point) FFT of the ADC data. The second core (core1) is responsible for asynchronously computing a "long" (default 4096-point) FFT of the ADC data. Each portion of the LED strip then uses a subset of the transform coefficients from each resolution FFT --- the lower portion of the LED strip receives the lowest frequency content from the long FFT, the middle gets the lower/middle range frequency content from medium FFT, and the upper portion of the LED strip gets the high frequency content from the short FFT.