Upload a MIDI or MusicXML file. See the note transition graph. Hear it played back. View the sheet music.
Playback
Upload a MIDI or MusicXML file first.
Melodic graph
Harmonic graph
This file appears to be monophonic — no simultaneous pitches means
there are no chords to analyze. The melodic graph above still works.
Chord sequence
Sheet music
Summary
Melodic
All pitch transitions (sorted by probability)
Harmonic
All chord transitions (sorted by probability)
About midi-graph
midi-graph turns a MIDI or MusicXML file into a visual map of which notes follow which. Designed and implemented by Zaher Alkaei.
What you get
Melodic graph — each node is a unique pitch, each arrow is a "this note is followed by that note" transition. Arrow width ∝ probability; arrow direction shows flow. For multi-track MIDI, a track picker lets you focus on one voice at a time (only that track's notes glow during playback).
Harmonic graph — slices the piece into fixed-size windows (eighth / quarter / half note) and groups the pitches sounding in each window into a chord. Nodes are chords (24 12-TET templates: triads, 7ths, sus, 6ths, add9, m7b5, 7sus, 7b9, 7#9, etc. + literal-spelling labels for quarter-tones), edges are chord-to-chord transitions. For monophonic files the panel shows a notice instead.
Summary — two columns. Left: total notes, unique pitches, total transitions, self-loops + share, pitch range, and every pitch transition sorted by probability (not just the top 5). Right: unique chords, total chord transitions, self-loops, chord range, and every chord transition sorted by probability. For monophonic files the right column shows a placeholder.
Sheet music — real notation. MusicXML renders directly; MIDI files are converted via webmscore (MuseScore 1.x in WASM) for professional engraving — proper beam grouping, voice separation, slurs, articulations, key and time signatures.
Playback — hear the piece with Tone.js. Hover on the graph: notes glow when they sound. Stop works mid-piece, replay works after Stop, and the natural end also resets correctly.
How to use it
Click Load demo (Twinkle Twinkle, .mid) or Load demo (ya-tyra, .mxl) for a one-click example, or use Choose File to upload your own. Drag-and-drop also works in most browsers.
Read the Summary panel for an at-a-glance overview.
Explore the Transition graph: each node shows the pitch + its share of the piece; each arrow shows the conditional probability of "next note given current note". Hover an arrow to see the count + percentage.
Press ▶ Play to hear the piece — the graph glows on every sounding pitch. ■ Stop works mid-piece; you can replay immediately.
Scroll down to the Sheet music panel for the notation.
Keyboard shortcuts
Space — Play / Stop (when not focused on a text input)
Esc — close this info dialog
The two demos are different pieces
The Twinkle Twinkle demo is the classic nursery rhyme in a 4-voice arrangement (Twinkle, Twinkle, Little Star + variations / ABC melody + alphabet song sharing the same harmony), standard 12-TET MIDI (144 notes, 13 pitches, 5 tracks). The ya-tyra demo is the Arabic maqam piece "يا طيرة طيري يا حمامة" (O little bird, fly O pigeon) in compressed MusicXML (243 notes, 8 pitches, with quarter-tones). They showcase different features: Twinkle → clean triadic harmony (I-V-I-vi-IV-V-I) + synthetic sheet music from MIDI + multi-track glow; ya-tyra → microtonal support + .mxl (zip) extraction + real notation.
Quarter-tones
Quarter-tones are preserved exactly as cents (1/100 of a semitone). The display uses the compact form C↑4 / D#↑4 for half-sharps. The ya-tyra demo's source XML actually encodes the quarter-tones as half-FLATS (B↓3 and E↓4), but the app reports them as the sharp-spelled enharmonic names A#↑3 and D#↑4 — same pitch, different spelling. See the README for the full details.
File support
MIDI (.mid, .midi) — parsed from the file's bytes. Cents derived from MIDI note number (no quarter-tones — MIDI is 12-TET).
MusicXML (.musicxml, .xml) — parsed as XML. Full quarter-tone support (alter can be −1.5, −0.5, 0.5, 1.5).
Compressed MusicXML (.mxl) — a zip containing container.xml + the score. Extracted in the browser via fflate; no server needed.
The file type is detected from the file's contents (first 4 bytes), not the extension — so a mis-named file still routes to the right parser.