ExMidi.MidiParser (ex_midi v0.2.0)

Copy Markdown View Source

Streaming byte-by-byte MIDI parser.

Feed raw MIDI bytes (integers 0-255) in any chunking — the parser handles running status, interleaved real-time messages, system exclusive frames, and meta messages. Completed messages are queued and drained with parse/1 or flush/1.

Examples

parser = ExMidi.MidiParser.new()
parser = ExMidi.MidiParser.feed_bytes(parser, [144, 60, 100])
{msg, _parser} = ExMidi.MidiParser.parse(parser)
# => {{:midi, {:note_on, [channel: 1, pitch: 60, velocity: 100]}}, _parser}

Notes:

  • Real-time bytes (F8-FC, FE, and the undefined-but-reserved F9 "tick") are emitted immediately, even in the middle of an incomplete message or a system exclusive frame, as the MIDI specification allows.
  • Channel voice messages support running status; a note-on with velocity 0 is reported as a note-off with velocity 64.
  • System exclusive messages are reported with their full framing: {:sys_ex, [0xF0 | data] ++ [0xF7]}.

Summary

Types

What the parser is waiting for to complete the current message.

t()

Functions

Feed a single byte (0-255) into the parser.

Feed a list of bytes into the parser.

Return all completed messages in feed order and drain the queue.

Create a new parser.

Pop the oldest completed message. Returns {message, parser} or nil when no message is available.

Number of completed messages waiting to be parsed.

Types

expectation()

@type expectation() ::
  :idle
  | :sysex
  | :meta_length
  | {:meta_data, byte(), non_neg_integer()}
  | {:bytes, pos_integer()}

What the parser is waiting for to complete the current message.

message()

@type message() :: {:midi, term()}

t()

@type t() :: %ExMidi.MidiParser{
  buf: term(),
  expect: term(),
  messages: term(),
  running: term()
}

Functions

feed_byte(parser, b)

@spec feed_byte(t(), byte()) :: t()

Feed a single byte (0-255) into the parser.

feed_bytes(parser, bytes)

@spec feed_bytes(t(), [byte()]) :: t()

Feed a list of bytes into the parser.

flush(parser)

@spec flush(t()) :: {[message()], t()}

Return all completed messages in feed order and drain the queue.

new()

@spec new() :: t()

Create a new parser.

parse(parser)

@spec parse(t()) :: {message(), t()} | nil

Pop the oldest completed message. Returns {message, parser} or nil when no message is available.

pending(midi_parser)

@spec pending(t()) :: non_neg_integer()

Number of completed messages waiting to be parsed.