midi_msg/system_exclusive/
machine_control.rs1use crate::parse_error::*;
2use crate::time_code::*;
3use alloc::vec::Vec;
4
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum MachineControlCommandMsg {
15 Stop,
16 Play,
17 DeferredPlay,
18 FastForward,
19 Rewind,
20 RecordStrobe,
21 RecordExit,
22 RecordPause,
23 Pause,
24 Eject,
25 Chase,
26 CommandErrorReset,
27 MMCReset,
28 LocateInformationField(InformationField),
31 LocateTarget(StandardTimeCode),
32 Wait,
35 Resume,
36 Unimplemented(Vec<u8>),
39}
40
41impl MachineControlCommandMsg {
42 pub(crate) fn extend_midi(&self, v: &mut Vec<u8>) {
43 match self {
44 Self::Stop => v.push(0x01),
45 Self::Play => v.push(0x02),
46 Self::DeferredPlay => v.push(0x03),
47 Self::FastForward => v.push(0x04),
48 Self::Rewind => v.push(0x05),
49 Self::RecordStrobe => v.push(0x06),
50 Self::RecordExit => v.push(0x07),
51 Self::RecordPause => v.push(0x08),
52 Self::Pause => v.push(0x09),
53 Self::Eject => v.push(0x0A),
54 Self::Chase => v.push(0x0B),
55 Self::CommandErrorReset => v.push(0x0C),
56 Self::MMCReset => v.push(0x0D),
57 Self::LocateInformationField(f) => {
58 v.push(0x44);
59 v.push(0x2); v.push(0x0); v.push(*f as u8);
62 }
63 Self::LocateTarget(stc) => {
64 v.push(0x44);
65 v.push(0x6); v.push(0x1); stc.extend_midi(v);
68 }
69 Self::Wait => v.push(0x01),
70 Self::Resume => v.push(0x01),
71 Self::Unimplemented(d) => v.extend_from_slice(d),
72 }
73 }
74
75 #[allow(dead_code)]
76 pub(crate) fn from_midi(_: &[u8]) -> Result<(Self, usize), ParseError> {
77 Err(ParseError::NotImplemented("MachineControlCommandMsg"))
78 }
79}
80
81#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
85#[derive(Debug, Clone, Copy, PartialEq, Eq)]
86pub enum InformationField {
87 SelectedTimeCode = 0x01,
88 SelectedMasterCode = 0x02,
89 RequestedOffset = 0x03,
90 ActualOffset = 0x04,
91 LockDeviation = 0x05,
92 GeneratorTimeCode = 0x06,
93 MidiTimeCodeInput = 0x07,
94 GP0 = 0x08,
95 GP1 = 0x09,
96 GP2 = 0x0A,
97 GP3 = 0x0B,
98 GP4 = 0x0C,
99 GP5 = 0x0D,
100 GP6 = 0x0E,
101 GP7 = 0x0F,
102 }
105
106#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
113#[derive(Debug, Clone, PartialEq, Eq)]
114pub enum MachineControlResponseMsg {
115 Unimplemented(Vec<u8>),
118}
119
120impl MachineControlResponseMsg {
121 pub(crate) fn extend_midi(&self, v: &mut Vec<u8>) {
122 match self {
123 Self::Unimplemented(d) => v.extend_from_slice(d),
124 }
125 }
126
127 #[allow(dead_code)]
128 pub(crate) fn from_midi(_m: &[u8]) -> Result<(Self, usize), ParseError> {
129 Err(ParseError::NotImplemented("MachineControlResponseMsg"))
130 }
131}
132
133#[doc(hidden)]
134#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
136pub struct StandardSpeed(pub f32);
137
138impl StandardSpeed {
139 #[allow(dead_code)]
140 pub(crate) fn extend_midi(&self, _: &mut Vec<u8>) {
141 todo!()
142 }
143}
144
145#[doc(hidden)]
146#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
148pub struct StandardTrack {
149 pub video_active: bool,
150 pub time_code_active: bool,
151 pub time_code_track_active: bool,
152 pub aux_track_a_active: bool,
153 pub aux_track_b_active: bool,
154 pub track_1_active: bool,
155 pub track_2_active: bool,
156 pub other_tracks: Vec<bool>,
157}
158
159impl StandardTrack {
160 #[allow(dead_code)]
161 pub(crate) fn extend_midi(&self, _: &mut Vec<u8>) {
162 todo!()
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use crate::*;
169 use alloc::vec;
170
171 #[test]
172 fn serialize_machine_control_msg() {
173 assert_eq!(
174 MidiMsg::SystemExclusive {
175 msg: SystemExclusiveMsg::UniversalRealTime {
176 device: DeviceID::AllCall,
177 msg: UniversalRealTimeMsg::MachineControlCommand(
178 MachineControlCommandMsg::Stop
179 ),
180 },
181 }
182 .to_midi(),
183 vec![0xF0, 0x7F, 0x7f, 0x6, 0x1, 0xF7]
184 );
185
186 assert_eq!(
187 MidiMsg::SystemExclusive {
188 msg: SystemExclusiveMsg::UniversalRealTime {
189 device: DeviceID::AllCall,
190 msg: UniversalRealTimeMsg::MachineControlCommand(
191 MachineControlCommandMsg::LocateTarget(StandardTimeCode {
192 seconds: 0x20,
193 code_type: TimeCodeType::FPS24, ..Default::default()
195 })
196 ),
197 },
198 }
199 .to_midi(),
200 vec![
201 0xF0, 0x7F, 0x7f, 0x6, 0x44, 0x06, 0x1, 0x0, 0x0, 0x20, 0x0, 0x0, 0xF7
208 ]
209 );
210 }
211}