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