Skip to main content

sim_lib_midi_core/
wire.rs

1//! Canonical MIDI channel-message wire bytes.
2//!
3//! The status-nibble + data-byte layout of a [`ChannelMessage`] is fixed by the
4//! MIDI spec; the SMF writer and the wasm frame model each hand-rolled the same
5//! `match`. This is the one home for it (OVERLAP6.14).
6
7use crate::ChannelMessage;
8
9/// Encode a channel message to its `(status, data)` wire bytes.
10///
11/// Pitch-bend's two data bytes are masked to 7 bits each, per the MIDI spec.
12pub fn encode_channel(message: &ChannelMessage) -> (u8, Vec<u8>) {
13    match *message {
14        ChannelMessage::NoteOff { ch, key, vel } => (0x80 | ch.0, vec![key.0, vel.0]),
15        ChannelMessage::NoteOn { ch, key, vel } => (0x90 | ch.0, vec![key.0, vel.0]),
16        ChannelMessage::PolyAftertouch { ch, key, pressure } => {
17            (0xa0 | ch.0, vec![key.0, pressure.0])
18        }
19        ChannelMessage::ControlChange { ch, cc, value } => (0xb0 | ch.0, vec![cc.0, value.0]),
20        ChannelMessage::ProgramChange { ch, program } => (0xc0 | ch.0, vec![program.0]),
21        ChannelMessage::ChanAftertouch { ch, pressure } => (0xd0 | ch.0, vec![pressure.0]),
22        ChannelMessage::PitchBend { ch, value } => (
23            0xe0 | ch.0,
24            vec![(value.0 & 0x7f) as u8, ((value.0 >> 7) & 0x7f) as u8],
25        ),
26    }
27}