When a MIDI Note Ends One Sixteenth Early
MIDI gives us timed note events, not a finished score. When Pianory imports a MIDI file into its score player, it has to choose a readable written duration. A tiny release gap near the next note can be meaningful, or it can make notation look more staccato than the phrase suggests.
How the converter quantizes time
Our converter snaps starts and durations to a sixteenth-note grid: four grid units equal one quarter note. It builds one voice per hand, groups simultaneous starts into a chord, and caps that chord at the hand's next onset.
For a held note released just before that onset, it fills a gap only when:
- the gap is at most one grid unit, and
- no more than a quarter of the note length.
Otherwise it leaves the gap.
A concrete boundary case
The focused test is concrete. A C5 note starts at quarter 0 and lasts 3.75 quarters; the next D5 starts at quarter 4. The first note spans 15 sixteenth units, followed by a one-unit gap.
In a 4/4 bar of 16 units, that gap passes the rule, so the MusicXML contains a whole-note type and no ordinary rest. The test asserts that output.
Limits of the heuristic
This is a notation heuristic, not a claim that every MIDI performance is represented exactly. Triplets and swing are approximate on this grid, and a larger gap should remain a rest. The useful design choice is to make the threshold explicit and test a boundary case instead of letting a seemingly harmless release create an unwanted sliver of silence on the page.
I make Pianory, the piano-learning app behind this converter. AI helped draft this article; I checked the claims against src/lib/music/midi.ts and the focused test. On 26 October, pnpm exec vitest run src/lib/music/midi.spec.ts passed all 16 tests.
Comments
No comments yet. Start the discussion.