stm32h7
STM32H755 Granular Synthesizer
A real-time granular synthesizer running on the Cortex-M7 core of an STM32H755 dual-core MCU. Audio streams in and out over USB (UAC2 + MIDI composite device), with a browser-based control panel for parameter tweaking and monitoring.
What It Does
PC audio (YouTube, a DAW, anything) routes through the STM32 via USB Audio. The firmware captures incoming audio into a circular source buffer, then a 32-voice granular engine chops it into tiny overlapping grains with controllable density, size, spray, speed, and stereo spread. An FX chain (filter, ping-pong delay, Freeverb reverb) processes the output before sending it back to the PC over USB. A web UI provides sliders, transport controls, file playback, recording, and real-time performance telemetry.
Hardware
- Board: NUCLEO-H755ZI-Q (STM32H755ZIT6, Cortex-M7 @ 480 MHz)
- USB Audio/MIDI: CN13 (user USB port) — not the ST-LINK port
- Display: SSD1306 128x64 OLED via I2C1 (PB8/PB9)
- Power: SMPS only — do NOT configure for LDO or the board bricks
Features
- Granular engine: 32 simultaneous grains, Hann windowing, zero-crossing grain start, bipolar speed (-2x to +2x with reverse), speed scatter/randomize
- FX chain: Biquad LPF → stereo ping-pong delay (500ms max) → Freeverb
- USB composite device: UAC2 stereo 48 kHz/16-bit (in + out) + MIDI
- Web control panel: Real-time sliders, keyboard shortcuts, file playback, recording, preset import/export, performance telemetry
- OLED display: Grain visualization, CPU usage, active grain count
- Telemetry: 10 Hz MIDI CC stream with CPU %, active grains, peak/RMS levels, buffer stats
Architecture
PC Audio ──→ USB OUT ──→ Source Buffer (AXI SRAM, 250K samples)
│
▼
32-voice Granular Engine
│
▼
FX: LPF → Delay → Reverb
│
▼
USB IN ──→ PC Speakers (via PulseAudio loopback)
│
▼
Web UI ←── MIDI CC telemetry
Memory Layout
| Region | Address | Size | Usage |
|---|---|---|---|
| FLASH | 0x08000000 | 1 MB | Firmware code |
| DTCM | 0x20000000 | 128 KB | Stack, BSS, static data |
| AXI RAM | 0x24000000 | 512 KB | TinyUSB buffers + source buffer |
| SRAM1 | 0x30000000 | 128 KB | DMA buffers (OLED I2C) |
| SRAM2 | 0x30020000 | 128 KB | Delay line buffers (int16) |
| SRAM3 | 0x30040000 | 32 KB | Reverb comb/allpass buffers |
Source Files
| File | Purpose |
|---|---|
src/main.c |
Superloop, USB callbacks, DWT profiling, telemetry, OLED |
src/granular.c |
32-voice granular engine |
src/fx.c |
FX chain: biquad LPF, ping-pong delay, Freeverb |
src/ssd1306.c |
SSD1306 OLED driver (DMA + polling) |
src/i2c.c |
I2C1 peripheral driver |
src/usb_descriptors.c |
USB Audio + MIDI composite descriptor |
src/system_stm32h7xx.c |
Clock tree, PLL, SMPS power config |
web/index.html |
Browser control panel (Web MIDI API) |
Build & Flash
Requires Docker (the toolchain runs in a container).
# Build and flash
docker compose run --rm dev /workspace/scripts/flash.sh
# USB must be on CN13 (user USB), not the ST-LINK port
The flash script builds with CMake + Ninja using arm-none-eabi-gcc, then flashes via OpenOCD.
Audio Routing
After flashing, set up PulseAudio loopback routing and the web server:
./scripts/audio-setup.sh # set up routing + start web server
./scripts/audio-setup.sh --teardown # undo everything
This configures:
- STM32 as the default PulseAudio sink (all PC audio routes through it)
- Loopback from STM32 source back to PC speakers
- Web server on
http://localhost:8000
Web UI
Open http://localhost:8000 in Chrome (requires Web MIDI API support).
- Auto-connects to the Granular Synth MIDI device
- Transport: Record, Test Tone, File Playback, Loop
- Parameter sliders with click-to-edit values
- Keyboard shortcuts: Space (record), T (tone), P (play), S (stop), L (loop), Esc (stop all)
- Performance panel: CPU %, active grains, L/R level meters
- Preset import/export (JSON)
MIDI CC Map (Channel 1)
| CC | Parameter | Range |
|---|---|---|
| 1 | Grain Density | 1–200 Hz |
| 2 | Grain Size | 10–1000 ms |
| 3 | Spray | 0–100% |
| 4 | Speed | -2.0x to +2.0x |
| 5 | Scan Position | 0–100% |
| 7 | Volume | 0–100% |
| 8 | Dry/Wet | 0–100% |
| 10 | Stereo Spread | 0–100% |
| 12 | Randomize | 0–100% |
[README truncated]
Recent Activity
4cbaf8freverb working nicely (2026-03-12)1e14c82added readme (2026-03-12)1721a43added fx see to work coul ddo with more testing (2026-03-11)0c0c91breverse grain playback with bidirectional speed slider.. (2026-03-11)d6af94bgrain visulaiser working beautifully (2026-03-11)
Languages
- C: 51%
- HTML: 24%
- Assembly: 19%
- Shell: 4%
- CMake: 1%