MidiProto.Parser (midi_proto v0.2.0)

Parses incoming MIDI data.

Use this module to parse incoming MIDI data from your device and it'll convert it to a stream of message structs for you. Handy, eh?

Usage

We split the receiving data and the parsing functions into separate functions so that you have the flexibility to handle incoming data without having pay the cost of parsing until you're ready.

Here's an example of parsing a single MIDI note on message:

iex> Parser.init()
...> |> Parser.append(<<145, 2, 3>>)
...> |> Parser.parse()
{:ok, [%MidiProto.Message.NoteOn{channel: 1, note_number: 2, velocity: 3}], %Parser{}}

You can call append/2 and parse/1 and number of times fill and empty the buffer as required.

Summary

Functions

Append some new incoming data to the end of the parser buffer.

Check if the parse buffer is empty.

Initialize an empty parser struct ready to receive data.

Parse the contents of the buffer, returning zero or more messages.

Types

@type t() :: %MidiProto.Parser{buffer: binary()}

Functions

Link to this function

append(parser, new_bytes)

@spec append(t(), binary()) :: t()

Append some new incoming data to the end of the parser buffer.

Usually you append a packet at a time, but partial packets are fine, as long as they are completed before the call to parse/1 is made.

Example

iex> Parser.init()
...> |> Parser.append(<<0xff>>)
%Parser{buffer: <<0xff>>}
@spec empty?(t()) :: boolean()

Check if the parse buffer is empty.

@spec init() :: t()

Initialize an empty parser struct ready to receive data.

iex> Parser.init()
%Parser{}
@spec parse(t()) :: {:ok, [MidiProto.Message.t()], t()} | {:error, :invalid_packet}

Parse the contents of the buffer, returning zero or more messages.

Example

iex> Parser.init()
...> |> Parser.append(<<0xff>>)
...> |> Parser.parse()
{:ok, [%SystemReset{}], %Parser{}}