midi-codec 0.4.0

Tools for encoding and decoding a stream of MIDI messages.
Documentation
#[derive(Debug, Clone, Copy)]
pub enum Status {
    ChannelVoice(ChannelVoiceStatus),
    SystemCommon(SystemCommonStatus),
    SystemExclusive,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RequiredDataBytes {
    D0,
    D1,
    D2,
}

impl Status {
    pub fn required_data_bytes(self) -> RequiredDataBytes {
        match self {
            Status::ChannelVoice(status) => status.status.required_data_bytes(),
            Status::SystemCommon(status) => status.required_data_bytes(),
            Status::SystemExclusive => RequiredDataBytes::D0,
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ChannelVoiceStatus {
    pub status: ChannelStatus,
    pub channel: u8,
}

impl From<ChannelVoiceStatus> for u8 {
    fn from(value: ChannelVoiceStatus) -> Self {
        let lower = value.channel & 0b1111;

        let upper = match value.status {
            ChannelStatus::NoteOff => 0b1000,
            ChannelStatus::NoteOn => 0b1001,
            ChannelStatus::PolyphonicPressure => 0b1010,
            ChannelStatus::ControlChange => 0b1011,
            ChannelStatus::ProgramChange => 0b1100,
            ChannelStatus::ChannelPressure => 0b1101,
            ChannelStatus::PitchBend => 0b1110,
        };

        upper << 4 | lower
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ChannelStatus {
    NoteOff,
    NoteOn,
    PolyphonicPressure,
    ControlChange,
    ProgramChange,
    ChannelPressure,
    PitchBend,
}

impl ChannelStatus {
    pub fn required_data_bytes(self) -> RequiredDataBytes {
        match self {
            ChannelStatus::NoteOff => RequiredDataBytes::D2,
            ChannelStatus::NoteOn => RequiredDataBytes::D2,
            ChannelStatus::PolyphonicPressure => RequiredDataBytes::D2,
            ChannelStatus::ControlChange => RequiredDataBytes::D2,
            ChannelStatus::ProgramChange => RequiredDataBytes::D1,
            ChannelStatus::ChannelPressure => RequiredDataBytes::D1,
            ChannelStatus::PitchBend => RequiredDataBytes::D2,
        }
    }
}

#[derive(Debug, Clone, Copy)]
pub enum SystemCommonStatus {
    MTCQuarterFrame,
    SongPositionPointer,
    SongSelect,
    Undefined1,
    Undefined2,
    TuneRequest,
    EOX,
}

impl SystemCommonStatus {
    pub fn required_data_bytes(self) -> RequiredDataBytes {
        match self {
            SystemCommonStatus::MTCQuarterFrame => RequiredDataBytes::D1,
            SystemCommonStatus::SongPositionPointer => RequiredDataBytes::D2,
            SystemCommonStatus::SongSelect => RequiredDataBytes::D1,
            SystemCommonStatus::Undefined1 => RequiredDataBytes::D0,
            SystemCommonStatus::Undefined2 => RequiredDataBytes::D0,
            SystemCommonStatus::TuneRequest => RequiredDataBytes::D0,
            SystemCommonStatus::EOX => RequiredDataBytes::D0,
        }
    }
}

impl From<SystemCommonStatus> for u8 {
    fn from(value: SystemCommonStatus) -> Self {
        match value {
            SystemCommonStatus::MTCQuarterFrame => 0b1111_0001,
            SystemCommonStatus::SongPositionPointer => 0b1111_0010,
            SystemCommonStatus::SongSelect => 0b1111_0011,
            SystemCommonStatus::Undefined1 => 0b1111_0100,
            SystemCommonStatus::Undefined2 => 0b1111_0101,
            SystemCommonStatus::TuneRequest => 0b1111_0110,
            SystemCommonStatus::EOX => 0b1111_0111,
        }
    }
}