use crate::parse_error::*;
use crate::time_code::*;
#[derive(Debug, Clone, PartialEq)]
pub enum MachineControlCommandMsg {
Stop,
Play,
DeferredPlay,
FastForward,
Rewind,
RecordStrobe,
RecordExit,
RecordPause,
Pause,
Eject,
Chase,
CommandErrorReset,
MMCReset,
LocateInformationField(InformationField),
LocateTarget(StandardTimeCode),
Wait,
Resume,
Unimplemented(Vec<u8>),
}
impl MachineControlCommandMsg {
pub(crate) fn extend_midi(&self, v: &mut Vec<u8>) {
match self {
Self::Stop => v.push(0x01),
Self::Play => v.push(0x02),
Self::DeferredPlay => v.push(0x03),
Self::FastForward => v.push(0x04),
Self::Rewind => v.push(0x05),
Self::RecordStrobe => v.push(0x06),
Self::RecordExit => v.push(0x07),
Self::RecordPause => v.push(0x08),
Self::Pause => v.push(0x09),
Self::Eject => v.push(0x0A),
Self::Chase => v.push(0x0B),
Self::CommandErrorReset => v.push(0x0C),
Self::MMCReset => v.push(0x0D),
Self::LocateInformationField(f) => {
v.push(0x44);
v.push(2);
v.push(0);
v.push(*f as u8);
}
Self::LocateTarget(stc) => {
v.push(0x44);
v.push(6);
v.push(1);
stc.extend_midi(v);
}
Self::Wait => v.push(0x01),
Self::Resume => v.push(0x01),
Self::Unimplemented(d) => v.extend_from_slice(d),
}
}
#[allow(dead_code)]
pub(crate) fn from_midi(_m: &[u8]) -> Result<(Self, usize), ParseError> {
Err(ParseError::Invalid(format!("TODO: Not implemented")))
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum InformationField {
SelectedTimeCode = 0x01,
SelectedMasterCode = 0x02,
RequestedOffset = 0x03,
ActualOffset = 0x04,
LockDeviation = 0x05,
GeneratorTimeCode = 0x06,
MidiTimeCodeInput = 0x07,
GP0 = 0x08,
GP1 = 0x09,
GP2 = 0x0A,
GP3 = 0x0B,
GP4 = 0x0C,
GP5 = 0x0D,
GP6 = 0x0E,
GP7 = 0x0F,
}
#[derive(Debug, Clone, PartialEq)]
pub enum MachineControlResponseMsg {
Unimplemented(Vec<u8>),
}
impl MachineControlResponseMsg {
pub(crate) fn extend_midi(&self, v: &mut Vec<u8>) {
match self {
Self::Unimplemented(d) => v.extend_from_slice(d),
}
}
#[allow(dead_code)]
pub(crate) fn from_midi(_m: &[u8]) -> Result<(Self, usize), ParseError> {
Err(ParseError::Invalid(format!("TODO: Not implemented")))
}
}
#[doc(hidden)]
pub struct StandardSpeed(f32);
impl StandardSpeed {
#[allow(dead_code)]
pub(crate) fn extend_midi(&self, _v: &mut Vec<u8>) {
}
}
#[doc(hidden)]
pub struct StandardTrack {
pub video_active: bool,
pub time_code_active: bool,
pub time_code_track_active: bool,
pub aux_track_a_active: bool,
pub aux_track_b_active: bool,
pub track_1_active: bool,
pub track_2_active: bool,
pub other_tracks: Vec<bool>,
}
impl StandardTrack {
#[allow(dead_code)]
pub(crate) fn extend_midi(&self, _v: &mut Vec<u8>) {
}
}
#[cfg(test)]
mod tests {
use crate::*;
#[test]
fn serialize_machine_control_msg() {
assert_eq!(
MidiMsg::SystemExclusive {
msg: SystemExclusiveMsg::UniversalRealTime {
device: DeviceID::AllCall,
msg: UniversalRealTimeMsg::MachineControlCommand(
MachineControlCommandMsg::Stop
),
},
}
.to_midi(),
vec![0xF0, 0x7F, 0x7f, 06, 01, 0xF7]
);
assert_eq!(
MidiMsg::SystemExclusive {
msg: SystemExclusiveMsg::UniversalRealTime {
device: DeviceID::AllCall,
msg: UniversalRealTimeMsg::MachineControlCommand(
MachineControlCommandMsg::LocateTarget(StandardTimeCode {
seconds: 0x20,
code_type: TimeCodeType::FPS24,
..Default::default()
})
),
},
}
.to_midi(),
vec![
0xF0, 0x7F, 0x7f,
06,
0x44,
0x06,
01,
0, 0, 0x20, 0, 0,
0xF7
]
);
}
}