#midi #music


A (eventually) complete representation of the MIDI 1.0 Detailed Specification and its many extensions and addenda, to allow for the serialization and deserialization of MIDI byte streams to and from a typed representation

5 releases (3 breaking)

0.4.0 Sep 28, 2022
0.3.0 Mar 19, 2021
0.2.1 Mar 6, 2021
0.2.0 Mar 6, 2021
0.1.0 Mar 3, 2021

#105 in Audio

Download history 52/week @ 2023-02-13 69/week @ 2023-02-20 46/week @ 2023-02-27 47/week @ 2023-03-06 34/week @ 2023-03-13 29/week @ 2023-03-20 61/week @ 2023-03-27 111/week @ 2023-04-03 40/week @ 2023-04-10 34/week @ 2023-04-17 44/week @ 2023-04-24 55/week @ 2023-05-01 56/week @ 2023-05-08 43/week @ 2023-05-15 16/week @ 2023-05-22 56/week @ 2023-05-29

185 downloads per month
Used in 6 crates (4 directly)

MIT license



Crates.io Docs.rs

midi-msg aims to be a complete representation of the MIDI 1.0 Detailed Specification and its many extensions and addenda, to allow for the serialization and deserialization of MIDI byte streams to and from a typed representation. MIDI 2.0 may be supported at a later date.

midi-msg types follow the taxonomy detailed in the MIDI spec, and have the goal of being entirely safe. That is to say, any MidiMsg can be serialized into a valid MIDI byte sequence. Likewise, as it strives for completeness, any valid MIDI byte sequence can be deserialized into a MidiMsg. A corollary to this is that "MIDI-like" messages that do not conform to the spec are mostly not representable. Additionally, midi-msg strives to capture the semantic meaning of MIDI with types that are not simply "bags of bytes". Any values that are not numeric atoms are represented with their meaning in mind. Nonetheless, much of what MIDI achieves is predicated on passing around numeric values and as such they are handled according to the following approach.

Since the MIDI spec makes extensive use of non-byte-aligned integers, a Rust representation could either be achieved by introducing "exotic" integer types or by clamping Rust's primitive types to the desired range. For the sake of ergonomics, the latter approach was taken, though this does make this typed representation slightly "lossy". Any overflows between these representations are treated as max values (or min, for negative signed values). Other libraries, which have taken other approaches with respect to these design decisions, can be found below.


Add the following line to your Cargo.toml file:

midi-msg = "0.4"

If you want to use midi-msg in a no_std environment, add this line instead:

midi-msg = { version = "0.4", default-features = false, features=["sysex"] }

Disabling system exclusive functionality

The default sysex Cargo feature can be disabled to exclude code related to system exclusive functionality, which can be useful to reduce the binary size in resource constrained environments. If sysex is not used and an attempt is made to parse a system exclusive message, an error will be returned.

To be implemented

  • Deserialization of most of UniversalRealTimeMsg and UniversalNonRealTimeMsg


MIDI messages described by the following Midi Manufacturer Association (MMA) documents are supported (with their corresponding Midi Manufacturer Association [MMA] publication number, Recommended Practice [RP] number, or Changes/Additions [CA] number as noted):

  • MIDI 1.0 Detailed Specification 4.2.1 (The base specification. All types should be assumed to be defined by this document unless otherwise specified)
  • MIDI Time Code (MTC) (MMA-001 / RP-004 / RP-008)
  • General MIDI System Level 1 (GM1) (MMA-007 / RP-003)
  • General MIDI 2 1.2 (GM2) (RP-024/RP-036/RP-037/RP-045)
  • File Reference System Exclusive Message (CA-018)
  • Sample Dump Size, Rate and Name Extensions (CA-019)
  • MIDI Tuning Updated Specification (CA-020/CA-021/RP-020)
  • Controller Destination Setting (CA-022)
  • Key-Based Instrument Controllers (CA-023)
  • Global Parameter Control (CA-024)
  • Master Fine/Coarse Tuning (CA-025)
  • Modulation Depth Range RPN (CA-026)
  • Extension 00-01 to File Reference Sysex Message (CA-028)
  • CC #88 High Resolution Velocity Prefix (CA-031)
  • Response to Data Inc/Dec Controllers (RP-018)
  • Sound Controller Defaults (RP-021)
  • Redefinition of RPN 01/02 (RP-022)
  • Renaming of CC91 and CC93 (RP-023)
  • Three Dimensional Sound Controllers (RP-049)
  • MIDI Polyphonic Expression 1.0 (RP-053)

The following addenda are not yet fully supported by midi-msg, though hooks are provided to access these messages:

  • MIDI Machine Control 1.0 (MMC) (MMA-016 / RP-013) (partial support)
  • MIDI Show Control 1.1.1 (MSC) (RP-002/RP-014)

The following addenda were consulted but considered not relevant to this library:

  • Response to Reset All Controllers (RP-018)
  • Default Pan Formula (RP-036)

Support for the Standard MIDI Files specification may be added.

Other Rust MIDI representation libraries


If you would like to see how midi-msg interprets the results of received messages, you can check out this repository and run the following to use a modified version of midir's test_read_input example.

cargo run --example test_read_input

This will produce output like:

1816489080: ChannelVoice { channel: Ch1, msg: NoteOn { note: 62, velocity: 59 } }
1816643991: ChannelVoice { channel: Ch1, msg: NoteOff { note: 62, velocity: 53 } }

Note that midir is installed as a dev-dependency and this does not impose any requirement on the use of midir when specifying this crate as a dependency.


Pull requests for the features listed above as not-yet supported, for bug fixes (any omissions from the spec are considered bugs), or for documentation additions are most welcome, as are bug reports.