DEV Community

Giang Pham Truong
Giang Pham Truong

Posted on AI-assisted

When a Sustained MIDI Note Meets the Next Onset

A MIDI file can contain note events that overlap in time. A readable score needs a voice model, and that model makes choices about which overlaps it can represent. Pianory's MIDI-to-MusicXML converter currently builds one notation voice per hand. This article describes that constraint and a test that makes it visible.

Within a hand, notes sharing the same start are grouped into one chord. The converter sorts those starts, inserts a rest when the next start is later than the current cursor, and limits each group's written length to the next onset in that hand. Even when an input note sustains longer, the generated one-voice score can end it at that next onset. This keeps the measures filled consistently, but it does not preserve independently overlapping voices within the same hand.

The focused fixture is concrete. Three right-hand pitches, MIDI 60, 64 and 67, begin together at quarter 0 and last two quarters; the test expects C4, E4 and G4 in a chord. In the left hand, MIDI 48 begins at quarter 0 for four quarters and MIDI 55 begins at quarter 2 for two. The test states that the first left-hand whole note is cut where the next left-hand note starts, expects C3 then G3, and checks the measure sums.

This is an explicit notation tradeoff, not a statement that MIDI always means legato or that the output captures every overlapping line. If the product needs independent same-hand voices, the representation must change rather than hiding the overlap. I make Pianory. AI helped draft this article; I checked the claims against src/lib/music/midi.ts and src/lib/music/midi.spec.ts. On 27 October, pnpm test:unit -- --run src/lib/music/midi.spec.ts passed all 16 focused tests.

Top comments (0)