[−][src]Trait helgoboss_midi::ShortMessage
A single short MIDI message, where short means it's made up by a maximum of 3 bytes.
This trait is supposed to be implemented for structs that represent a short MIDI message. Only the three byte-returning methods need to be implemented, the rest is done by default methods. Optimizations can be applied by overwriting default methods.
Please also implement the trait ShortMessageFactory
for your struct if creating new short
messages should be supported.
Design
Why a trait and not just a data structure?
The advantage of using a trait is that a unified API can be used to work with short MIDI
messages regardless of the underlying data structure. This crate comes with two implementations:
the "no-fuzz" byte-based data structure RawShortMessage
and the match-friendly data
structure StructuredShortMessage
. Each one has its own subtle strengths, yet both are really
just MIDI messages and should have the same capabilities. This fact is reflected by having a
common trait.
If there wouldn't be a trait, we would probably keep the StructuredShortMessage
implementation and ditch RawShortMessage
. But this would come at a small cost. In real-world
applications, short MIDI messages are constructed from raw bytes. When creating a
StructuredShortMessage
from raw bytes, a small amount of conversion is required - even if
the consumer doesn't need the matching capabilities at all. With RawShortMessage
, it's just
a matter of copying the bytes. The conversion can happen at a later point when we have to
inspect the message. However, keeping only RawShortMessage
is also not a good idea because
then we lose the matching capabilities.
Another benefit is flexibility. We might have an existing struct (e.g. an FFI struct) which
already represents a short MIDI message. Okay, in this case we could just eagerly copy those 3
bytes to a RawShortMessage
, that's cheap. But what if that existing struct represents more
than a short MIDI message, e.g. it also supports System Exclusive messages or carries MIDI
event information such as a frame? Then simply copying it a dozen times can decrease
performance. So we might want to pass it around as a reference instead. Then we can just
implement the trait for it and it will look and behave like a short MIDI message.
Why doesn't this trait support System Exclusive messages?
This trait is not designed to represent messages that are longer than 3 bytes, such as complete
System Exclusive messages. One benefit is that implementations of this trait can easily get by
without doing heap allocations. This is important because MIDI messages are often processed in a
real-time thread where things need to happen fast and heap allocations are a no-go. Also,
implementations can be made copyable just by deriving Copy
, which is essential for passing
around messages by copying rather then dealing with references.
For the majority of use cases, System Exclusive messages are not necessary. Support for them can be built as a separate data structure on top of this trait and will probably added to helgoboss-midi in future.
Why doesn't this trait support 14-bit Control Change or (N)RPN messages?
This trait is not used to represent MIDI messages made up by multiple short messages, such as (N)RPN messages. Those are implemented in separate structs in order to follow the single-responsibility principle.
Why do methods in this trait take self by reference?
Methods of this trait take self by reference, not by value. Other functions in this crate do
the same, as long as they don't take a concrete short MIDI message type. This might seem
unnecessary considering that it takes only 3 bytes to represent a short MIDI message and that
they are usually Copy
. The reason for still taking a reference is the same like mentioned
above: Existing structs that implement this trait could represent more than just a short MIDI
message, consist of more than 3 bytes and not even be Copy
- we just don't know when we work
with generics.
Required methods
pub fn status_byte(&self) -> u8
[src]
Returns the status byte.
pub fn data_byte_1(&self) -> U7
[src]
Returns the first data byte.
pub fn data_byte_2(&self) -> U7
[src]
Returns the second data byte.
Provided methods
pub fn to_bytes(&self) -> (u8, U7, U7)
[src]
Returns the status byte and the two data bytes as a tuple.
Implementations can override this default implementation if it's cheaper to get all bytes in one go.
pub fn to_other<O: ShortMessageFactory>(&self) -> O
[src]
Converts this message to a short message of another type.
pub fn to_structured(&self) -> StructuredShortMessage
[src]
Converts this message to a StructuredShortMessage
, which is ideal for matching.
pub fn type(&self) -> ShortMessageType
[src]
Returns the type of this message.
pub fn super_type(&self) -> MessageSuperType
[src]
Returns the super type of this message.
pub fn main_category(&self) -> MessageMainCategory
[src]
Returns the main category of this message.
pub fn is_note_on(&self) -> bool
[src]
Returns whether this message is a note-on in a practical sense. That means, it also returns
false
if the message type is NoteOn
but the velocity is zero.
pub fn is_note_off(&self) -> bool
[src]
Returns whether this message is a note-off in a practical sense. That means, it also returns
true
if the message type is NoteOn
but the velocity is zero.
pub fn is_note(&self) -> bool
[src]
Returns whether this message is a note-on or note-off.
pub fn channel(&self) -> Option<Channel>
[src]
Returns the channel of this message if applicable.
pub fn key_number(&self) -> Option<KeyNumber>
[src]
Returns the key number of this message if applicable.
pub fn velocity(&self) -> Option<U7>
[src]
Returns the velocity of this message if applicable.
pub fn controller_number(&self) -> Option<ControllerNumber>
[src]
Returns the controller number of this message if applicable.
pub fn control_value(&self) -> Option<U7>
[src]
Returns the control value of this message if applicable.
pub fn program_number(&self) -> Option<U7>
[src]
Returns the program number of this message if applicable.
pub fn pressure_amount(&self) -> Option<U7>
[src]
Returns the pressure amount of this message if applicable.
pub fn pitch_bend_value(&self) -> Option<U14>
[src]
Returns the pitch bend value of this message if applicable.