A real-time audio spectrum analyzer that visualizes sound frequencies on an OLED display. Built with STM32F411, INMP441 MEMS microphone, and SSD1306 display.
- Real-Time FFT Processing using ARM CMSIS-DSP (512-point)
- 8-Band Frequency Visualization with logarithmic scaling
- Peak Hold Effect for smooth, professional-looking bars
- DMA-Driven Audio Capture for zero CPU overhead
- 30+ FPS Display Update rate
- Low Latency (~40ms total pipeline)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ OLED Display (128x64) โ
โ โ
โ โโโโ โ
โ โโโโ โโโโ โโโโ โ
โ โโโโ โโโโ โโโโ โโโโ โ
โ โโโโ โโโโ โโโโ โโโโ โโโโ โ
โ โโโโ โโโโ โโโโ โโโโ โโโโ โโโโโ
โ โโโโ โโโโ โโโโ โโโโ โโโโ โโโโโ
โ 0 1 2 3 4 5 โ
โ Bass Mid Treble โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
(Add actual photo/GIF of your working project here)
| Component | Model | Quantity | Price (โน) |
|---|---|---|---|
| Microcontroller | STM32F411 (Black Pill) | 1 | 450 |
| MEMS Microphone | INMP441 | 1 | 180 |
| OLED Display | SSD1306 (128x64, SPI) | 1 | 350 |
| Breadboard | Standard | 1 | 50 |
| Jumper Wires | M-M, M-F | 20 | 30 |
| Total | โน1,060 |
- Logic Analyzer (~โน800) - for I2S debugging
- Oscilloscope access (university lab)
INMP441 STM32F411
VDD โโโโโโโโโบ 3.3V
GND โโโโโโโโโบ GND
WS โโโโโโโโโบ PA4 (I2S2_WS)
SCK โโโโโโโโโบ PB13 (I2S2_CK) โ NOT PB10 (conflict with I2C2)
SD โโโโโโโโโบ PC3 (I2S2_SD)
L/R โโโโโโโโโบ GND (Left channel)
SSD1306 STM32F411
VCC โโโโโโโโโบ 3.3V
GND โโโโโโโโโบ GND
SCL โโโโโโโโโบ PB10 (I2C2_SCL)
SDA โโโโโโโโโบ PB3 (I2C2_SDA)
git clone https://github.com/yourusername/audio-spectrum-analyzer.git
cd audio-spectrum-analyzer- File โ Open Projects from File System
- Select the project folder
- Click Finish
Open the .ioc file and verify:
I2S2 Settings:
- Mode: Master Receive
- Standard: Philips I2S
- Data Format: 24 bits
- Sample Rate: 44.1 kHz
- DMA: Circular mode, High priority
I2C2 Settings:
- Speed Mode: Fast Mode (400 kHz)
- Clock Speed: 400000
- Addressing Mode: 7-bit
Critical step - don't skip!
- Right-click project โ Properties
- C/C++ Build โ Settings โ MCU Settings
- Check "Use float with printf"
- Project โ Manage Middleware โ CMSIS โ DSP โ
- Add defines:
ARM_MATH_CM4,__FPU_PRESENT=1
# In STM32CubeIDE
Project โ Build All (Ctrl+B)
Run โ Debug (F11)- Power on STM32
- Play music near the microphone
- Watch the spectrum bars dance! ๐ถ
Sound_analyzer/
โโโ README.md โ You are here
โโโ README_SETUP.md โ Detailed setup guide
โโโ LICENSE โ MIT License
โโโ .gitignore โ Git ignore rules
โ
โโโ MIC/ โ I2S microphone driver
โ โโโ i2s_mic.h
โ โโโ i2s_mic.c
โ
โโโ OLED/ โ SSD1306 display driver (I2C)
โ โโโ ssd1306.h / .c
โ โโโ ssd1306_fonts.h / .c
โ โโโ ssd1306_conf.h โ Active config (I2C2)
โ โโโ ssd1306_conf_i2c.h โ I2C config backup
โ
โโโ FFT/ โ FFT processing (CMSIS-DSP)
โ โโโ fft_processor.h / .c โ CMSIS-DSP version (~1.5 ms)
โ โโโ fft_processor_simple.h / .c โ Fallback (~15 ms)
โ
โโโ SPECTRUM/ โ Frequency band analyzer
โ โโโ spectrum.h
โ โโโ spectrum.c
โ
โโโ DISPLAY/ โ Spectrum visualization
โ โโโ spectrum_display.h
โ โโโ spectrum_display.c
โ
โโโ MAIN_EXAMPLE/ โ Integration examples
โโโ main_integration_example.c โ Primary (I2C2 OLED)
โโโ main_i2c_version.c โ Full self-contained version
โโโโโโโโโโโโโโโ
โ INMP441 โ I2S Digital Microphone
โ 24-bit โ 44.1 kHz sampling
โโโโโโโโฌโโโโโโโ
โ I2S DMA (512 samples)
โผ
โโโโโโโโโโโโโโโ
โ DMA Buffer โ Circular buffer, double-buffering
โ 512 samples โ
โโโโโโโโฌโโโโโโโ
โ Half/Full transfer interrupts
โผ
โโโโโโโโโโโโโโโ
โ FFT (CMSIS) โ 512-point FFT with Hanning window
โ ~1.5ms โ Magnitude spectrum (256 bins)
โโโโโโโโฌโโโโโโโ
โ Frequency domain data
โผ
โโโโโโโโโโโโโโโ
โ Frequency โ Map 256 bins โ 8 logarithmic bands
โ Mapping โ Bass, Mid, Treble separation
โโโโโโโโฌโโโโโโโ
โ Bar heights[8]
โผ
โโโโโโโโโโโโโโโ
โ Display โ Draw bars on SSD1306 via SPI
โ 30+ FPS โ Peak hold + smoothing effects
โโโโโโโโโโโโโโโ
| Bar | Freq Range | Description |
|---|---|---|
| 0 | 86-172 Hz | Sub-bass (kick drum) |
| 1 | 258-431 Hz | Bass guitar, bass notes |
| 2 | 517-861 Hz | Low midrange (male vocals) |
| 3 | 947-1550 Hz | Midrange (vocals, guitar) |
| 4 | 1636-2584 Hz | Upper midrange (female vocals) |
| 5 | 2670-4307 Hz | Presence (clarity, definition) |
| 6 | 4393-6890 Hz | Brilliance (cymbals, hi-hats) |
| 7 | 6977-10336 Hz | Air (sparkle, ambience) |
Edit SPECTRUM/spectrum.c:
#define SCALE_FACTOR 3.5f // Increase for taller bars (try 2.0-6.0)
#define MIN_THRESHOLD 0.01f // Lower for more sensitivity#define SMOOTHING_FACTOR 0.7f // 0.0 = no smooth, 0.9 = very smooth
#define PEAK_DECAY_RATE 0.95f // How fast peaks fall (0.9-0.99)In main loop:
// Simple bars
DISPLAY_DrawBars(bar_heights);
// Bars with peak hold (recommended)
DISPLAY_DrawBarsWithPeaks(bar_heights, peaks);
// Custom style
DISPLAY_DrawSpectrum(bars, peaks, STYLE_OUTLINED_BARS);| Metric | Value |
|---|---|
| Frame Rate | 30+ FPS |
| FFT Processing Time | ~1.5 ms |
| Display Update Time | ~15 ms |
| Total Latency | ~40 ms |
| CPU Usage | ~60% @ 100 MHz |
| Memory (RAM) | ~12 KB |
| Flash Usage | ~45 KB |
- Check SPI wiring (SCK, MOSI, CS, DC, RST)
- Verify
ssd1306_conf.hpin definitions match your wiring - Test with
ssd1306_TestAll()function
- Enable CMSIS-DSP library in project settings
- Add
ARM_MATH_CM4and__FPU_PRESENT=1defines - Rebuild project (clean first)
- Check I2S wiring (WS, SCK, SD)
- Verify microphone VDD = 3.3V (multimeter)
- Check DMA is in circular mode
- Print
mic_data_readyflag to verify data arrival
- Increase
SMOOTHING_FACTOR(try 0.8) - Adjust
SCALE_FACTOR(try 2.0-5.0) - Check for EMI/noise near microphone
See README_SETUP.md for detailed troubleshooting.
Without windowing, rectangular truncation of the signal causes spectral leakage - energy from one frequency bin spills into adjacent bins, creating false peaks.
The Hanning window smoothly tapers the signal to zero at edges:
w[n] = 0.5 * (1 - cos(2ฯn/N))This reduces sidelobes by ~31 dB, giving cleaner frequency separation.
Human hearing is logarithmic - we perceive octaves (doubling of frequency) as equal intervals. Mapping FFT bins logarithmically creates a more musically-relevant display.
Linear spacing would waste resolution on high frequencies we barely hear.
The 512-sample buffer is split into two halves:
- Half-transfer interrupt: Process samples 0-255 while DMA fills 256-511
- Full-transfer interrupt: Process samples 256-511 while DMA wraps to 0-255
This zero-copy design prevents audio dropouts and maximizes throughput.
Potential features to add:
- Beat Detection - Flash on bass hits
- Bluetooth Audio Input - Analyze phone music
- RGB LED Strip - WS2812B color visualization
- BPM Counter - Detect tempo from bass frequencies
- Multiple Display Modes - Waveform, waterfall, VU meter
- Auto-Gain Control - Adapt to loud/quiet environments
- PC Companion App - Python GUI for tuning parameters
Pull requests welcome! Areas for improvement:
- Optimize FFT for lower latency
- Add alternative windowing functions (Hamming, Blackman)
- Implement adaptive frequency ranges based on content
- Create PCB design for permanent installation
- Port to other STM32 families (F0, F7, H7)
MIT License - see LICENSE file for details.
Kushal Pitaliya
- GitHub: @kushalpitaliya
- ARM CMSIS-DSP team for optimized FFT algorithms
- afiskon for SSD1306 display library
- STMicroelectronics for HAL drivers
- InvenSense for INMP441 microphone design
- 3Blue1Brown for Fourier transform visualization
- Lines of Code: ~1,500
- Development Time: 8 weeks
- Components: 3 major ICs
- Total Cost: โน1,060
- Frame Rate: 30+ FPS
- Latency: <50 ms
Built with โค๏ธ using STM32, CMSIS-DSP, and lots of โ
- Setup Guide - Detailed installation instructions
- Implementation Plan - Development roadmap
- Example Code - Complete integration
- Troubleshooting - Common issues & fixes
โญ Star this repo if you found it useful!