1use super::*;
82
83#[derive(Default, Debug)]
85pub struct ItwinProtocol;
86
87impl TcatOperation for ItwinProtocol {}
88
89impl TcatGlobalSectionSpecification for ItwinProtocol {}
90
91pub type ItwinKnobSegment = TcKonnektSegment<ItwinKnob>;
93
94pub type ItwinConfigSegment = TcKonnektSegment<ItwinConfig>;
96
97pub type ItwinMixerStateSegment = TcKonnektSegment<ItwinMixerState>;
99
100pub type ItwinReverbStateSegment = TcKonnektSegment<ItwinReverbState>;
102
103pub type ItwinChStripStatesSegment = TcKonnektSegment<ItwinChStripStates>;
105
106pub type ItwinMixerMeterSegment = TcKonnektSegment<ItwinMixerMeter>;
110
111pub type ItwinHwStateSegment = TcKonnektSegment<ItwinHwState>;
113
114pub type ItwinReverbMeterSegment = TcKonnektSegment<ItwinReverbMeter>;
116
117pub type ItwinChStripMetersSegment = TcKonnektSegment<ItwinChStripMeters>;
119
120macro_rules! segment_default {
121 ($p:ty, $t:ty) => {
122 impl Default for TcKonnektSegment<$t> {
123 fn default() -> Self {
124 Self {
125 data: <$t>::default(),
126 raw: vec![0; <$p as TcKonnektSegmentSerdes<$t>>::SIZE],
127 }
128 }
129 }
130 };
131}
132
133segment_default!(ItwinProtocol, ItwinKnob);
134segment_default!(ItwinProtocol, ItwinConfig);
135segment_default!(ItwinProtocol, ItwinMixerState);
136segment_default!(ItwinProtocol, ItwinReverbState);
137segment_default!(ItwinProtocol, ItwinChStripStates);
138segment_default!(ItwinProtocol, ItwinMixerMeter);
139segment_default!(ItwinProtocol, ItwinHwState);
140segment_default!(ItwinProtocol, ItwinReverbMeter);
141segment_default!(ItwinProtocol, ItwinChStripMeters);
142
143#[derive(Debug, Copy, Clone, PartialEq, Eq)]
145pub struct ItwinKnob {
146 pub target: ShellKnob0Target,
148 pub clock_recovery: bool,
150}
151
152impl Default for ItwinKnob {
153 fn default() -> Self {
154 Self {
155 target: <ItwinProtocol as ShellKnob0TargetSpecification>::KNOB0_TARGETS[0],
156 clock_recovery: Default::default(),
157 }
158 }
159}
160
161impl ShellKnob0TargetSpecification for ItwinProtocol {
162 const KNOB0_TARGETS: &'static [ShellKnob0Target] = &[
163 ShellKnob0Target::ChannelStrip0,
164 ShellKnob0Target::ChannelStrip1,
165 ShellKnob0Target::Reverb,
166 ShellKnob0Target::Mixer,
167 ];
168}
169
170impl TcKonnektSegmentSerdes<ItwinKnob> for ItwinProtocol {
171 const NAME: &'static str = "knob";
172 const OFFSET: usize = 0x0004;
173 const SIZE: usize = SHELL_KNOB_SEGMENT_SIZE;
174
175 fn serialize(params: &ItwinKnob, raw: &mut [u8]) -> Result<(), String> {
176 serialize_knob0_target::<ItwinProtocol>(¶ms.target, &mut raw[..4])?;
177 serialize_bool(¶ms.clock_recovery, &mut raw[8..12]);
178 Ok(())
179 }
180
181 fn deserialize(params: &mut ItwinKnob, raw: &[u8]) -> Result<(), String> {
182 deserialize_knob0_target::<ItwinProtocol>(&mut params.target, &raw[..4])?;
183 deserialize_bool(&mut params.clock_recovery, &raw[8..12]);
184 Ok(())
185 }
186}
187
188impl TcKonnektMutableSegmentOperation<ItwinKnob> for ItwinProtocol {}
189
190impl TcKonnektNotifiedSegmentOperation<ItwinKnob> for ItwinProtocol {
191 const NOTIFY_FLAG: u32 = SHELL_KNOB_NOTIFY_FLAG;
192}
193
194impl AsRef<ShellKnob0Target> for ItwinKnob {
195 fn as_ref(&self) -> &ShellKnob0Target {
196 &self.target
197 }
198}
199
200impl AsMut<ShellKnob0Target> for ItwinKnob {
201 fn as_mut(&mut self) -> &mut ShellKnob0Target {
202 &mut self.target
203 }
204}
205
206pub const ITWIN_PHYS_OUT_PAIR_COUNT: usize = 7;
208
209#[derive(Debug, Copy, Clone, PartialEq, Eq)]
211pub enum ItwinOutputPairSrc {
212 MixerOut01,
214 Analog01,
216 Analog23,
218 Spdif01,
220 Adat01,
222 Adat23,
224 Adat45,
226 Adat67,
228 Stream01,
230 Stream23,
232 Stream45,
234 Stream67,
236 Stream89,
238 Stream1011,
240 Stream1213,
242 MixerSend01,
244}
245
246impl Default for ItwinOutputPairSrc {
247 fn default() -> Self {
248 Self::MixerOut01
249 }
250}
251
252const OUTPUT_PAIR_SOURCES: &[ItwinOutputPairSrc] = &[
253 ItwinOutputPairSrc::MixerOut01,
254 ItwinOutputPairSrc::Analog01,
255 ItwinOutputPairSrc::Analog23,
256 ItwinOutputPairSrc::Spdif01,
257 ItwinOutputPairSrc::Adat01,
258 ItwinOutputPairSrc::Adat23,
259 ItwinOutputPairSrc::Adat45,
260 ItwinOutputPairSrc::Adat67,
261 ItwinOutputPairSrc::Stream01,
262 ItwinOutputPairSrc::Stream23,
263 ItwinOutputPairSrc::Stream45,
264 ItwinOutputPairSrc::Stream67,
265 ItwinOutputPairSrc::Stream89,
266 ItwinOutputPairSrc::Stream1011,
267 ItwinOutputPairSrc::Stream1213,
268 ItwinOutputPairSrc::MixerSend01,
269];
270
271const OUTPUT_PAIR_SOURCE_LABEL: &str = "output pair source";
272
273fn serialize_output_pair_src(src: &ItwinOutputPairSrc, raw: &mut [u8]) -> Result<(), String> {
274 serialize_position(OUTPUT_PAIR_SOURCES, src, raw, OUTPUT_PAIR_SOURCE_LABEL)
275}
276
277fn deserialize_output_pair_src(src: &mut ItwinOutputPairSrc, raw: &[u8]) -> Result<(), String> {
278 deserialize_position(OUTPUT_PAIR_SOURCES, src, raw, OUTPUT_PAIR_SOURCE_LABEL)
279}
280
281#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
283pub struct ItwinConfig {
284 pub mixer_stream_src_pair: ShellMixerStreamSourcePair,
286 pub standalone_src: ShellStandaloneClockSource,
288 pub standalone_rate: TcKonnektStandaloneClockRate,
290 pub output_pair_src: [ItwinOutputPairSrc; ITWIN_PHYS_OUT_PAIR_COUNT],
292}
293
294impl ShellMixerStreamSourcePairSpecification for ItwinProtocol {
295 const MIXER_STREAM_SOURCE_PAIRS: &'static [ShellMixerStreamSourcePair] = &[
296 ShellMixerStreamSourcePair::Stream0_1,
297 ShellMixerStreamSourcePair::Stream2_3,
298 ShellMixerStreamSourcePair::Stream4_5,
299 ShellMixerStreamSourcePair::Stream6_7,
300 ShellMixerStreamSourcePair::Stream8_9,
301 ShellMixerStreamSourcePair::Stream10_11,
302 ShellMixerStreamSourcePair::Stream12_13,
303 ];
304}
305
306impl ShellStandaloneClockSpecification for ItwinProtocol {
307 const STANDALONE_CLOCK_SOURCES: &'static [ShellStandaloneClockSource] = &[
308 ShellStandaloneClockSource::Optical,
309 ShellStandaloneClockSource::Coaxial,
310 ShellStandaloneClockSource::Internal,
311 ];
312}
313
314impl TcKonnektSegmentSerdes<ItwinConfig> for ItwinProtocol {
315 const NAME: &'static str = "configuration";
316 const OFFSET: usize = 0x0028;
317 const SIZE: usize = 168;
318
319 fn serialize(params: &ItwinConfig, raw: &mut [u8]) -> Result<(), String> {
320 serialize_mixer_stream_source_pair::<ItwinProtocol>(
321 ¶ms.mixer_stream_src_pair,
322 &mut raw[24..28],
323 )?;
324 serialize_standalone_clock_source::<ItwinProtocol>(
325 ¶ms.standalone_src,
326 &mut raw[28..32],
327 )?;
328 serialize_standalone_clock_rate(¶ms.standalone_rate, &mut raw[32..36])?;
329 params
330 .output_pair_src
331 .iter()
332 .enumerate()
333 .try_for_each(|(i, src)| {
334 let pos = 120 + i * 4;
335 serialize_output_pair_src(src, &mut raw[pos..(pos + 4)])
336 })?;
337 Ok(())
338 }
339
340 fn deserialize(params: &mut ItwinConfig, raw: &[u8]) -> Result<(), String> {
341 deserialize_mixer_stream_source_pair::<ItwinProtocol>(
342 &mut params.mixer_stream_src_pair,
343 &raw[24..28],
344 )?;
345 deserialize_standalone_clock_source::<ItwinProtocol>(
346 &mut params.standalone_src,
347 &raw[28..32],
348 )?;
349 deserialize_standalone_clock_rate(&mut params.standalone_rate, &raw[32..36])?;
350 params
351 .output_pair_src
352 .iter_mut()
353 .enumerate()
354 .try_for_each(|(i, src)| {
355 let pos = 120 + i * 4;
356 deserialize_output_pair_src(src, &raw[pos..(pos + 4)])
357 })?;
358 Ok(())
359 }
360}
361
362impl TcKonnektMutableSegmentOperation<ItwinConfig> for ItwinProtocol {}
363
364impl TcKonnektNotifiedSegmentOperation<ItwinConfig> for ItwinProtocol {
365 const NOTIFY_FLAG: u32 = SHELL_CONFIG_NOTIFY_FLAG;
366}
367
368impl AsRef<ShellStandaloneClockSource> for ItwinConfig {
369 fn as_ref(&self) -> &ShellStandaloneClockSource {
370 &self.standalone_src
371 }
372}
373
374impl AsMut<ShellStandaloneClockSource> for ItwinConfig {
375 fn as_mut(&mut self) -> &mut ShellStandaloneClockSource {
376 &mut self.standalone_src
377 }
378}
379
380impl AsRef<TcKonnektStandaloneClockRate> for ItwinConfig {
381 fn as_ref(&self) -> &TcKonnektStandaloneClockRate {
382 &self.standalone_rate
383 }
384}
385
386impl AsMut<TcKonnektStandaloneClockRate> for ItwinConfig {
387 fn as_mut(&mut self) -> &mut TcKonnektStandaloneClockRate {
388 &mut self.standalone_rate
389 }
390}
391
392impl AsRef<ShellMixerStreamSourcePair> for ItwinConfig {
393 fn as_ref(&self) -> &ShellMixerStreamSourcePair {
394 &self.mixer_stream_src_pair
395 }
396}
397
398impl AsMut<ShellMixerStreamSourcePair> for ItwinConfig {
399 fn as_mut(&mut self) -> &mut ShellMixerStreamSourcePair {
400 &mut self.mixer_stream_src_pair
401 }
402}
403
404#[derive(Debug, Clone, PartialEq, Eq)]
406pub struct ItwinMixerState {
407 pub mixer: ShellMixerState,
409 pub stream_mix_balance: u32,
411 pub enabled: bool,
413}
414
415impl Default for ItwinMixerState {
416 fn default() -> Self {
417 ItwinMixerState {
418 mixer: ItwinProtocol::create_mixer_state(),
419 enabled: Default::default(),
420 stream_mix_balance: Default::default(),
421 }
422 }
423}
424
425impl ShellMixerStateSpecification for ItwinProtocol {
426 const MONITOR_SRC_MAP: [Option<ShellMixerMonitorSrcType>; SHELL_MIXER_MONITOR_SRC_COUNT] = [
427 Some(ShellMixerMonitorSrcType::Stream),
428 None,
429 None,
430 Some(ShellMixerMonitorSrcType::Spdif),
431 Some(ShellMixerMonitorSrcType::Analog),
432 Some(ShellMixerMonitorSrcType::Analog),
433 Some(ShellMixerMonitorSrcType::AdatSpdif),
434 Some(ShellMixerMonitorSrcType::Adat),
435 Some(ShellMixerMonitorSrcType::Adat),
436 Some(ShellMixerMonitorSrcType::Adat),
437 ];
438}
439
440impl TcKonnektSegmentSerdes<ItwinMixerState> for ItwinProtocol {
441 const NAME: &'static str = "mixer-state";
442 const OFFSET: usize = 0x00d0;
443 const SIZE: usize = ShellMixerState::SIZE + 56;
444
445 fn serialize(params: &ItwinMixerState, raw: &mut [u8]) -> Result<(), String> {
446 serialize_mixer_state::<ItwinProtocol>(¶ms.mixer, raw)?;
447
448 serialize_u32(¶ms.stream_mix_balance, &mut raw[348..352]);
449 serialize_bool(¶ms.enabled, &mut raw[352..356]);
450 Ok(())
451 }
452
453 fn deserialize(params: &mut ItwinMixerState, raw: &[u8]) -> Result<(), String> {
454 deserialize_mixer_state::<ItwinProtocol>(&mut params.mixer, raw)?;
455
456 deserialize_u32(&mut params.stream_mix_balance, &raw[348..352]);
457 deserialize_bool(&mut params.enabled, &raw[352..356]);
458 Ok(())
459 }
460}
461
462impl TcKonnektMutableSegmentOperation<ItwinMixerState> for ItwinProtocol {}
463
464impl TcKonnektNotifiedSegmentOperation<ItwinMixerState> for ItwinProtocol {
465 const NOTIFY_FLAG: u32 = SHELL_MIXER_NOTIFY_FLAG;
466}
467
468impl AsRef<ShellMixerState> for ItwinMixerState {
469 fn as_ref(&self) -> &ShellMixerState {
470 &self.mixer
471 }
472}
473
474impl AsMut<ShellMixerState> for ItwinMixerState {
475 fn as_mut(&mut self) -> &mut ShellMixerState {
476 &mut self.mixer
477 }
478}
479
480#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
482pub struct ItwinReverbState(pub ReverbState);
483
484impl TcKonnektSegmentSerdes<ItwinReverbState> for ItwinProtocol {
485 const NAME: &'static str = "reverb-state";
486 const OFFSET: usize = 0x0244;
487 const SIZE: usize = ReverbState::SIZE;
488
489 fn serialize(params: &ItwinReverbState, raw: &mut [u8]) -> Result<(), String> {
490 serialize_reverb_state(¶ms.0, raw)
491 }
492
493 fn deserialize(params: &mut ItwinReverbState, raw: &[u8]) -> Result<(), String> {
494 deserialize_reverb_state(&mut params.0, raw)
495 }
496}
497
498impl TcKonnektMutableSegmentOperation<ItwinReverbState> for ItwinProtocol {}
499
500impl TcKonnektNotifiedSegmentOperation<ItwinReverbState> for ItwinProtocol {
501 const NOTIFY_FLAG: u32 = SHELL_REVERB_NOTIFY_FLAG;
502}
503
504impl AsRef<ReverbState> for ItwinReverbState {
505 fn as_ref(&self) -> &ReverbState {
506 &self.0
507 }
508}
509
510impl AsMut<ReverbState> for ItwinReverbState {
511 fn as_mut(&mut self) -> &mut ReverbState {
512 &mut self.0
513 }
514}
515
516#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
518pub struct ItwinChStripStates(pub [ChStripState; SHELL_CH_STRIP_COUNT]);
519
520impl TcKonnektSegmentSerdes<ItwinChStripStates> for ItwinProtocol {
521 const NAME: &'static str = "channel-strip-state";
522 const OFFSET: usize = 0x028c;
523 const SIZE: usize = ChStripState::SIZE * SHELL_CH_STRIP_COUNT + 4;
524
525 fn serialize(params: &ItwinChStripStates, raw: &mut [u8]) -> Result<(), String> {
526 serialize_ch_strip_states(¶ms.0, raw)
527 }
528
529 fn deserialize(params: &mut ItwinChStripStates, raw: &[u8]) -> Result<(), String> {
530 deserialize_ch_strip_states(&mut params.0, raw)
531 }
532}
533
534impl TcKonnektMutableSegmentOperation<ItwinChStripStates> for ItwinProtocol {}
535
536impl TcKonnektNotifiedSegmentOperation<ItwinChStripStates> for ItwinProtocol {
537 const NOTIFY_FLAG: u32 = SHELL_CH_STRIP_NOTIFY_FLAG;
538}
539
540impl AsRef<[ChStripState]> for ItwinChStripStates {
541 fn as_ref(&self) -> &[ChStripState] {
542 &self.0
543 }
544}
545
546impl AsMut<[ChStripState]> for ItwinChStripStates {
547 fn as_mut(&mut self) -> &mut [ChStripState] {
548 &mut self.0
549 }
550}
551
552#[derive(Debug, Copy, Clone, PartialEq, Eq)]
554pub enum ListeningMode {
555 Monaural,
557 Stereo,
559 Side,
561}
562
563impl Default for ListeningMode {
564 fn default() -> Self {
565 Self::Monaural
566 }
567}
568
569const LISTENING_MODES: &[ListeningMode] = &[
570 ListeningMode::Monaural,
571 ListeningMode::Stereo,
572 ListeningMode::Side,
573];
574
575const LISTENING_MODE_LABEL: &str = "listening mode";
576
577fn serialize_listening_mode(mode: &ListeningMode, raw: &mut [u8]) -> Result<(), String> {
578 serialize_position(LISTENING_MODES, mode, raw, LISTENING_MODE_LABEL)
579}
580
581fn deserialize_listening_mode(mode: &mut ListeningMode, raw: &[u8]) -> Result<(), String> {
582 deserialize_position(LISTENING_MODES, mode, raw, LISTENING_MODE_LABEL)
583}
584
585#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
587pub struct ItwinHwState {
588 pub hw_state: ShellHwState,
590 pub listening_mode: ListeningMode,
592}
593
594impl TcKonnektSegmentSerdes<ItwinHwState> for ItwinProtocol {
595 const NAME: &'static str = "hardware-state";
596 const OFFSET: usize = 0x1008;
597 const SIZE: usize = ShellHwState::SIZE;
598
599 fn serialize(params: &ItwinHwState, raw: &mut [u8]) -> Result<(), String> {
600 serialize_hw_state(¶ms.hw_state, raw)?;
601 serialize_listening_mode(¶ms.listening_mode, &mut raw[8..12])?;
602 Ok(())
603 }
604
605 fn deserialize(params: &mut ItwinHwState, raw: &[u8]) -> Result<(), String> {
606 deserialize_hw_state(&mut params.hw_state, raw)?;
607 deserialize_listening_mode(&mut params.listening_mode, &raw[8..12])?;
608 Ok(())
609 }
610}
611
612impl TcKonnektMutableSegmentOperation<ItwinHwState> for ItwinProtocol {}
613
614impl TcKonnektNotifiedSegmentOperation<ItwinHwState> for ItwinProtocol {
615 const NOTIFY_FLAG: u32 = SHELL_HW_STATE_NOTIFY_FLAG;
616}
617
618impl AsRef<ShellHwState> for ItwinHwState {
619 fn as_ref(&self) -> &ShellHwState {
620 &self.hw_state
621 }
622}
623
624impl AsMut<ShellHwState> for ItwinHwState {
625 fn as_mut(&mut self) -> &mut ShellHwState {
626 &mut self.hw_state
627 }
628}
629
630impl AsRef<FireWireLedState> for ItwinHwState {
631 fn as_ref(&self) -> &FireWireLedState {
632 &self.hw_state.firewire_led
633 }
634}
635
636impl AsMut<FireWireLedState> for ItwinHwState {
637 fn as_mut(&mut self) -> &mut FireWireLedState {
638 &mut self.hw_state.firewire_led
639 }
640}
641
642#[derive(Debug, Clone, PartialEq, Eq)]
644pub struct ItwinMixerMeter(pub ShellMixerMeter);
645
646impl Default for ItwinMixerMeter {
647 fn default() -> Self {
648 ItwinMixerMeter(ItwinProtocol::create_meter_state())
649 }
650}
651
652impl ShellMixerMeterSpecification for ItwinProtocol {
653 const ANALOG_INPUT_COUNT: usize = 4;
654 const DIGITAL_INPUT_COUNT: usize = 8;
655}
656
657impl TcKonnektSegmentSerdes<ItwinMixerMeter> for ItwinProtocol {
658 const NAME: &'static str = "mixer-meter";
659 const OFFSET: usize = 0x106c;
660 const SIZE: usize = ShellMixerMeter::SIZE;
661
662 fn serialize(params: &ItwinMixerMeter, raw: &mut [u8]) -> Result<(), String> {
663 serialize_mixer_meter::<ItwinProtocol>(¶ms.0, raw)
664 }
665
666 fn deserialize(params: &mut ItwinMixerMeter, raw: &[u8]) -> Result<(), String> {
667 deserialize_mixer_meter::<ItwinProtocol>(&mut params.0, raw)
668 }
669}
670
671impl AsRef<ShellMixerMeter> for ItwinMixerMeter {
672 fn as_ref(&self) -> &ShellMixerMeter {
673 &self.0
674 }
675}
676
677impl AsMut<ShellMixerMeter> for ItwinMixerMeter {
678 fn as_mut(&mut self) -> &mut ShellMixerMeter {
679 &mut self.0
680 }
681}
682
683#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
685pub struct ItwinReverbMeter(pub ReverbMeter);
686
687impl TcKonnektSegmentSerdes<ItwinReverbMeter> for ItwinProtocol {
688 const NAME: &'static str = "reverb-meter";
689 const OFFSET: usize = 0x10c8;
690 const SIZE: usize = ReverbMeter::SIZE;
691
692 fn serialize(params: &ItwinReverbMeter, raw: &mut [u8]) -> Result<(), String> {
693 serialize_reverb_meter(¶ms.0, raw)
694 }
695
696 fn deserialize(params: &mut ItwinReverbMeter, raw: &[u8]) -> Result<(), String> {
697 deserialize_reverb_meter(&mut params.0, raw)
698 }
699}
700
701impl AsRef<ReverbMeter> for ItwinReverbMeter {
702 fn as_ref(&self) -> &ReverbMeter {
703 &self.0
704 }
705}
706
707impl AsMut<ReverbMeter> for ItwinReverbMeter {
708 fn as_mut(&mut self) -> &mut ReverbMeter {
709 &mut self.0
710 }
711}
712
713#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
715pub struct ItwinChStripMeters(pub [ChStripMeter; SHELL_CH_STRIP_COUNT]);
716
717impl TcKonnektSegmentSerdes<ItwinChStripMeters> for ItwinProtocol {
718 const NAME: &'static str = "channel-strip-meter";
719 const OFFSET: usize = 0x10e0;
720 const SIZE: usize = ChStripMeter::SIZE * SHELL_CH_STRIP_COUNT + 4;
721
722 fn serialize(params: &ItwinChStripMeters, raw: &mut [u8]) -> Result<(), String> {
723 serialize_ch_strip_meters(¶ms.0, raw)
724 }
725
726 fn deserialize(params: &mut ItwinChStripMeters, raw: &[u8]) -> Result<(), String> {
727 deserialize_ch_strip_meters(&mut params.0, raw)
728 }
729}
730
731impl AsRef<[ChStripMeter]> for ItwinChStripMeters {
732 fn as_ref(&self) -> &[ChStripMeter] {
733 &self.0
734 }
735}
736
737impl AsMut<[ChStripMeter]> for ItwinChStripMeters {
738 fn as_mut(&mut self) -> &mut [ChStripMeter] {
739 &mut self.0
740 }
741}