A scale-aware chord generator and voice-leading engine for Ableton Live 12 (Max for Live, MIDI effect). Turns single notes into rich, voice-led chords that follow Live's global Scale — pick a voicing, play any monophonic line, and Harmonia builds chord shapes that stay in key and lead smoothly between changes.
- Scale-aware in real time — reads
root_note,scale_intervals,scale_name, andscale_modefromlive_setvia the LiveAPI; change the global key/scale in Live's transport and Harmonia tracks it instantly, with a 200 ms polling fallback in case observers miss a change - Eight voicing modes — Triad · 7th · 9th · 11th · Quartal · Cluster · Drop-2 · Wide
- Voice leading — optionally minimises octave displacement between consecutive chords for smoother transitions
- Spread, Tension, Octave Mix, Strum, Humanize, Velocity Curve — full shaping over each generated voicing; every parameter is a Live-native parameter, mappable, automatable, MIDI-mappable
- Two-octave piano-roll visualisation — in-scale tones in purple, root highlighted, input note in yellow, output voices glowing cyan
- Built-in info text — hover any control in Live and the description shows up in the Info View
- Drag
Harmonia.amxdfrom the repo into a MIDI track in Ableton Live 12 (or copy to your User Library). - Add an instrument (Wavetable, Operator, Drum Rack, Simpler, VST, …) after Harmonia in the track's device chain.
- Play a note — Harmonia builds chords from your input immediately.
| Name | Type | Range | Description |
|---|---|---|---|
| Voicing | menu | 8 modes | Chord voicing type (Triad, 7th, 9th, 11th, Quartal, Cluster, Drop-2, Wide) |
| Voices | numbox | 1–7 | Number of voices in the chord |
| Tension | dial | 0–1.0 | Harmonic tension — raise upper chord tones by a scale degree |
| Spread | dial | 0–1.0 | Expand intervals between chord tones |
| Octave Mix | dial | -1.0–1.0 | Add an octave doubling above (+) or below (-) |
| Strum | dial | 0 ms–… | Arpeggiate chord voices with a time spread |
| Humanize | dial | 0–1.0 | Random velocity variation across voices |
| Vel Curve | dial | -1.0–1.0 | Velocity bias across voices (negative = louder bass, positive = louder top) |
| Voice Leading | toggle | 0/1 | Minimise pitch displacement between consecutive chords |
| Bypass | toggle | 0/1 | Pass MIDI through unmodified |
Hover over any control in Live to see the description in the bottom info panel.
Engine: harmonia.js ([v8] object — ECMAScript 6+) receives note-on/off from [midiparse], looks up the input pitch's scale degree in the current Live 12 global scale, builds a chord via the selected voicing template (degree offsets), applies spread/tension/octave-mix/drop/voice-leading transforms, shapes per-voice velocity, and emits note <pitch> <velocity> messages routed back through [midiformat] → [midiout].
Scale tracking uses LiveAPI observers on root_note, scale_intervals, scale_name, and scale_mode from live_set, with a debounced Task callback (15 ms) to coalesce rapid changes, plus a 200 ms polling fallback for reliability.
harmonia_viz.js renders a two-octave piano-roll visualisation via [jsui] — scale tones, root, input note, and output chord voices all colour-coded.
harmonia_build.py is the device generator — it reads Harmonia.maxpat and the JS source files, then produces a frozen .amxd binary container with all dependencies embedded. No external template file is needed.
- Ableton Live 12 required for full scale-aware chord generation — Live 11 doesn't expose
scale_name/scale_intervalson the song object; the engine will fall back to C Major. - Max for Live 8.6+ (the engine uses the
[v8]JavaScript object, introduced in Max 8.6). - Built and tested on macOS. Windows untested but should work.
harmonia_build.py (Python 3.11+) generates a frozen .amxd that embeds the patcher JSON and all JS dependencies (harmonia.js, harmonia_viz.js) into a single self-contained file. Output is written next to the script. Edit the sources and re-run to regenerate.
python3.11 harmonia_build.pyThe .amxd binary container uses the frozen mx@c format:
'ampf' [4-byte LE size] "mmmm" ← device type tag
'meta' [4-byte LE size] uint32_LE(7) ← format version
'ptch' [4-byte LE size]
'mx@c' [BE uint32 = 16] ← frozen device container
[8-byte BE footer_offset]
[patcher JSON] ← Harmonia.maxpat
[harmonia_viz.js bytes]
[harmonia.js bytes]
'dlst' [BE size] [dire entries] ← file directory
The script generates this structure directly — no external template or reference .amxd is needed. The frozen format matches what Max's own Freeze Device produces.
Adrian Kwiatkowski — electronic music producer.
Listen: Spotify · Bandcamp · SoundCloud · Apple Music · YouTube
MIT — see LICENSE. You can edit, modify, redistribute, and use Harmonia in commercial productions; please retain the copyright notice in derivative works.
