A note-on starts a note - unless its velocity is zero, which the standard says is really a note-off. Today you parse note-on and pin that surprising edge, because getting it wrong doubles or drops every note later.
Parse a note-on event, treating a velocity of zero as a note-off.
A note-on (high nibble 0x9) starts a note: a note number and a velocity,
how hard the key was struck. 0x90 0x3C 0x64 is “channel 0, note 60, velocity 100.”
Simple enough - except for one rule that trips every beginner.
By convention a note-on with velocity 0 is not a silent note; it is a
note-off. Sequencers exploit this so a stream of note-ons can both start and
stop notes using running status (coming soon) without ever emitting a real 0x8
status. So 0x90 0x3C 0x00 must parse as a note-off on note 60. Fold that decision
in here, at the source: if you skip it, later note-pairing will see a note started
and never ended, and your note durations will be wrong. This is the kind of edge
the whole project exists to pin.
// 0x9n with velocity > 0 is NoteOn; velocity == 0 is really NoteOff// read note and velocity, then choose the Kind from the velocityif velocity == 0 {// Kind = "NoteOff"}