Speech enhancement on a microcontroller · SIH 2026
Removing engine, gunfire and wind noise from radio speech on a $4 microcontroller, for Smart India Hackathon 2026: speech 11.2 dB clearer, measured on the board. Team of 6.
Published 24 Aug 2026 · Updated 11 Oct 2026
- My part
- Capture firmware, on-device model, measurement rig (1 of 6)
- Team
- 6 · Smart India Hackathon 2026, problem 52
- Timeline
- Aug – Dec 2026
- Status
- Ongoing
- Links
- Firmware · Demo video · Raw measurements
- Skills
- Edge and low-resource systems, Embedded C · STM32 · Arduino
In short
- Problem
- Speech on soldiers’ radios is buried in engine, gunfire and wind noise. The brief asks for enhancement on the device itself that reaches 3 targets: signal-to-noise ratio above 15 dB, an intelligibility score above 0.85 and a quality score above 2.5.
- What I did
- Wrote the microphone capture firmware, fitted a compressed model onto the board and built the rig that measures it.
- Result
- Speech 11.2 dB clearer (target: 15 dB), intelligibility 0.87, quality 2.6, on 120 held-out clips; 31 ms of delay at 38 mW. Clarity is still below target.
- How to check
- Demo video · firmware · raw measurements (CSV) · reproduce with mic_lab.py
Requirements: 3 audio targets, 128 KB of memory, under 40 ms
- Signal-to-noise ratio improved by more than 15 dB; intelligibility above 0.85; quality above 2.5
- Across steady, changing and sudden noise: engine, wind, gunfire
- Board: STM32F411, a 100 MHz Arm Cortex-M4F with 128 KB RAM and 512 KB flash, no external memory
- End-to-end delay under 40 ms, so a conversation still feels natural
Block diagram: why an STM32F411, not an ESP32-S3
We tried an ESP32-S3 first. The STM32F411 won because its DMA timing is deterministic and CMSIS-NN runs the model faster on it.
Measurements: 11.2 dB clearer, 31 ms, 38 mW on the board
| Metric | Result | Target | How measured |
|---|---|---|---|
| Speech clarity (SNR gain) | +11.2 dB | > 15 dB | 120 held-out clips, 3 noise types |
| Intelligibility (STOI) | 0.87 | > 0.85 | pystoi, same 120 clips |
| Quality (PESQ) | 2.6 | > 2.5 | pesq, same 120 clips |
| End-to-end delay | 31 ms | < 40 ms | click track in vs out on a 2-channel scope |
| Power | 38 mW | — | INA219 on the 3.3 V rail, 60 s average |
| Flash / RAM | 214 / 97 KB | 512 / 128 KB | arm-none-eabi-size |
Debugging: why the samples were off by one bit
Symptom: the captured audio was loud crackle; the values looked right but shifted. Hypotheses: wrong sample rate, wrong word length, wrong I²S standard. Measurement: a logic-analyser capture of the clock and data lines.
Root cause and fix: the INMP441 sends 24-bit data one clock after the word-select line changes (the Philips standard), but the peripheral was set to MSB-justified. Switching the standard fixed it.
What broke: sudden noise like gunfire improves least
- What failed
- Sudden noise like gunfire improves by only 6.1 dB, against 11.2 dB overall.
- How I found out
- Splitting the 120 test clips by noise type.
- What I changed
- Moving the spectral transform to CMSIS-DSP to free 18 KB of RAM for a larger model.
- Still open
- Whether the larger model fits inside the 40 ms delay budget.
References
Credits. Arya Maddel, Jagdish Sonigra, Kashish Degaonkar, Parth Latke and Tanish Thakkar.
How I used AI tools. Used Claude to review the DMA code and draft this write-up; all measurements taken by hand.