A MIDI piano-roll visualizer written in Odin using Raylib.
Resonance loads Standard MIDI Files and renders them as a falling-note piano roll with real-time audio playback via sine-wave synthesis. The MIDI parser is written from scratch — no external MIDI libraries.
- Odin compiler (the
vendor:raylibbindings ship with Odin, so Raylib needs no separate install) - A desktop OS with OpenGL (developed on Linux / Arch)
# Run directly (compiles to a temp binary, then runs)
odin run .
# …optionally with a file to load on startup
odin run . -- song.mid
# Or build a standalone binary
odin build . -out:resonance
./resonance song.midOnce the window is open, drag and drop any .mid file onto it to load it.
A summary of the parsed file (format, division, tracks, note counts, tempo) is
printed to the console — handy for verifying the parser against real files.
Two example files are included:
odin run . -- assets/demo.mid # 2-track melody + chords (good first look)
odin run . -- assets/sample.mid # minimal 2-note file| Key | Action |
|---|---|
Space |
Pause / resume |
1 |
0.5× speed |
2 |
1× speed |
3 |
2× speed |
R |
Restart from the beginning |
| drag/drop | Load another .mid |
Playback loops automatically at the end. The speed multiplier changes tempo, not pitch.
The MIDI parser has a unit-test suite (hand-built byte streams covering tempo meta events, running status, note-on-velocity-0, SMPTE division, and malformed headers):
odin test .resonance/
├── main.odin # entry point, playback engine, controls
├── midi.odin # MIDI binary parser (Format 0 & 1)
├── midi_test.odin # parser unit tests
├── timeline.odin # tick→seconds tempo map, note + event extraction
├── piano_roll.odin # falling-note rendering + 88-key keyboard
├── audio.odin # sine-wave synthesis + polyphonic mixing
├── ui.odin # BPM display, speed/pause overlay, progress bar
└── assets/
├── demo.mid # 2-track melody + chords
└── sample.mid # minimal 2-note file
- MIDI parser — Format 0/1, variable-length quantities, running status, note on/off, velocity, delta/absolute ticks, tempo & meta events, SysEx
- Piano-roll renderer — falling note blocks, 88-key keyboard, per-octave shading
- Multi-track rendering — one color per track, layered
- Audio playback — sine-wave synthesis (equal temperament, A4 = 440 Hz), polyphonic mixing
- Playback controls — 0.5×/1×/2× speed, pause/resume, BPM display
- Drag-and-drop loading at runtime
MIT