Expand description
This is a library for serializing and deserializing MIDI (byte) streams.
§Creating MIDI byte sequences
MidiMsg is the starting point for all MIDI messages. All MidiMsgs
can be serialized into a valid MIDI sequence. You can create a MidiMsg
and turn it into a Vec<u8> like so:
use midi_msg::*;
MidiMsg::ChannelVoice {
channel: Channel::Ch1,
msg: ChannelVoiceMsg::NoteOn {
note: 60,
velocity: 127
}
}
.to_midi();§Deserializing MIDI byte sequences
Likewise, byte sequences can be deserialized into MidiMsgs with MidiMsg::from_midi:
use midi_msg::*;
// These are two MIDI 'note on' messages:
let midi_bytes: Vec<u8> = vec![
0x93, 0x66, 0x70, // First msg
0x93, 0x55, 0x60, // Second msg
];
let (msg, len) = MidiMsg::from_midi(&midi_bytes).expect("Not an error");
assert_eq!(len, 3);
assert_eq!(msg, MidiMsg::ChannelVoice {
channel: Channel::Ch4,
msg: ChannelVoiceMsg::NoteOn {
note: 0x66,
velocity: 0x70
}
});Where then len returned is the number of bytes used when a MidiMsg has been deserialized.
Similarly, MidiMsg::from_midi_with_context can be used to track the state associated
with a MIDI stream, which is necessary to deserialize certain messages:
use midi_msg::*;
let mut ctx = ReceiverContext::new();
// This is a three-byte MIDI 'note on' message followed by a two-byte "running status"
// 'note on' message, which inherits its first ("status") byte from the last `ChannelModeMsg`:
let midi_bytes: Vec<u8> = vec![
0x93, 0x66, 0x70, // First msg
0x55, 0x60, // Running status msg
];
let (_msg1, len1) =
MidiMsg::from_midi_with_context(&midi_bytes, &mut ctx).expect("Not an error");
let (msg2, len2) =
MidiMsg::from_midi_with_context(&midi_bytes[len1..], &mut ctx).expect("Not an error");
assert_eq!(len2, 2);
assert_eq!(msg2, MidiMsg::ChannelVoice {
channel: Channel::Ch4,
msg: ChannelVoiceMsg::NoteOn {
note: 0x55,
velocity: 0x60
}
});The previous message would not have been deserializable without the context:
use midi_msg::*;
let midi_bytes: Vec<u8> = vec![
0x93, 0x66, 0x70, // First msg
0x55, 0x60, // Running status msg
];
let (_msg1, len1) = MidiMsg::from_midi(&midi_bytes).expect("Not an error");
MidiMsg::from_midi(&midi_bytes[len1..]).unwrap();
§Midi files
We can work with Standard Midi Files (SMF) in much the same way. The MidiFile struct represents this data type and it can be serialized into a Vec<u8> and deserialized from a Vec<u8>. It holds a header and a list of tracks. Regular Track::Midi tracks contains a list of MidiMsg events along with the “delta time” that separates subsequent ones. The definition of the delta time is given by the division field in the Header.
Convenience functions are provided for constructing a MidiFile based on a series of events and absolute beat or frame timings. For example, the following creates a MidiFile with a single track containing a single note.
use midi_msg::*;
let mut file = MidiFile::default();
// Add a track, updating the header with the number of tracks:
file.add_track(Track::default());
// Add a note on message at beat 0:
file.extend_track(0, MidiMsg::ChannelVoice {
channel: Channel::Ch1,
msg: ChannelVoiceMsg::NoteOn {
note: 60,
velocity: 127
}
}, 0.0);
// Add a note off message at beat 1:
file.extend_track(0, MidiMsg::ChannelVoice {
channel: Channel::Ch1,
msg: ChannelVoiceMsg::NoteOff {
note: 60,
velocity: 0
}
}, 1.0);
// Add an end of track message at beat 4, which is the only required (by the spec) message in a track:
file.extend_track(0, MidiMsg::Meta { msg: Meta::EndOfTrack }, 4.0);
// Now we can serialize the track to a Vec<u8>:
let midi_bytes = file.to_midi();
// And we can deserialize it back to a MidiFile:
let file2 = MidiFile::from_midi(&midi_bytes).unwrap();
assert_eq!(file, file2);§Notes
See the readme for a list of the MIDI Manufacturer Association documents that are referenced throughout these docs.
Deserialization of most of UniversalRealTimeMsg and UniversalNonRealTimeMsg has not
yet been implemented.
Structs§
- The set of channels to apply this tuning message to. Used by
ScaleTuning1ByteandScaleTuning2Byte. - An iterator over the variants of Self
- Allows for the selection of the destination of a control change message. Used by
UniversalRealTimeMsg::GlobalParameterControl. - Allows for the selection of the destination of a channel pressure/poly key pressure message. Used by
UniversalRealTimeMsg. - A time signature occurring in a Standard Midi File.
- An iterator over the variants of Self
- An iterator over the variants of Self
- Global Parameter Control, to control parameters on a device that affect all sound. E.g. a global reverb. Used by
UniversalRealTimeMsg::GlobalParameterControl. - The header chunk of a Standard Midi File
- Like
TimeCodebut includesfractional_frames. Used inTimeCodeCueingSetupMsgand the SMFMetaevent. - A response to
UniversalNonRealTimeMsg::IdentityRequest, meant to indicate the type of device that this message is sent from. Used byUniversalNonRealTimeMsg::IdentityReply. - Intended to act like Control Change messages, but targeted at an individual key. For e.g. Drum sounds that have configurable attack/release/decay per key. Used by
UniversalRealTimeMsg::KeyBasedInstrumentControl. - Set the tunings of all 128 notes. Used by
UniversalNonRealTimeMsg. - A key signature occurring in a Standard Midi File.
- Two 7-bit “bytes”, used to identify the manufacturer for
SystemExclusiveMsg::Commercialmessages. See the published list of IDs. - A Standard Midi File (SMF)
- Errors that can occur when parsing a
MidiFile - Passed to
MidiMsg::from_midi_with_contextto allow for the capture and use of captured context while reading from a MIDI stream. - Set the tuning of all octaves for a set of channels. Used by
UniversalNonRealTimeMsgandUniversalRealTimeMsg. - Set the high-res tuning of all octaves for a set of channels. Used by
UniversalNonRealTimeMsgandUniversalRealTimeMsg. - Set the tuning of all octaves for a tuning program/bank. Used by
UniversalNonRealTimeMsg. - Set the high-res tuning of all octaves for a tuning program/bank. Used by
UniversalNonRealTimeMsg. - A time signature. Used by
TimeSignature. - Like
TimeCodebut usessubframesto optionally include status flags, and fractional frames. Also may be negative. Used inMachineControlCommandMsg. - Like
UserBitsbut allows for the embedding of a “secondary time code”. - Used to synchronize device positions, by
SystemCommonMsg::TimeCodeQuarterFrameXas well asUniversalRealTimeMsg::TimeCodeFull. - Used by
StandardTimeCode. - Used to communicate a new time signature to the receiver. Used by
UniversalRealTimeMsg. - An event occurring in a track in a Standard Midi File
- Used to represent a tuning by
TuningNoteChangeandKeyBasedTuningDump. - Change the tunings of one or more notes, either real-time or not. Used by
UniversalNonRealTimeMsgandUniversalRealTimeMsg. - 32 bits defined by SMPTE for “special functions”. Used in
UniversalRealTimeMsg::TimeCodeUserBits. See the SMTPE time code standard. - How to map a
WAVfile for MIDI reference. Used bySelectMap.
Enums§
- Indicates that the next MIDI clock message is the first clock of a new measure. Which bar is optionally indicated by this message. Used by
UniversalRealTimeMsg::BarMarker. - The note value of a beat, used by
Signature. - The MIDI channel, 1-16. Used by
MidiMsgand elsewhere. - Channel-level messages that should alter the mode of the receiver. Used in
MidiMsg. - Channel-level messages that act on a voice. For instance, turning notes on off, or modifying sounding notes. Used in
MidiMsg. - The type of chorus, used by
GlobalParameterControl::chorus. - Used by
ChannelVoiceMsg::ControlChangeto modify sounds. Each control targets a particularControlNumber, the meaning of which is given by convention. - An enum that defines the MIDI numbers associated with Control Changes.
- The parameters that can be controlled by
ControllerDestinationorControlChangeControllerDestination. - The device ID being addressed, either a number between 0-126 or
AllCall(all devices). Used bySystemExclusiveMsg::UniversalNonRealTimeandSystemExclusiveMsg::UniversalRealTime. - The division of a Standard Midi File, which specifies the meaning of the delta times in the file
- The type of loop being described by a
SampleDumpMsg. - The extended sample dump messages described in CA-019, used to allow for longer, named samples. Used by
UniversalNonRealTimeMsg::SampleDump. - Used to transmit general file data. Used by
UniversalNonRealTimeMsg. - The set of messages used for accessing files on a shared file system or network so they can be used to play sounds without transferring the file contents. Used by
UniversalNonRealTimeMsg::FileReference. - The file type of a given file, as used by
FileReferenceMsg. - A four-character file type used by
FileDumpMsg. - The General MIDI percussion sound to play for a given note number when targeting Channel 10.
- The instrument that should be played when applying a
ChannelVoiceMsg::ProgramChange. - Used to turn General MIDI level 1 or 2 on, or turn them off.
- A MIDI Machine Control Information Field, which functions something like an address
- What loop a
SampleDumpMsgorExtendedSampleDumpMsgis referring to. - The type of loop being described by a
SampleDumpMsg. - A MIDI Machine Control Command. Used by
UniversalRealTimeMsg::MachineControlCommand. - A MIDI Machine Control Response> Used by
UniversalRealTimeMsg::MachineControlResponse. - A meta event in a Standard Midi File
- The primary interface of this library. Used to encode MIDI messages.
- Used by
ControlChange::Parameter. “Entry” Parameters can be used to set the given parameters: they will first select that parameter, then send aControlChange::DataEntrywith the given value. - Returned when
MidiMsg::from_midiand similar where not successful. - Used by
ChannelModeMsg::PolyMode. - The type of reverb, used by
GlobalParameterControl::reverb. - The format of a Standard Midi File
- Used to request and transmit sampler data. Used by
UniversalNonRealTimeMsg::SampleDump. - How to map a file for MIDI reference. Used by
FileReferenceMsg::SelectContents. - A MIDI Show Control command. Used by
UniversalRealTimeMsg::ShowControl. - The “slot” of the device being referred to by
GlobalParameterControl. Values other thanUnregisteredcome from the General MIDI 2 spec. - Used by
StandardTimeCode. - A fairly limited set of messages, generally for device synchronization. Used in
MidiMsg. - The bulk of the MIDI spec lives here, in “Universal System Exclusive” messages. Also used for manufacturer-specific messages. Used in
MidiMsg. - A fairly limited set of messages used for device synchronization. Used in
MidiMsg. - Realtime Time Code Cueing. Used by
UniversalRealTimeMsg::TimeCodeCueing. - Non-realtime Time Code Cueing. Used by
UniversalNonRealTimeMsg::TimeCodeCueingSetup. - Indicates the frame rate of the given
TimeCode. - A track in a Standard Midi File
- A diverse range of messages for non-real-time applications. Used by
SystemExclusiveMsg::UniversalNonRealTime. - A diverse range of messages for real-time applications. Used by
SystemExclusiveMsg::UniversalRealTime.
Functions§
- Given a frequency in Hertz, returns (midi_note_number, additional cents from semitone)
- Given a frequency in Hertz, returns a floating point midi note number with 1.0 = 100 cents
- Given a midi note number and additional cents, return the frequency
- Given a floating point midi note number, return the frequency in Hertz
- Find the index of the next message in a MIDI byte sequence. This is useful for being able to skip over messages, which may be necessary when a message is unable to be deserialized.