use std::convert::{TryFrom, TryInto};
use crate::midi::{Control, Event, Message, Note};
#[derive(Debug)]
#[repr(transparent)]
pub(crate) struct Midi(pub(crate) [u8; 4]);
impl From<Midi> for Event {
fn from(other: Midi) -> Event {
if other.0 == [0xFF; 4] {
return Event::Disconnect;
}
let chan = other.0[0] & 0x0F;
let id = other.0[1].try_into().unwrap();
let note = Note::try_from(other.0[1]).unwrap();
let value = other.0[2].try_into().unwrap();
match other.0[0] & 0xF0 {
0x80 => Event::NoteOff { chan, note, value },
0x90 => Event::NoteOn { chan, note, value },
0xA0 => Event::NoteTouch { chan, note, value },
0xB0 => Event::Control {
chan,
message: Control::new(id, value),
},
0xC0 => Event::Instrument {
chan,
patch: [id, value],
},
0xD0 => Event::Pressure { chan, value: id },
0xE0 => Event::Bend {
chan,
lsb: id,
msb: value,
},
0xF0 => Event::System {
message: match chan {
0x0 => Message::ExStart,
0x1 => Message::TimeCode,
0x2 => Message::SongPosition,
0x3 => Message::SongSelect,
0x6 => Message::TuneRequest,
0x7 => Message::ExEnd,
0x8 => Message::TimingClock,
0xA => Message::Start,
0xB => Message::Continue,
0xC => Message::Stop,
0xE => Message::ActiveSensing,
0xF => Message::SystemReset,
_ => Message::Unknown(other.0[0]),
},
},
a => {
panic!("FIXME: Unknown MIDI event {:X}", a)
}
}
}
}