Batteries-included Elixir MIDI.
ExMidi provides a unified API for MIDI message construction, binary
encode/decode, Standard MIDI File read/write, SYX file support, and a
streaming MIDI parser.
Message terms
All MIDI messages are represented as {:midi, payload} tuples:
{:midi, {:note_on, [channel: 1, pitch: 60, velocity: 100]}}Modules
ExMidi.MidiMsg— lightweight message constructors (tuple-based)ExMidi.MidiMessage— frozen message struct with rich API (copy, hex, dict, etc.)ExMidi.MidiBin— binary encode/decode of MIDI messagesExMidi.MidiParser— streaming byte-by-byte MIDI parserExMidi.MidiFile— Standard MIDI File read/write (Format 0/1/2)ExMidi.MidiSyx— SYX file read/writeExMidi.MidiUtil— utility functionsExMidi.MidiLib— version information
Quick start
# Message constructors
ExMidi.MidiMsg.note_on(60, 100)
# => {:midi, {:note_on, [pitch: 60, velocity: 100]}}
# Binary encode/decode
ExMidi.MidiBin.encode(ExMidi.MidiMsg.note_on(1, 60, 100))
# => <<144, 60, 100>>
ExMidi.MidiBin.decode(<<144, 60, 100>>)
# => {:midi, {:note_on, [channel: 1, pitch: 60, velocity: 100]}}
# Frozen message struct
msg = ExMidi.MidiMessage.new(:note_on, channel: 1, pitch: 60, velocity: 100)
ExMidi.MidiMessage.to_hex(msg)
# => "90 3C 64"
# Streaming parser
parser = ExMidi.MidiParser.new()
parser = ExMidi.MidiParser.feed_bytes(parser, [144, 60, 100])
{msg, _} = ExMidi.MidiParser.parse(parser)
# MIDI file
midi = ExMidi.MidiFile.read("song.mid")
for msg <- ExMidi.MidiFile.play(midi), do: IO.inspect(msg)