1use super::*;
115
116#[derive(Default, Debug)]
120pub struct SaffirePro26ioClkProtocol;
121
122impl SaffireProioMediaClockSpecification for SaffirePro26ioClkProtocol {
123 const FREQ_LIST: &'static [u32] = &[44100, 48000, 88200, 96000, 176400, 192000];
124}
125
126impl SaffireProioSamplingClockSpecification for SaffirePro26ioClkProtocol {
127 const SRC_LIST: &'static [SaffireProioSamplingClockSource] = &[
128 SaffireProioSamplingClockSource::Internal,
129 SaffireProioSamplingClockSource::Spdif,
130 SaffireProioSamplingClockSource::Adat0,
131 SaffireProioSamplingClockSource::Adat1,
132 SaffireProioSamplingClockSource::WordClock,
133 ];
134}
135
136#[derive(Default, Debug)]
138pub struct SaffirePro26ioMeterProtocol;
139
140impl SaffireProioMeterOperation for SaffirePro26ioMeterProtocol {
141 const SRC_LIST: &'static [SaffireProioSamplingClockSource] = &[
142 SaffireProioSamplingClockSource::Internal,
143 SaffireProioSamplingClockSource::Spdif,
144 SaffireProioSamplingClockSource::Adat0,
145 SaffireProioSamplingClockSource::Adat1,
146 SaffireProioSamplingClockSource::WordClock,
147 ];
148}
149
150#[derive(Default, Debug)]
152pub struct SaffirePro26ioMonitorProtocol;
153
154impl SaffireProioMonitorSpecification for SaffirePro26ioMonitorProtocol {
155 const HAS_ADAT: bool = true;
156}
157
158#[derive(Default, Debug)]
160pub struct SaffirePro26ioSpecificProtocol;
161
162impl SaffireProioSpecificSpecification for SaffirePro26ioSpecificProtocol {
163 const PHANTOM_POWERING_COUNT: usize = 2;
164 const INSERT_SWAP_COUNT: usize = 2;
165}
166
167#[derive(Default, Debug)]
171pub struct SaffirePro10ioClkProtocol;
172
173impl SaffireProioMediaClockSpecification for SaffirePro10ioClkProtocol {
174 const FREQ_LIST: &'static [u32] = &[44100, 48000, 88200, 96000];
175}
176
177#[derive(Default, Debug)]
179pub struct SaffirePro10ioMonitorProtocol;
180
181impl SaffireProioMonitorSpecification for SaffirePro10ioMonitorProtocol {
182 const HAS_ADAT: bool = false;
183}
184
185#[derive(Default, Debug)]
187pub struct SaffirePro10ioSpecificProtocol;
188
189impl SaffireProioSpecificSpecification for SaffirePro10ioSpecificProtocol {
190 const PHANTOM_POWERING_COUNT: usize = 0;
191 const INSERT_SWAP_COUNT: usize = 0;
192}
193
194#[derive(Default, Debug)]
196pub struct SaffireProioOutputProtocol;
197
198impl SaffireOutputSpecification for SaffireProioOutputProtocol {
199 const OUTPUT_OFFSETS: &'static [usize] = &[0x140, 0x144, 0x148, 0x14c];
201
202 const MUTE_COUNT: usize = 4;
203 const VOL_COUNT: usize = 4;
204 const HWCTL_COUNT: usize = 4;
205 const DIM_COUNT: usize = 4;
206 const PAD_COUNT: usize = 4;
207}
208
209impl SaffireProioSamplingClockSpecification for SaffirePro10ioClkProtocol {
210 const SRC_LIST: &'static [SaffireProioSamplingClockSource] = &[
211 SaffireProioSamplingClockSource::Internal,
212 SaffireProioSamplingClockSource::Spdif,
213 ];
214}
215
216#[derive(Default, Debug)]
218pub struct SaffirePro10ioMeterProtocol;
219
220impl SaffireProioMeterOperation for SaffirePro10ioMeterProtocol {
221 const SRC_LIST: &'static [SaffireProioSamplingClockSource] = &[
222 SaffireProioSamplingClockSource::Internal,
223 SaffireProioSamplingClockSource::Spdif,
224 ];
225}
226
227#[derive(Default, Debug)]
229pub struct SaffireProioMixerProtocol;
230
231pub trait SaffireProioMediaClockSpecification {
233 const FREQ_LIST: &'static [u32];
235}
236
237impl<O: SaffireProioMediaClockSpecification> SaffireParametersSerdes<MediaClockParameters> for O {
238 const OFFSETS: &'static [usize] = &[0x0150];
239
240 fn serialize(params: &MediaClockParameters, raw: &mut [u8]) {
241 raw.copy_from_slice(&(params.freq_idx as u32).to_be_bytes());
242 }
243
244 fn deserialize(params: &mut MediaClockParameters, raw: &[u8]) {
245 let mut quadlet = [9u8; 4];
246 quadlet.copy_from_slice(&raw[..4]);
247 let idx = u32::from_be_bytes(quadlet) as usize;
248 if idx < Self::FREQ_LIST.len() {
249 params.freq_idx = idx;
250 }
251 }
252}
253
254#[derive(Debug, Copy, Clone, PartialEq, Eq)]
256pub enum SaffireProioSamplingClockSource {
257 Internal,
259 Spdif,
261 Adat0,
263 Adat1,
265 WordClock,
267}
268
269impl Default for SaffireProioSamplingClockSource {
270 fn default() -> Self {
271 Self::Internal
272 }
273}
274
275pub trait SaffireProioSamplingClockSpecification {
277 const SRC_LIST: &'static [SaffireProioSamplingClockSource];
279}
280
281impl<O: SaffireProioSamplingClockSpecification> SaffireParametersSerdes<SamplingClockParameters>
282 for O
283{
284 const OFFSETS: &'static [usize] = &[0x0174];
285
286 fn serialize(params: &SamplingClockParameters, raw: &mut [u8]) {
287 if let Some(val) = Self::SRC_LIST
288 .iter()
289 .nth(params.src_idx)
290 .and_then(|&src| match src {
291 SaffireProioSamplingClockSource::Internal => Some(CLK_SRC_INTERNAL),
292 SaffireProioSamplingClockSource::Spdif => Some(CLK_SRC_SPDIF),
293 SaffireProioSamplingClockSource::Adat0 => Some(CLK_SRC_ADAT0),
294 SaffireProioSamplingClockSource::Adat1 => Some(CLK_SRC_ADAT1),
295 SaffireProioSamplingClockSource::WordClock => Some(CLK_SRC_WORD_CLOCK),
296 })
297 {
298 raw.copy_from_slice(&val.to_be_bytes());
299 }
300 }
301
302 fn deserialize(params: &mut SamplingClockParameters, raw: &[u8]) {
303 let mut quadlet = [0u8; 4];
304 quadlet.copy_from_slice(&raw[..4]);
305 let val = u32::from_be_bytes(quadlet) & CLK_SRC_CONF_MASK;
306 if let Some(src_idx) = match val {
307 CLK_SRC_INTERNAL => Some(SaffireProioSamplingClockSource::Internal),
308 CLK_SRC_SPDIF => Some(SaffireProioSamplingClockSource::Spdif),
309 CLK_SRC_ADAT0 => Some(SaffireProioSamplingClockSource::Adat0),
310 CLK_SRC_ADAT1 => Some(SaffireProioSamplingClockSource::Adat1),
311 CLK_SRC_WORD_CLOCK => Some(SaffireProioSamplingClockSource::WordClock),
312 _ => None,
313 }
314 .and_then(|src| Self::SRC_LIST.iter().position(|s| s.eq(&src)))
315 {
316 params.src_idx = src_idx;
317 }
318 }
319}
320
321const CLK_SRC_EFFECTIVE_MASK: u32 = 0x0000ff00;
322const CLK_SRC_CONF_MASK: u32 = 0x000000ff;
323const CLK_SRC_INTERNAL: u32 = 0x00;
324const CLK_SRC_SPDIF: u32 = 0x02;
325const CLK_SRC_ADAT0: u32 = 0x03;
326const CLK_SRC_ADAT1: u32 = 0x04;
327const CLK_SRC_WORD_CLOCK: u32 = 0x05;
328
329#[derive(Default, Debug)]
331pub struct SaffireProioThroughProtocol;
332
333impl SaffireThroughSpecification for SaffireProioThroughProtocol {
334 const THROUGH_OFFSETS: &'static [usize] = &[0x019c, 0x01a0];
335}
336
337#[derive(Default, Debug)]
339pub struct SaffireProioMeterState {
340 pub monitor_knob: u8,
342 pub mute_led: bool,
344 pub dim_led: bool,
346 pub effective_clk_srcs: SaffireProioSamplingClockSource,
348}
349
350pub trait SaffireProioMeterOperation {
353 const SRC_LIST: &'static [SaffireProioSamplingClockSource];
355
356 const OFFSETS: &'static [usize] = &[
357 0x0158, 0x015c, 0x0160, 0x0174, ];
362
363 fn cache(
365 req: &FwReq,
366 node: &FwNode,
367 state: &mut SaffireProioMeterState,
368 timeout_ms: u32,
369 ) -> Result<(), Error> {
370 let mut buf = vec![0; Self::OFFSETS.len() * 4];
371 saffire_read_quadlets(req, node, &Self::OFFSETS, &mut buf, timeout_ms).and_then(|_| {
372 let mut quadlet = [0; 4];
373 let vals = (0..Self::OFFSETS.len()).fold(Vec::new(), |mut vals, i| {
374 let pos = i * 4;
375 quadlet.copy_from_slice(&buf[pos..(pos + 4)]);
376 vals.push(u32::from_be_bytes(quadlet));
377 vals
378 });
379
380 state.monitor_knob = (vals[0] & 0xff) as u8;
381 state.mute_led = vals[1] > 0;
382 state.dim_led = vals[2] > 0;
383
384 state.effective_clk_srcs = match (vals[3] & CLK_SRC_EFFECTIVE_MASK) >> 8 {
385 CLK_SRC_INTERNAL => Ok(SaffireProioSamplingClockSource::Internal),
386 CLK_SRC_SPDIF => Ok(SaffireProioSamplingClockSource::Spdif),
387 CLK_SRC_ADAT0 => Ok(SaffireProioSamplingClockSource::Adat0),
388 CLK_SRC_ADAT1 => Ok(SaffireProioSamplingClockSource::Adat1),
389 CLK_SRC_WORD_CLOCK => Ok(SaffireProioSamplingClockSource::WordClock),
390 _ => {
391 let msg = format!("Unexpected value for source of sampling clock: {}", vals[0]);
392 Err(Error::new(FileError::Io, &msg))
393 }
394 }?;
395
396 Ok(())
397 })
398 }
399}
400
401#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
403pub struct SaffireProioMonitorParameters {
404 pub analog_inputs: [[i16; 8]; 2],
406 pub spdif_inputs: [[i16; 2]; 2],
408 pub adat_inputs: Option<[[i16; 16]; 2]>,
410}
411
412pub trait SaffireProioMonitorSpecification {
414 const HAS_ADAT: bool;
416
417 const MONITOR_OFFSETS: &'static [usize] = &[
419 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c, 0x40, 0x44, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c, 0x60, 0x64, 0x68, 0x6c, 0x70, 0x74, 0x78, 0x7c, 0x80, 0x84, 0x88, 0x8c, 0x90, 0x94, 0x98, 0x9c, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, 0xc4, 0xc8, 0xcc, ];
475}
476
477impl<O: SaffireProioMonitorSpecification> SaffireParametersSerdes<SaffireProioMonitorParameters>
478 for O
479{
480 const OFFSETS: &'static [usize] = Self::MONITOR_OFFSETS;
481
482 fn serialize(params: &SaffireProioMonitorParameters, raw: &mut [u8]) {
483 params
484 .analog_inputs
485 .iter()
486 .enumerate()
487 .for_each(|(i, gains)| {
488 gains.iter().enumerate().for_each(|(j, &gain)| {
489 let pos = (i + j * 2) * 4;
490 let gain = gain as i32;
491 raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
492 });
493 });
494
495 params
496 .spdif_inputs
497 .iter()
498 .enumerate()
499 .for_each(|(i, gains)| {
500 gains.iter().enumerate().for_each(|(j, &gain)| {
501 let pos = (16 + i + j * 2) * 4;
502 let gain = gain as i32;
503 raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
504 });
505 });
506
507 if let Some(adat_inputs) = ¶ms.adat_inputs {
508 adat_inputs.iter().enumerate().for_each(|(i, gains)| {
509 gains.iter().enumerate().for_each(|(j, &gain)| {
510 let pos = (20 + i + j * 2) * 4;
511 let gain = gain as i32;
512 raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
513 });
514 });
515 }
516 }
517
518 fn deserialize(params: &mut SaffireProioMonitorParameters, raw: &[u8]) {
519 let mut quadlet = [0; 4];
520
521 let quads: Vec<i16> = (0..raw.len())
522 .step_by(4)
523 .map(|pos| {
524 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
525 i32::from_be_bytes(quadlet) as i16
526 })
527 .collect();
528
529 params
530 .analog_inputs
531 .iter_mut()
532 .enumerate()
533 .for_each(|(i, gains)| {
534 gains.iter_mut().enumerate().for_each(|(j, gain)| {
535 let pos = i + j * 2;
536 *gain = quads[pos];
537 });
538 });
539
540 params
541 .spdif_inputs
542 .iter_mut()
543 .enumerate()
544 .for_each(|(i, gains)| {
545 gains.iter_mut().enumerate().for_each(|(j, gain)| {
546 let pos = 16 + i + j * 2;
547 *gain = quads[pos];
548 });
549 });
550
551 if let Some(adat_inputs) = &mut params.adat_inputs {
552 adat_inputs.iter_mut().enumerate().for_each(|(i, gains)| {
553 gains.iter_mut().enumerate().for_each(|(j, gain)| {
554 let pos = 20 + i + j * 2;
555 *gain = quads[pos];
556 });
557 });
558 }
559 }
560}
561
562pub trait SaffireProioMonitorProtocol: SaffireProioMonitorSpecification {
564 const LEVEL_MIN: i16 = 0;
566 const LEVEL_MAX: i16 = 0x7fff;
568 const LEVEL_STEP: i16 = 0x100;
570
571 fn create_params() -> SaffireProioMonitorParameters {
572 SaffireProioMonitorParameters {
573 analog_inputs: Default::default(),
574 spdif_inputs: Default::default(),
575 adat_inputs: if Self::HAS_ADAT {
576 Some(Default::default())
577 } else {
578 None
579 },
580 }
581 }
582}
583
584impl<O: SaffireProioMonitorSpecification> SaffireProioMonitorProtocol for O {}
585
586#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
588pub struct SaffireProioMixerParameters {
589 pub monitor_sources: [i16; 10],
591 pub stream_source_pair0: [i16; 10],
593 pub stream_sources: [i16; 10],
595}
596
597impl SaffireParametersSerdes<SaffireProioMixerParameters> for SaffireProioMixerProtocol {
598 const OFFSETS: &'static [usize] = &[
599 0x0d0, 0x0d4, 0x0d8, 0x0dc, 0x0e0, 0x0e4, 0x0e8, 0x0ec, 0x0f0, 0x0f4, 0x0f8, 0x0fc, 0x100, 0x104, 0x108, 0x10c, 0x110, 0x114, 0x118, 0x11c, 0x120, 0x124, 0x128, 0x12c, 0x130, 0x134, 0x138, 0x13c, ];
638
639 fn serialize(params: &SaffireProioMixerParameters, raw: &mut [u8]) {
640 params
641 .monitor_sources
642 .iter()
643 .enumerate()
644 .for_each(|(i, &level)| {
645 let pos = calc_monitor_source_pos(i) * 4;
646 let level = level as i32;
647 raw[pos..(pos + 4)].copy_from_slice(&level.to_be_bytes());
648 });
649
650 params
651 .stream_source_pair0
652 .iter()
653 .enumerate()
654 .for_each(|(i, &level)| {
655 let pos = calc_stream_source_pair0_pos(i) * 4;
656 let level = level as i32;
657 raw[pos..(pos + 4)].copy_from_slice(&level.to_be_bytes());
658 });
659
660 params
661 .stream_sources
662 .iter()
663 .enumerate()
664 .for_each(|(i, &level)| {
665 let pos = calc_stream_source_pos(i) * 4;
666 let level = level as i32;
667 raw[pos..(pos + 4)].copy_from_slice(&level.to_be_bytes());
668 });
669 }
670
671 fn deserialize(params: &mut SaffireProioMixerParameters, raw: &[u8]) {
672 let mut quadlet = [0; 4];
673
674 let quads: Vec<i16> = (0..raw.len())
675 .step_by(4)
676 .map(|pos| {
677 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
678 i32::from_be_bytes(quadlet) as i16
679 })
680 .collect();
681
682 params
683 .monitor_sources
684 .iter_mut()
685 .enumerate()
686 .for_each(|(i, level)| {
687 let pos = calc_monitor_source_pos(i);
688 *level = quads[pos];
689 });
690
691 params
692 .stream_source_pair0
693 .iter_mut()
694 .enumerate()
695 .for_each(|(i, level)| {
696 let pos = calc_stream_source_pair0_pos(i);
697 *level = quads[pos];
698 });
699
700 params
701 .stream_sources
702 .iter_mut()
703 .enumerate()
704 .for_each(|(i, level)| {
705 let pos = calc_stream_source_pos(i);
706 *level = quads[pos];
707 });
708 }
709}
710
711impl SaffireProioMixerProtocol {
712 pub const LEVEL_MIN: i16 = 0;
714 pub const LEVEL_MAX: i16 = 0x7fff;
716 pub const LEVEL_STEP: i16 = 0x100;
718}
719
720fn calc_monitor_source_pos(i: usize) -> usize {
721 if i < 2 {
722 1 + i * 2
723 } else {
724 6 + (i - 2) * 3
725 }
726}
727
728fn calc_stream_source_pair0_pos(i: usize) -> usize {
729 if i < 2 {
730 i * 2
731 } else {
732 4 + (i - 2) * 3
733 }
734}
735
736fn calc_stream_source_pos(i: usize) -> usize {
737 if i < 2 {
738 i * 2
739 } else {
740 5 + (i - 2) * 3
741 }
742}
743
744#[derive(Debug, Copy, Clone, Eq, PartialEq)]
746pub enum SaffireProioStandaloneMode {
747 Mix,
749 Track,
751}
752
753impl Default for SaffireProioStandaloneMode {
754 fn default() -> Self {
755 Self::Mix
756 }
757}
758
759#[derive(Debug, Clone, PartialEq, Eq)]
761pub struct SaffireProioSpecificParameters {
762 pub head_room: bool,
764 pub phantom_powerings: Vec<bool>,
766 pub insert_swaps: Vec<bool>,
768 pub standalone_mode: SaffireProioStandaloneMode,
770 pub adat_enabled: bool,
772 pub direct_monitoring: bool,
774}
775
776pub trait SaffireProioSpecificSpecification {
778 const SPECIFIC_OFFSETS: &'static [usize] = &[
780 0x016c, 0x0188, 0x018c, 0x0190, 0x0194, 0x01bc, 0x01c0, 0x01c8, ];
789
790 const PHANTOM_POWERING_COUNT: usize;
792
793 const INSERT_SWAP_COUNT: usize;
795}
796
797impl<O: SaffireProioSpecificSpecification> SaffireParametersSerdes<SaffireProioSpecificParameters>
799 for O
800{
801 const OFFSETS: &'static [usize] = Self::SPECIFIC_OFFSETS;
802
803 fn serialize(params: &SaffireProioSpecificParameters, raw: &mut [u8]) {
804 raw[..4].copy_from_slice(&(params.head_room as u32).to_be_bytes());
805
806 params
807 .phantom_powerings
808 .iter()
809 .rev()
810 .enumerate()
811 .for_each(|(i, &enabled)| {
812 let pos = 4 + i * 4;
813 raw[pos..(pos + 4)].copy_from_slice(&(enabled as u32).to_be_bytes());
814 });
815
816 params
817 .insert_swaps
818 .iter()
819 .enumerate()
820 .for_each(|(i, &enabled)| {
821 let pos = 12 + i * 4;
822 raw[pos..(pos + 4)].copy_from_slice(&(enabled as u32).to_be_bytes());
823 });
824
825 let val = (params.standalone_mode == SaffireProioStandaloneMode::Track) as u32;
826 raw[20..24].copy_from_slice(&val.to_be_bytes());
827
828 raw[24..28].copy_from_slice(&(!params.adat_enabled as u32).to_be_bytes());
829 raw[28..32].copy_from_slice(&(params.direct_monitoring as u32).to_be_bytes());
830 }
831
832 fn deserialize(params: &mut SaffireProioSpecificParameters, raw: &[u8]) {
833 let mut quadlet = [0; 4];
834
835 let quads: Vec<i16> = (0..raw.len())
836 .step_by(4)
837 .map(|pos| {
838 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
839 i32::from_be_bytes(quadlet) as i16
840 })
841 .collect();
842
843 params.head_room = quads[0] > 0;
844
845 params
846 .phantom_powerings
847 .iter_mut()
848 .rev()
849 .enumerate()
850 .for_each(|(i, enabled)| *enabled = quads[1 + i] > 0);
851
852 params
853 .insert_swaps
854 .iter_mut()
855 .enumerate()
856 .for_each(|(i, enabled)| *enabled = quads[3 + i] > 0);
857
858 params.standalone_mode = if quads[5] > 0 {
859 SaffireProioStandaloneMode::Track
860 } else {
861 SaffireProioStandaloneMode::Mix
862 };
863
864 params.adat_enabled = quads[6] == 0;
865 params.direct_monitoring = quads[7] > 0;
866 }
867}
868
869pub trait SaffireProioSpecificOperation: SaffireProioSpecificSpecification {
872 fn create_params() -> SaffireProioSpecificParameters {
873 SaffireProioSpecificParameters {
874 head_room: Default::default(),
875 phantom_powerings: vec![Default::default(); Self::PHANTOM_POWERING_COUNT],
876 insert_swaps: vec![Default::default(); Self::INSERT_SWAP_COUNT],
877 standalone_mode: Default::default(),
878 adat_enabled: Default::default(),
879 direct_monitoring: Default::default(),
880 }
881 }
882}
883
884impl<O: SaffireProioSpecificSpecification> SaffireProioSpecificOperation for O {}
885
886#[derive(Default, Debug)]
888pub struct SaffireProioStoreConfigProtocol;
889
890impl SaffireStoreConfigSpecification for SaffireProioStoreConfigProtocol {
891 const STORE_CONFIG_OFFSETS: &'static [usize] = &[0x1b0];
892}
893
894#[cfg(test)]
895mod test {
896 use super::*;
897
898 #[test]
899 fn saffireproio_output_protocol_serdes() {
900 let mut params = SaffireProioOutputProtocol::create_output_parameters();
901
902 params
903 .mutes
904 .iter_mut()
905 .step_by(2)
906 .for_each(|mute| *mute = true);
907
908 params
909 .vols
910 .iter_mut()
911 .enumerate()
912 .for_each(|(i, vol)| *vol = i as u8);
913
914 params
915 .hwctls
916 .iter_mut()
917 .step_by(2)
918 .for_each(|hwctl| *hwctl = true);
919
920 params
921 .dims
922 .iter_mut()
923 .step_by(2)
924 .for_each(|dim| *dim = true);
925
926 params
927 .pads
928 .iter_mut()
929 .step_by(2)
930 .for_each(|pad| *pad = true);
931
932 let mut raw = vec![0u8; SaffireProioOutputProtocol::OFFSETS.len() * 4];
933 SaffireProioOutputProtocol::serialize(¶ms, &mut raw);
934 let mut p = SaffireProioOutputProtocol::create_output_parameters();
935 SaffireProioOutputProtocol::deserialize(&mut p, &raw);
936
937 assert_eq!(params, p);
938 }
939
940 #[test]
941 fn saffirepro10io_monitor_protocol_serdes() {
942 let params = SaffireProioMonitorParameters {
943 analog_inputs: [
944 [45, 89, -17, -90, -28, 95, 32, -51],
945 [-2, -43, -34, 69, 27, 14, 37, 10],
946 ],
947 spdif_inputs: [[84, 46], [42, -20]],
948 adat_inputs: None,
949 };
950 let mut raw = vec![0u8; SaffirePro10ioMonitorProtocol::OFFSETS.len() * 4];
951 SaffirePro10ioMonitorProtocol::serialize(¶ms, &mut raw);
952 let mut p = SaffirePro10ioMonitorProtocol::create_params();
953 SaffirePro10ioMonitorProtocol::deserialize(&mut p, &raw);
954
955 assert_eq!(params, p);
956 }
957
958 #[test]
959 fn saffirepro26io_monitor_protocol_serdes() {
960 let params = SaffireProioMonitorParameters {
961 analog_inputs: [
962 [45, 89, -17, -90, -28, 95, 32, -51],
963 [-2, -43, -34, 69, 27, 14, 37, 10],
964 ],
965 spdif_inputs: [[84, 46], [42, -20]],
966 adat_inputs: Some([
967 [
968 38, 9, 20, 4, -9, 82, -41, -14, 88, -18, 58, 1, -98, -26, 54, 21,
969 ],
970 [
971 58, 66, 42, -36, -50, 36, 50, -77, -99, -49, 52, -78, -51, -80, -40, 94,
972 ],
973 ]),
974 };
975 let mut raw = vec![0u8; SaffirePro26ioMonitorProtocol::OFFSETS.len() * 4];
976 SaffirePro26ioMonitorProtocol::serialize(¶ms, &mut raw);
977 let mut p = SaffirePro26ioMonitorProtocol::create_params();
978 SaffirePro26ioMonitorProtocol::deserialize(&mut p, &raw);
979
980 assert_eq!(params, p);
981 }
982
983 #[test]
984 fn saffirepro10io_specific_protocol_serdes() {
985 let mut params = SaffirePro10ioSpecificProtocol::create_params();
986 params.standalone_mode = SaffireProioStandaloneMode::Track;
987 params.adat_enabled = true;
988 params.direct_monitoring = true;
989 let mut raw = vec![0u8; SaffirePro10ioSpecificProtocol::OFFSETS.len() * 4];
990 SaffirePro10ioSpecificProtocol::serialize(¶ms, &mut raw);
991 let mut p = SaffirePro10ioSpecificProtocol::create_params();
992 SaffirePro10ioSpecificProtocol::deserialize(&mut p, &raw);
993
994 assert_eq!(params, p);
995 }
996
997 #[test]
998 fn saffirepro26io_specific_protocol_serdes() {
999 let mut params = SaffirePro26ioSpecificProtocol::create_params();
1000 params.phantom_powerings[0] = true;
1001 params.phantom_powerings[1] = false;
1002 params.insert_swaps[0] = false;
1003 params.insert_swaps[1] = true;
1004 params.standalone_mode = SaffireProioStandaloneMode::Track;
1005 params.adat_enabled = true;
1006 params.direct_monitoring = true;
1007 let mut raw = vec![0u8; SaffirePro26ioSpecificProtocol::OFFSETS.len() * 4];
1008 SaffirePro26ioSpecificProtocol::serialize(¶ms, &mut raw);
1009 let mut p = SaffirePro26ioSpecificProtocol::create_params();
1010 SaffirePro26ioSpecificProtocol::deserialize(&mut p, &raw);
1011
1012 assert_eq!(params, p);
1013 }
1014
1015 #[test]
1016 #[should_panic(expected = "expected to fail")]
1017 fn saffireproio_mixer_protocol_serdes() {
1018 let params = SaffireProioMixerParameters {
1019 monitor_sources: [-6, 25, 32, 76, 91, 57, -21, 88, 9, -87],
1020 stream_source_pair0: [84, -65, 59, 2, -21, 96, 40, 67, 72, 30],
1021 stream_sources: [-78, -75, -58, 86, 16, 59, 41, 88, 57, 24],
1022 };
1023 let mut raw = vec![0u8; SaffireProioMixerProtocol::OFFSETS.len() * 4];
1024 SaffireProioMixerProtocol::serialize(¶ms, &mut raw);
1025 let mut p = SaffireProioMixerParameters::default();
1026 SaffireProioMixerProtocol::deserialize(&mut p, &raw);
1027
1028 assert_eq!(params, p, "expected to fail");
1029 }
1030
1031 #[test]
1032 fn saffireproio_through_protocol_serdes() {
1033 let params = SaffireThroughParameters {
1034 midi: true,
1035 ac3: true,
1036 };
1037 let mut raw = vec![0u8; SaffireProioThroughProtocol::OFFSETS.len() * 4];
1038 SaffireProioThroughProtocol::serialize(¶ms, &mut raw);
1039 let mut p = SaffireThroughParameters::default();
1040 SaffireProioThroughProtocol::deserialize(&mut p, &raw);
1041
1042 assert_eq!(params, p);
1043 }
1044
1045 #[test]
1046 fn saffirepro10io_media_clock_serdes() {
1047 let mut raw = [0u8; 4];
1048 (0..SaffirePro10ioClkProtocol::FREQ_LIST.len()).for_each(|freq_idx| {
1049 let params = MediaClockParameters { freq_idx };
1050 SaffirePro10ioClkProtocol::serialize(¶ms, &mut raw);
1051 let mut p = MediaClockParameters::default();
1052 SaffirePro10ioClkProtocol::deserialize(&mut p, &raw);
1053 assert_eq!(params, p);
1054 });
1055 }
1056
1057 #[test]
1058 fn saffirepro26io_media_clock_serdes() {
1059 let mut raw = [0u8; 4];
1060 (0..SaffirePro26ioClkProtocol::FREQ_LIST.len()).for_each(|freq_idx| {
1061 let params = MediaClockParameters { freq_idx };
1062 SaffirePro26ioClkProtocol::serialize(¶ms, &mut raw);
1063 let mut p = MediaClockParameters::default();
1064 SaffirePro26ioClkProtocol::deserialize(&mut p, &raw);
1065 assert_eq!(params, p);
1066 });
1067 }
1068
1069 #[test]
1070 fn saffirepro10io_sampling_clock_serdes() {
1071 let mut raw = [0u8; 4];
1072 (0..SaffirePro10ioClkProtocol::SRC_LIST.len()).for_each(|src_idx| {
1073 let params = SamplingClockParameters { src_idx };
1074 SaffirePro10ioClkProtocol::serialize(¶ms, &mut raw);
1075 let mut p = SamplingClockParameters::default();
1076 SaffirePro10ioClkProtocol::deserialize(&mut p, &raw);
1077 assert_eq!(params, p);
1078 });
1079 }
1080
1081 #[test]
1082 fn saffirepro26io_sampling_clock_serdes() {
1083 let mut raw = [0u8; 4];
1084 (0..SaffirePro26ioClkProtocol::SRC_LIST.len()).for_each(|src_idx| {
1085 let params = SamplingClockParameters { src_idx };
1086 SaffirePro26ioClkProtocol::serialize(¶ms, &mut raw);
1087 let mut p = SamplingClockParameters::default();
1088 SaffirePro26ioClkProtocol::deserialize(&mut p, &raw);
1089 assert_eq!(params, p);
1090 });
1091 }
1092
1093 #[test]
1094 fn test_mixer_offset_helpers() {
1095 assert_eq!(calc_monitor_source_pos(0), 1);
1096 assert_eq!(calc_monitor_source_pos(1), 3);
1097 assert_eq!(calc_monitor_source_pos(2), 6);
1098 assert_eq!(calc_monitor_source_pos(3), 9);
1099 assert_eq!(calc_monitor_source_pos(4), 12);
1100 assert_eq!(calc_monitor_source_pos(5), 15);
1101 assert_eq!(calc_monitor_source_pos(6), 18);
1102 assert_eq!(calc_monitor_source_pos(7), 21);
1103 assert_eq!(calc_monitor_source_pos(8), 24);
1104 assert_eq!(calc_monitor_source_pos(9), 27);
1105
1106 assert_eq!(calc_stream_source_pair0_pos(0), 0);
1107 assert_eq!(calc_stream_source_pair0_pos(1), 2);
1108 assert_eq!(calc_stream_source_pair0_pos(2), 4);
1109 assert_eq!(calc_stream_source_pair0_pos(3), 7);
1110 assert_eq!(calc_stream_source_pair0_pos(4), 10);
1111 assert_eq!(calc_stream_source_pair0_pos(5), 13);
1112 assert_eq!(calc_stream_source_pair0_pos(6), 16);
1113 assert_eq!(calc_stream_source_pair0_pos(7), 19);
1114 assert_eq!(calc_stream_source_pair0_pos(8), 22);
1115 assert_eq!(calc_stream_source_pair0_pos(9), 25);
1116
1117 assert_eq!(calc_stream_source_pos(0), 0);
1118 assert_eq!(calc_stream_source_pos(1), 2);
1119 assert_eq!(calc_stream_source_pos(2), 5);
1120 assert_eq!(calc_stream_source_pos(3), 8);
1121 assert_eq!(calc_stream_source_pos(4), 11);
1122 assert_eq!(calc_stream_source_pos(5), 14);
1123 assert_eq!(calc_stream_source_pos(6), 17);
1124 assert_eq!(calc_stream_source_pos(7), 20);
1125 assert_eq!(calc_stream_source_pos(8), 23);
1126 assert_eq!(calc_stream_source_pos(9), 26);
1127 }
1128}