1use super::*;
50
51#[derive(Default, Debug)]
53pub struct Inspire1394ClkProtocol;
54
55impl MediaClockFrequencyOperation for Inspire1394ClkProtocol {
56 const FREQ_LIST: &'static [u32] = &[44100, 48000, 88200, 96000];
57}
58
59impl SamplingClockSourceOperation for Inspire1394ClkProtocol {
60 const DST: SignalAddr = SignalAddr::Subunit(SignalSubunitAddr {
61 subunit: MUSIC_SUBUNIT_0,
62 plug_id: 0x03,
63 });
64
65 const SRC_LIST: &'static [SignalAddr] = &[
66 SignalAddr::Subunit(SignalSubunitAddr {
68 subunit: MUSIC_SUBUNIT_0,
69 plug_id: 0x02,
70 }),
71 ];
72}
73
74#[derive(Default, Debug)]
76pub struct Inspire1394PhysInputProtocol;
77
78impl AvcAudioFeatureSpecification for Inspire1394PhysInputProtocol {
79 const ENTRIES: &'static [(u8, AudioCh)] = &[
80 (0x1, AudioCh::Each(0)),
81 (0x1, AudioCh::Each(1)),
82 (0x2, AudioCh::Each(0)),
83 (0x2, AudioCh::Each(1)),
84 ];
85}
86
87impl AvcLevelOperation for Inspire1394PhysInputProtocol {}
88
89impl AvcMuteOperation for Inspire1394PhysInputProtocol {}
90
91#[derive(Default, Debug)]
93pub struct Inspire1394PhysOutputProtocol;
94
95impl AvcAudioFeatureSpecification for Inspire1394PhysOutputProtocol {
96 const ENTRIES: &'static [(u8, AudioCh)] = &[(0x06, AudioCh::Each(0)), (0x06, AudioCh::Each(1))];
97}
98
99impl AvcLevelOperation for Inspire1394PhysOutputProtocol {}
100
101impl AvcMuteOperation for Inspire1394PhysOutputProtocol {}
102
103impl AvcSelectorOperation for Inspire1394PhysOutputProtocol {
104 const FUNC_BLOCK_ID_LIST: &'static [u8] = &[0x01];
105 const INPUT_PLUG_ID_LIST: &'static [u8] = &[0x00, 0x01];
107}
108
109#[derive(Default, Debug)]
111pub struct Inspire1394HeadphoneProtocol;
112
113impl AvcAudioFeatureSpecification for Inspire1394HeadphoneProtocol {
114 const ENTRIES: &'static [(u8, AudioCh)] = &[(0x07, AudioCh::Each(0)), (0x07, AudioCh::Each(1))];
115}
116
117impl AvcLevelOperation for Inspire1394HeadphoneProtocol {}
118
119impl AvcMuteOperation for Inspire1394HeadphoneProtocol {}
120
121#[derive(Default, Debug)]
123pub struct Inspire1394MixerAnalogSourceProtocol;
124
125impl AvcAudioFeatureSpecification for Inspire1394MixerAnalogSourceProtocol {
126 const ENTRIES: &'static [(u8, AudioCh)] = &[
127 (0x03, AudioCh::Each(0)),
128 (0x03, AudioCh::Each(1)),
129 (0x04, AudioCh::Each(0)),
130 (0x04, AudioCh::Each(1)),
131 ];
132}
133
134impl AvcLevelOperation for Inspire1394MixerAnalogSourceProtocol {}
135
136impl AvcLrBalanceOperation for Inspire1394MixerAnalogSourceProtocol {}
137
138impl AvcMuteOperation for Inspire1394MixerAnalogSourceProtocol {}
139
140#[derive(Default, Debug)]
142pub struct Inspire1394MixerStreamSourceProtocol;
143
144impl AvcAudioFeatureSpecification for Inspire1394MixerStreamSourceProtocol {
145 const ENTRIES: &'static [(u8, AudioCh)] = &[(0x05, AudioCh::Master)];
146}
147
148impl AvcLevelOperation for Inspire1394MixerStreamSourceProtocol {}
149
150impl AvcMuteOperation for Inspire1394MixerStreamSourceProtocol {}
151
152const METER_FRAME_SIZE: usize = 32;
153
154#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
156pub struct Inspire1394Meter {
157 pub phys_inputs: [i32; 4],
158 pub stream_inputs: [i32; 2],
159 pub phys_outputs: [i32; 2],
160 frame: [u8; METER_FRAME_SIZE],
161}
162
163#[derive(Default, Debug)]
165pub struct Inspire1394MeterProtocol;
166
167impl Inspire1394MeterProtocol {
168 pub const LEVEL_MIN: i32 = 0;
170 pub const LEVEL_MAX: i32 = 0x07ffffff;
172 pub const LEVEL_STEP: i32 = 0x100;
174
175 pub fn cache(
177 req: &FwReq,
178 node: &FwNode,
179 meter: &mut Inspire1394Meter,
180 timeout_ms: u32,
181 ) -> Result<(), Error> {
182 let frame = &mut meter.frame;
183 req.transaction_sync(
184 node,
185 FwTcode::ReadBlockRequest,
186 DM_APPL_METER_OFFSET,
187 METER_FRAME_SIZE,
188 frame,
189 timeout_ms,
190 )?;
191
192 let mut quadlet = [0u8; 4];
193 meter
194 .phys_inputs
195 .iter_mut()
196 .chain(&mut meter.stream_inputs)
197 .chain(&mut meter.phys_outputs)
198 .enumerate()
199 .for_each(|(i, m)| {
200 let pos = i * 4;
201 quadlet.copy_from_slice(&frame[pos..(pos + 4)]);
202 *m = i32::from_be_bytes(quadlet);
203 });
204
205 Ok(())
206 }
207}
208
209#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
211pub struct Inspire1394SwitchParameters {
212 pub pair1_phono: bool,
214 pub pair0_phantom: [bool; 2],
216 pub pair0_boost: [bool; 2],
218 pub pair0_limit: [bool; 2],
220}
221
222#[derive(Default, Debug)]
224pub struct Inspire1394SwitchProtocol;
225
226impl Inspire1394SwitchProtocol {
227 pub fn cache(
228 avc: &BebobAvc,
229 params: &mut Inspire1394SwitchParameters,
230 timeout_ms: u32,
231 ) -> Result<(), Error> {
232 [
233 InputSwitch::Analog34Phono(Default::default()),
234 InputSwitch::Analog12Phantom(0, Default::default()),
235 InputSwitch::Analog12Phantom(1, Default::default()),
236 InputSwitch::Analog12Boost(0, Default::default()),
237 InputSwitch::Analog12Boost(1, Default::default()),
238 InputSwitch::Analog12Limit(0, Default::default()),
239 InputSwitch::Analog12Limit(1, Default::default()),
240 ]
241 .iter()
242 .try_for_each(|switch| {
243 let mut op = InputSwitchOperation::new(switch);
244 avc.status(&AvcAddr::Subunit(MUSIC_SUBUNIT_0), &mut op, timeout_ms)?;
245 match op.switch {
246 InputSwitch::Analog34Phono(val) => params.pair1_phono = val,
247 InputSwitch::Analog12Phantom(idx, val) => params.pair0_phantom[idx] = val,
248 InputSwitch::Analog12Boost(idx, val) => params.pair0_boost[idx] = val,
249 InputSwitch::Analog12Limit(idx, val) => params.pair0_limit[idx] = val,
250 _ => (),
251 }
252 Ok(())
253 })
254 }
255
256 pub fn update(
257 avc: &BebobAvc,
258 params: &Inspire1394SwitchParameters,
259 prev: &mut Inspire1394SwitchParameters,
260 timeout_ms: u32,
261 ) -> Result<(), Error> {
262 Self::build_switches(prev)
263 .iter()
264 .zip(Self::build_switches(params).iter())
265 .filter(|(o, n)| !n.eq(o))
266 .try_for_each(|(_, new)| {
267 let mut op = InputSwitchOperation::new(new);
268 avc.control(&AvcAddr::Subunit(MUSIC_SUBUNIT_0), &mut op, timeout_ms)
269 })
270 .map(|_| *prev = *params)
271 }
272
273 fn build_switches(params: &Inspire1394SwitchParameters) -> Vec<InputSwitch> {
274 vec![
275 InputSwitch::Analog34Phono(params.pair1_phono),
276 InputSwitch::Analog12Phantom(0, params.pair0_phantom[0]),
277 InputSwitch::Analog12Phantom(1, params.pair0_phantom[1]),
278 InputSwitch::Analog12Boost(0, params.pair0_boost[0]),
279 InputSwitch::Analog12Boost(1, params.pair0_boost[1]),
280 InputSwitch::Analog12Limit(0, params.pair0_limit[0]),
281 InputSwitch::Analog12Limit(1, params.pair0_limit[1]),
282 ]
283 }
284}
285
286#[derive(Debug, Copy, Clone, PartialEq, Eq)]
288pub enum InputSwitch {
289 Analog34Phono(bool),
291 Analog12Phantom(usize, bool),
293 Analog12Boost(usize, bool),
295 Analog12Limit(usize, bool),
297 #[allow(dead_code)]
299 AnalogStereoLink(usize, bool),
300}
301
302const CMD_PHONO: u8 = 0x00;
303const CMD_MIC_PHANTOM: u8 = 0x01;
304const CMD_MIC_BOOST: u8 = 0x02;
305const CMD_MIC_LIMIT: u8 = 0x03;
306const CMD_STEREO_LINK: u8 = 0x05;
307
308impl Default for InputSwitch {
309 fn default() -> Self {
310 Self::Analog34Phono(false)
311 }
312}
313
314#[derive(Debug)]
316pub struct InputSwitchOperation {
317 pub switch: InputSwitch,
319 op: VendorDependent,
320}
321
322impl Default for InputSwitchOperation {
323 fn default() -> Self {
324 Self {
325 switch: Default::default(),
326 op: VendorDependent {
327 company_id: PRESONUS_OUI,
328 data: vec![0; 3],
329 },
330 }
331 }
332}
333
334impl InputSwitchOperation {
335 fn new(switch: &InputSwitch) -> Self {
336 let mut op = Self::default();
337 op.switch = *switch;
338 op
339 }
340}
341
342impl AvcOp for InputSwitchOperation {
343 const OPCODE: u8 = VendorDependent::OPCODE;
344}
345
346impl AvcControl for InputSwitchOperation {
347 fn build_operands(&mut self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
348 match self.switch {
349 InputSwitch::Analog34Phono(state) => {
350 self.op.data[0] = CMD_PHONO;
351 self.op.data[1] = 0x00;
352 self.op.data[2] = state as u8;
353 }
354 InputSwitch::Analog12Phantom(ch, state) => {
355 self.op.data[0] = CMD_MIC_PHANTOM;
356 self.op.data[1] = 1 + ch as u8;
357 self.op.data[2] = state as u8;
358 }
359 InputSwitch::Analog12Boost(ch, state) => {
360 self.op.data[0] = CMD_MIC_BOOST;
361 self.op.data[1] = 1 + ch as u8;
362 self.op.data[2] = state as u8;
363 }
364 InputSwitch::Analog12Limit(ch, state) => {
365 self.op.data[0] = CMD_MIC_LIMIT;
366 self.op.data[1] = 1 + ch as u8;
367 self.op.data[2] = state as u8;
368 }
369 InputSwitch::AnalogStereoLink(ch, state) => {
370 self.op.data[0] = CMD_STEREO_LINK;
371 self.op.data[1] = 1 + ch as u8;
372 self.op.data[2] = state as u8;
373 }
374 }
375 AvcControl::build_operands(&mut self.op, addr)
376 }
377
378 fn parse_operands(&mut self, addr: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
379 AvcControl::parse_operands(&mut self.op, addr, operands)
380 }
381}
382
383impl AvcStatus for InputSwitchOperation {
384 fn build_operands(&mut self, addr: &AvcAddr) -> Result<Vec<u8>, AvcCmdBuildError> {
385 match self.switch {
386 InputSwitch::Analog34Phono(_) => {
387 self.op.data[0] = CMD_PHONO;
388 self.op.data[1] = 0x00;
389 }
390 InputSwitch::Analog12Phantom(ch, _) => {
391 self.op.data[0] = CMD_PHONO;
392 self.op.data[1] = 1 + ch as u8;
393 }
394 InputSwitch::Analog12Boost(ch, _) => {
395 self.op.data[0] = CMD_PHONO;
396 self.op.data[1] = 1 + ch as u8;
397 }
398 InputSwitch::Analog12Limit(ch, _) => {
399 self.op.data[0] = CMD_PHONO;
400 self.op.data[1] = 1 + ch as u8;
401 }
402 InputSwitch::AnalogStereoLink(ch, _) => {
403 self.op.data[0] = CMD_STEREO_LINK;
404 self.op.data[1] = 1 + ch as u8;
405 }
406 }
407 self.op.data[2] = 0xff;
408 AvcControl::build_operands(&mut self.op, addr)
409 }
410
411 fn parse_operands(&mut self, addr: &AvcAddr, operands: &[u8]) -> Result<(), AvcRespParseError> {
412 AvcControl::parse_operands(&mut self.op, addr, operands).map(|_| match &mut self.switch {
413 InputSwitch::Analog34Phono(state) => {
414 *state = self.op.data[2] > 0;
415 }
416 InputSwitch::Analog12Phantom(_, state) => {
417 *state = self.op.data[2] > 0;
418 }
419 InputSwitch::Analog12Boost(_, state) => {
420 *state = self.op.data[2] > 0;
421 }
422 InputSwitch::Analog12Limit(_, state) => {
423 *state = self.op.data[2] > 0;
424 }
425 InputSwitch::AnalogStereoLink(_, state) => {
426 *state = self.op.data[2] > 0;
427 }
428 })
429 }
430}