Code Monkey home page Code Monkey logo

midi-msg's Introduction

midi-msg

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.

Installing

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

Support

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

Exploring

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.

Contributing

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.

midi-msg's People

Contributors

alexcharlton avatar asutherland avatar atoav avatar stuffmatic avatar xkr47 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

midi-msg's Issues

no_std support

This crate could be really useful in no_std environments like microcontrollers. There don't seem to be any dependencies on std that can't be replaced with alloc counterparts. I'm happy to submit a PR adding no_std support if you're interested.

License?

Hi, this looks like a really nice project! What license is the code released under?

Vec-less API for embedded usage?

I'm interested in using midi-msg for an embedded MIDI project, but I see that the core MidiMsg type relies on Vec<u8> for the internal representation of arbitrary-length message types, such as sysex messages.

Do you have any thoughts on what it might take to implement a type that has no_std support for all message types?

I could see two ways this might work:

  1. Replace MidiMsg with MidiMsg<'a>, and any internal use of Vec<u8> would be changed to &'a [u8], referring to a slice of the input buffer. I'm not sure if this would work in general - are there cases where the output Vec<u8> is not a contiguous slice of the input buffer? If every output type is a contiguous sample of the input, this seems like the best approach - no memory overhead!
  2. If the above won't work, replace MidiMsg with MidiMsg<Buffer>, where Buffer could be set to something like std::Vec<u8> or heapless::Vec<u8,N>, unified by a common (crate-specific) trait, and add a MessageTooLong constructor to the ParseError type (which would not ever occur while using std::Vec<u8>

I'm not sure if this would work with your design intentions for the library, but I'm probably going to have to add this functionality in any case, so figured I would check if there was some approach that would be upstreamable.

Cannot release 0.4.0 until ascii gets a new version

Upon attempting to publish to crates.io:

error: all dependencies must have a version specified when publishing.
dependency `ascii` does not specify a version
Note: The published dependency will use the version from crates.io,
the `git` specification will be removed from the dependency declaration.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.