Read straight from the chords MIDI — chord name, roman numeral in the local key, and function (T = tonic / home · S = subdominant / away · D = dominant / tension). Chords outside the key are flagged in plum (borrowed · secondary dominant · Neapolitan). Cadences sit between the chords.
Each melody note is classified against the chord sounding under it: is it a chord tone (root / 3rd / 5th / 7th), or a non-chord tone (passing, neighbor, suspension, appoggiatura, anticipation, pedal)? Dissonances on strong beats and tendency-tone resolutions are pulled out too.
The melody is split into phrases at rests and each phrase is labelled by similarity — a, b, c… with a ′ for a variation of the same idea. The melodic form and the harmonic form (how the chords repeat) sit side by side, and each phrase gets its contour shape.
Key by Krumhansl–Schmuckler profile correlation (global, and local via a sliding window). Chords by a time-windowed pitch-class weight vector matched to templates — it catches block chords and arpeggios alike. Roman numerals and function are read in the local key. Vertical classification is chord-tone membership plus context-based non-chord-tone heuristics. Everything runs in the browser; nothing is uploaded.