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.
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.
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.
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.
Top comments (0)