MidiMessageSplitter class

Splits a stream of MIDI bytes into complete messages.

This is the shared MIDI-assembly stage every transport in this plugin feeds, once it has stripped its own framing. It resolves running status, keeps partial messages across calls, and reassembles SysEx, so that each message handed to onMessage satisfies the MidiPacket.data contract: exactly one complete MIDI message, 0xF0 ... 0xF7 for SysEx and a single byte for System Real-Time.

The rules below are numbered, and the same numbers appear in the Kotlin and Swift ports (MidiPacketParser.kt / .swift) so the three implementations can be reviewed against one spec.

  1. System Real-Time (0xF8-0xFF) is handled first, in every state, and mutates nothing else — not the running status, not a partial message, not a SysEx in progress. It is emitted immediately, including between the data bytes of another message and from inside a SysEx. 0xF9 and 0xFD are undefined and are swallowed, but they disturb no state either.
  2. A channel voice status byte (0x80-0xEF) latches the running status, discards any incomplete message and starts a new one.
  3. System Common 0xF1/0xF2/0xF3 clears the running status and starts a new message; 0xF6 clears it and is emitted immediately.
  4. 0xF0 clears the running status and opens a SysEx. Inside a SysEx any non-real-time status byte aborts it: a 0xF7 is synthesised, the message is emitted, and the offending byte is then re-dispatched. maxSysExLength does the same, so a device that never sends 0xF7 cannot wedge the stream.
  5. 0xF7 outside a SysEx, and 0xF4/0xF5, clear the running status and emit nothing. A status byte is never latched before it has been classified.
  6. A data byte extends the message in flight, or revives the running status when there is none. A message is emitted when it reaches its expected length exactly. Data with neither is dropped.
  7. After an emission the partial message is cleared but the running status survives. Emitted messages are always copies; the internal buffers are never handed out.
  8. reset clears all state, and transports call it on disconnect.

Constructors

MidiMessageSplitter({required void onMessage(Uint8List message, int timestamp), int maxSysExLength = 65536})
Creates a splitter delivering complete messages to onMessage.

Properties

hashCode int
The hash code for this object.
no setterinherited
maxSysExLength int
Largest SysEx this splitter will assemble before force-terminating it.
final
onMessage → void Function(Uint8List message, int timestamp)
Called once per complete MIDI message.
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
parse(List<int> bytes, int timestamp) → void
Feeds bytes to the splitter, stamping any message they complete with timestamp.
reset() → void
Drops every partial message, the running status and any SysEx in progress.
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited