use crate::prelude::*;
use std::io::ErrorKind;
#[doc = r#"
One-byte messages that only occur in live MIDI events.
Real-Time messages are used for synchronization and are intended for all clock-
based units in a system. They contain Status bytes only — no Data bytes. Real-
Time messages may be sent at any time — even between bytes of a message which has
a different status. In such cases the Real-Time message is either acted upon or
ignored, after which the receiving process resumes under the previous status.
They are usually time-sensitive, get top priority and can even be transmitted in between other
messages.
"#]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum SystemRealTimeMessage {
TimingClock,
Start,
Continue,
Stop,
ActiveSensing,
Reset,
Undefined(u8),
}
impl SystemRealTimeMessage {
pub fn byte(&self) -> u8 {
use SystemRealTimeMessage::*;
match self {
TimingClock => 0xF8,
Undefined(s) => *s,
Start => 0xFA,
Continue => 0xFB,
Stop => 0xFC,
ActiveSensing => 0xFE,
Reset => 0xFF,
}
}
pub fn from_byte(rep: u8) -> Result<Self, std::io::Error> {
use SystemRealTimeMessage::*;
Ok(match rep {
0xF8 => TimingClock,
0xFA => Start,
0xFB => Continue,
0xFC => Stop,
0xFE => ActiveSensing,
0xFF => Reset,
_ => {
Undefined(rep)
}
})
}
}
impl FromLiveEventBytes for SystemRealTimeMessage {
const MIN_STATUS_BYTE: u8 = 0xF8;
const MAX_STATUS_BYTE: u8 = 0xFF;
fn from_status_and_data(status: u8, bytes: &[u8]) -> Result<Self, std::io::Error> {
if bytes.is_empty() {
return Err(io_error!(
ErrorKind::InvalidData,
"System real time messages do not have data bytes"
));
}
Self::from_byte(status)
}
}