Dave Nelson

Voice-Leading and Harmonic Spot-Checks with LLMs (Without the AI Slop)

September 2026 — Labs & Notebooks

Most talk about AI and music revolves around “prompt-to-audio” generators (Suno, Udio), which isn't what serious composition or theory work is about.

Where LLMs (Claude, ChatGPT, Gemini) actually shine is as an on-demand theory sounding board—spot-checking counterpoint, flagging awkward voice crossings, or analyzing harmonic motion. The problem has always been how to get your musical ideas into the chat:

The Discussion Process (Try It Yourself)

Here's a clean 4-bar passage (a standard ii–V–I–VI in C with rootless 4-note voicings under a lead melody).

To see how an LLM handles raw symbolic data, copy the JSON block below, paste it into your model of choice, and give it a simple prompt:

“Analyze the voice leading and harmonic relationship between the melody and chord voicings in this 4-bar passage.”

4-Bar Passage — JSON

{ "meter": "4/4", "tempo": 120.0, "tracks": [ { "name": "01-Melody Lead", "notes": [ {"bar": 1, "beat": 1.00, "pitch": "E5", "len": 2.00, "vel": 96}, {"bar": 1, "beat": 3.00, "pitch": "F5", "len": 1.00, "vel": 92}, {"bar": 1, "beat": 4.00, "pitch": "D5", "len": 1.00, "vel": 88}, {"bar": 2, "beat": 1.00, "pitch": "E5", "len": 1.00, "vel": 94}, {"bar": 2, "beat": 2.00, "pitch": "D5", "len": 1.00, "vel": 90}, {"bar": 2, "beat": 3.00, "pitch": "B4", "len": 2.00, "vel": 98}, {"bar": 3, "beat": 1.00, "pitch": "C5", "len": 2.00, "vel": 96}, {"bar": 3, "beat": 3.00, "pitch": "D5", "len": 1.00, "vel": 88}, {"bar": 3, "beat": 4.00, "pitch": "E5", "len": 1.00, "vel": 92}, {"bar": 4, "beat": 1.00, "pitch": "G5", "len": 2.00, "vel": 100}, {"bar": 4, "beat": 3.00, "pitch": "F5", "len": 1.00, "vel": 94}, {"bar": 4, "beat": 4.00, "pitch": "C#5", "len": 1.00, "vel": 90} ] }, { "name": "02-Harmony Keys", "notes": [ {"bar": 1, "beat": 1.00, "pitch": "F3", "len": 4.00, "vel": 80}, {"bar": 1, "beat": 1.00, "pitch": "C4", "len": 4.00, "vel": 78}, {"bar": 1, "beat": 1.00, "pitch": "E4", "len": 4.00, "vel": 82}, {"bar": 1, "beat": 1.00, "pitch": "A4", "len": 4.00, "vel": 84}, {"bar": 2, "beat": 1.00, "pitch": "F3", "len": 4.00, "vel": 80}, {"bar": 2, "beat": 1.00, "pitch": "B3", "len": 4.00, "vel": 78}, {"bar": 2, "beat": 1.00, "pitch": "E4", "len": 4.00, "vel": 82}, {"bar": 2, "beat": 1.00, "pitch": "A4", "len": 4.00, "vel": 84}, {"bar": 3, "beat": 1.00, "pitch": "E3", "len": 4.00, "vel": 76}, {"bar": 3, "beat": 1.00, "pitch": "B3", "len": 4.00, "vel": 74}, {"bar": 3, "beat": 1.00, "pitch": "D4", "len": 4.00, "vel": 78}, {"bar": 3, "beat": 1.00, "pitch": "G4", "len": 4.00, "vel": 80}, {"bar": 4, "beat": 1.00, "pitch": "E3", "len": 4.00, "vel": 82}, {"bar": 4, "beat": 1.00, "pitch": "G3", "len": 4.00, "vel": 80}, {"bar": 4, "beat": 1.00, "pitch": "C#4", "len": 4.00, "vel": 84}, {"bar": 4, "beat": 1.00, "pitch": "Bb4", "len": 4.00, "vel": 86} ] } ] }

Copy / Paste From Your DAW

In my own writing setup, I've got a simple shortcut mapped in REAPER: select a few bars across a couple of tracks, hit a key, and it copies this lean JSON structure straight to the clipboard so I can paste it directly into a chat window mid-composition.

If you try running the test above, how did the theoretical breakdown match what you expected? And if anyone else is experimenting with pulling symbolic MIDI data into LLMs—in REAPER or another DAW—I'd love to compare notes.

Note: I used an LLM as an editorial assistant to help organize and format my thoughts for this post.