I made a browser tool, Song to Guitar TAB, that listens to a song, estimates its chords, and turns them into a guitar TAB you can play along with. It gets a lot right, but it also makes the kind of mistakes that jump out when you play along: one bar of a chorus that is suddenly a different chord from every other chorus.

So I tried something on top of it. First, find the song’s sections automatically: where the intro ends, where each verse and chorus is. Then use them: a chorus that comes back three times should have the same chords each time, so where one of them disagrees, it is probably a mistake.

I tried it on two songs by Josh Woodward, who releases his music under Creative Commons and publishes his own chord charts. That means every step can be checked against the composer’s chords.

Listen first

Hear the chorus three ways

On the analysis page you can play the chorus of “Goodbye To Spring” together with a synthesized guitar playing the tool’s TAB, with three different sets of chords:

  1. Fast reading: the chords read straight from the song
  2. Reading the separated parts: the song split into vocals, drums, bass and other instruments first, and the chords read again without the vocals and drums
  3. Fixed with the song’s sections: the new step in this article

Switch rows while it plays and only the guitar’s chords change, at the same place in the song, so you can hear exactly what each step did.

The chorus comparison: the chords of bars 49–64 for each of the three steps; coloured bars changed from the row above
The chorus comparison. Coloured bars changed from the row above.

Step 0: how the tool reads chords

The tool finds the beats and bars, then measures, for each bar, how strongly each of the 12 notes (C, C♯, D…) sounds. That profile is compared with chord templates, and the best match wins.

The problem is the voice. The sung melody is loud, and its notes get mistaken for chord tones. So the tool can also split the song into vocals, drums, bass and other instruments with a source-separation model (SCNet), running in the browser, and read the chords from the bass and the other instruments only. That is step ②.

Step 1: finding the sections

I tried three ways to find the sections.

  • Rules only. Things like “before the voice comes in is the intro” or “the part sung highest and repeated most is the chorus”, written as code. It worked on the first song I tuned it on, then fell apart on others, with things like a row of 4-bar “choruses”.
  • AI only. Give per-bar numbers to a small AI model (Claude Haiku) and ask it for the sections. The result looked plausible, but it changed from run to run, sometimes dropped the intro, and called a passage in another key a chorus.
  • Rules + AI. Rules set down the facts and a rough draft; the AI decides the boundaries and names from them; then rules correct anything that contradicts the facts (before the first sung bar is always the intro, for example). This was by far the steadiest.

Rules are good at facts, and the AI is good at the “this sounds like a chorus” kind of judgement, so each does the part it is good at.

The whole of Goodbye To Spring: estimated sections, the local key, where the voice sings, repeated lyric lines, and the bars fixed in step 3
The whole of “Goodbye To Spring”. From the top: estimated sections, the local key, where the voice sings, repeated lyric lines, and the bars changed in step ③.

For “Goodbye To Spring”, the estimated order is intro, verse, pre-chorus, chorus, verse, chorus, bridge, interlude, chorus, outro. Josh Woodward’s chart lists Intro, Verse, Chorus, Verse, Chorus, Bridge, Solo, and the final chorus, so apart from a short 4-bar pre-chorus the chart doesn’t name, the order matches. (The chart has no bar numbers, so the exact boundaries could not be checked.)

The clues all come from the separated vocals

Every clue the rules use comes from the song split into parts:

  • Is the voice singing? The level of the separated vocals. Before the voice is the intro; a gap is probably an interlude.
  • How high is it sung? Choruses tend to be sung higher than verses.
  • The local key. The key heard over the few bars around each bar, from the bass and the other instruments. It shows real key changes.
  • Repeated lyric lines. Speech recognition (Whisper) on the separated vocals, then: is this line the same as one sung earlier?

The lyrics turned out to be the strongest clue. A verse and a chorus often share chords, so chords alone can’t tell them apart, but a chorus repeats its words while each verse has new ones. The words themselves are never given to the AI: on my computer they become “this line repeats line 3”, and only those numbers go in.

A side note on the local key: the tool’s overall key for this song was F, but the composer’s chart is in B♭. The local key, read from the separated bass and instruments, says B♭ almost everywhere. The overall key estimate still has a habit of picking a neighbouring key, which is on my list.

Step 2: fixing the chords with the sections

Once the sections are known, every chorus can be laid over the others and the bars at the same place compared.

  1. Rules find suspicious bars: a bar where one occurrence of the chorus disagrees with the others, or a chord read as sus2, which often means the third (the note that makes a chord major or minor) wasn’t heard.
  2. Rules list candidate chords: what the other occurrences read there, the earlier readings, and plain major or minor versions of them. Each gets a score for how well it fits the sound of that bar.
  3. The AI picks one candidate. It cannot invent new chords.
  4. A last rule throws out any change of root that fits the sound clearly worse than before.

The key point is that the rules limit what the AI can choose from. I also tried letting an AI rewrite the chords of a whole song freely; the changes moved around a lot from run to run, so it wasn’t usable.

The chords of each estimated section of Goodbye To Spring after step 3
The chords of each estimated section after step ③ (the first time each section comes).

How close did it get?

I compared each step with Josh Woodward’s own charts. The charts are written for guitar shapes (“Goodbye To Spring” in C shapes with the guitar tuned down a whole step, “I’m Letting Go” in G shapes with a capo on the 5th fret), so I moved them to the pitch they actually sound at: B♭ and C. Then I followed the chart’s chord changes in order and counted how many show up in the estimated sequence.

Song (chord changes in the chart)① Fast② Parts③ Sections
Goodbye To Spring (58)root465352
root + major/minor454446
I’m Letting Go (33)root272625
root + major/minor262123

Two caveats: the charts write each section only once, and extra chords in the estimate are not counted against it, so this is a lenient score.

For “Goodbye To Spring”, separating the parts helped the roots most (46 → 53), and the section-based fix then got the most major/minor right (46). That is the same pattern I saw earlier on a Japanese pop song.

“I’m Letting Go” went the other way: the fast reading did best, and splitting into parts made it worse. It is a slow song carried by a capoed acoustic guitar, and my guess is that the separation pulled some of the guitar into the vocals. Josh Woodward also publishes instrumental versions of his songs, so this can be checked by comparing the separated backing with the real one. I haven’t done that yet.

What’s still missing

  • Two songs is not much. Some of the rules’ numbers were tuned on the first (Japanese) song, and more songs with known chords are needed to see whether they generalise.
  • The template behind the rough draft comes from Japanese pop song forms; songs built very differently may need other templates.
  • The tool’s overall key estimate confuses neighbouring keys, as it did on both songs here.

All the rules, with their numbers, are listed under “How it works” on the analysis page. If you want to try the tool on your own songs, the how-to guide walks through it.


  • Music: Josh Woodward, “Goodbye To Spring” and “I’m Letting Go”, licensed under CC BY 4.0. The chord charts compared here are from the same pages. The parts on the analysis page were separated from the recordings (changes made).
  • Source separation: SCNet (Tong et al.), model code from ZFTurbo/Music-Source-Separation-Training (MIT)
  • Speech recognition: Whisper (MIT), via mlx-whisper
  • AI: Claude Haiku