1use super::*;
118
119#[derive(Default, Debug)]
122pub struct SaffireClkProtocol;
123
124const SAFFIRE_MODE_192KHZ_OFFSET: usize = 0x138;
125
126impl MediaClockFrequencyOperation for SaffireClkProtocol {
127 const FREQ_LIST: &'static [u32] = &[44100, 48000, 88200, 96000, 192000];
128
129 fn update_freq(
130 avc: &BebobAvc,
131 params: &MediaClockParameters,
132 old: &mut MediaClockParameters,
133 timeout_ms: u32,
134 ) -> Result<(), Error> {
135 let mut op = SaffireAvcOperation {
137 offsets: vec![SAFFIRE_MODE_192KHZ_OFFSET],
138 buf: vec![0; 4],
139 ..Default::default()
140 };
141 avc.status(&AvcAddr::Unit, &mut op, timeout_ms)?;
142
143 let mut quadlet = [0; 4];
144 quadlet.copy_from_slice(&mut op.buf);
145 let val = u32::from_be_bytes(quadlet);
146 if (val > 0 && params.freq_idx < 4) || (val == 0 && params.freq_idx == 4) {
147 let msg = format!(
148 "Invalid frequency of media clock: {}",
149 Self::FREQ_LIST[params.freq_idx]
150 );
151 Err(Error::new(FileError::Inval, &msg))?;
152 }
153
154 let fdf = Self::FREQ_LIST
155 .iter()
156 .nth(params.freq_idx)
157 .ok_or_else(|| {
158 let msg = format!(
159 "Invalid argument for index of frequency: {}",
160 params.freq_idx
161 );
162 Error::new(FileError::Inval, &msg)
163 })
164 .map(|&freq| AmdtpFdf::new(AmdtpEventType::Am824, false, freq))?;
165
166 let mut op = InputPlugSignalFormat(PlugSignalFormat {
167 plug_id: 0,
168 fmt: FMT_IS_AMDTP,
169 fdf: fdf.into(),
170 });
171 avc.control(&AvcAddr::Unit, &mut op, timeout_ms)?;
172
173 let mut op = OutputPlugSignalFormat(PlugSignalFormat {
174 plug_id: 0,
175 fmt: FMT_IS_AMDTP,
176 fdf: fdf.into(),
177 });
178 avc.control(&AvcAddr::Unit, &mut op, timeout_ms)?;
179
180 *old = *params;
181
182 Ok(())
183 }
184}
185
186impl SamplingClockSourceOperation for SaffireClkProtocol {
187 const DST: SignalAddr = SignalAddr::Subunit(SignalSubunitAddr {
188 subunit: MUSIC_SUBUNIT_0,
189 plug_id: 0x04,
190 });
191
192 const SRC_LIST: &'static [SignalAddr] = &[
193 SignalAddr::Subunit(SignalSubunitAddr {
195 subunit: MUSIC_SUBUNIT_0,
196 plug_id: 0x07,
197 }),
198 SignalAddr::Unit(SignalUnitAddr::Ext(0x03)),
200 ];
201}
202
203#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
205pub struct SaffireMeter {
206 pub phys_inputs: [i32; 4],
208 pub dig_input_detect: bool,
210 pub monitor_knob_value: u16,
212}
213
214#[derive(Default, Debug)]
216pub struct SaffireMeterProtocol;
217
218impl SaffireMeterProtocol {
219 pub const MONITOR_KNOB_MIN: u16 = 0;
221 pub const MONITOR_KNOB_MAX: u16 = 0x1ff0;
223 pub const MONITOR_KNOB_STEP: u16 = 0x10;
225
226 pub const LEVEL_MIN: i32 = 0;
228 pub const LEVEL_MAX: i32 = 0x7fffffff;
230 pub const LEVEL_STEP: i32 = 1;
232
233 const OFFSETS: &'static [usize] = &[
234 0x00f4, 0x0100, 0x0104, 0x0108, 0x010c, 0x013c, ];
241
242 pub fn cache(
244 req: &FwReq,
245 node: &FwNode,
246 meter: &mut SaffireMeter,
247 timeout_ms: u32,
248 ) -> Result<(), Error> {
249 let mut raw = [0u8; Self::OFFSETS.len() * 4];
250
251 saffire_read_quadlets(req, node, Self::OFFSETS, &mut raw, timeout_ms).map(|_| {
252 let mut quadlet = [0u8; 4];
253 quadlet.copy_from_slice(&raw[..4]);
254 meter.monitor_knob_value = (u32::from_be_bytes(quadlet) & 0x0000ffff) as u16;
255
256 meter
257 .phys_inputs
258 .iter_mut()
259 .enumerate()
260 .for_each(|(i, level)| {
261 let pos = 4 + i * 4;
262 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
263 *level = i32::from_be_bytes(quadlet);
264 });
265
266 quadlet.copy_from_slice(&raw[20..]);
267 meter.dig_input_detect = u32::from_be_bytes(quadlet) > 0;
268 })
269 }
270}
271
272#[derive(Default, Debug)]
274pub struct SaffireOutputProtocol;
275
276impl SaffireOutputSpecification for SaffireOutputProtocol {
277 const OUTPUT_OFFSETS: &'static [usize] = &[0xdc, 0xe0, 0xe4, 0xe8, 0xec];
279
280 const MUTE_COUNT: usize = 5;
281 const VOL_COUNT: usize = 4;
282 const HWCTL_COUNT: usize = 4;
283 const DIM_COUNT: usize = 1;
284 const PAD_COUNT: usize = 0;
285}
286
287#[derive(Debug, Copy, Clone, Eq, PartialEq)]
289pub enum SaffireInputPair1Source {
290 AnalogInputPair0,
292 DigitalInputPair0,
294}
295
296impl Default for SaffireInputPair1Source {
297 fn default() -> Self {
298 Self::AnalogInputPair0
299 }
300}
301
302#[derive(Debug, Copy, Clone, Eq, PartialEq)]
304pub enum SaffireMixerMode {
305 StereoPaired,
307 StereoSeparated,
309}
310
311impl Default for SaffireMixerMode {
312 fn default() -> Self {
313 Self::StereoPaired
314 }
315}
316
317#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
319pub struct SaffireSpecificParameters {
320 pub mode_192khz: bool,
322 pub input_pair_1_src: SaffireInputPair1Source,
324 pub mixer_mode: SaffireMixerMode,
326}
327
328#[derive(Default, Debug)]
330pub struct SaffireSpecificProtocol;
331
332impl SaffireParametersSerdes<SaffireSpecificParameters> for SaffireSpecificProtocol {
333 const OFFSETS: &'static [usize] = &[
334 SAFFIRE_MODE_192KHZ_OFFSET,
335 SAFFIRE_INPUT_PAIR1_SRC_OFFSET,
336 SAFFIRE_MIXER_MODE_OFFSET,
337 ];
338
339 fn serialize(params: &SaffireSpecificParameters, raw: &mut [u8]) {
340 raw[..4].copy_from_slice(&(params.mode_192khz as u32).to_be_bytes());
341
342 let val: u32 = if params.input_pair_1_src == SaffireInputPair1Source::DigitalInputPair0 {
343 1
344 } else {
345 0
346 };
347 raw[4..8].copy_from_slice(&val.to_be_bytes());
348
349 let val: u32 = if params.mixer_mode == SaffireMixerMode::StereoSeparated {
350 1
351 } else {
352 0
353 };
354 raw[8..12].copy_from_slice(&val.to_be_bytes());
355 }
356
357 fn deserialize(params: &mut SaffireSpecificParameters, raw: &[u8]) {
358 let mut quadlet = [0u8; 4];
359
360 let quads: Vec<u32> = (0..raw.len())
361 .step_by(4)
362 .map(|pos| {
363 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
364 u32::from_be_bytes(quadlet)
365 })
366 .collect();
367
368 params.mode_192khz = quads[0] > 0;
369
370 params.input_pair_1_src = if quads[1] > 0 {
371 SaffireInputPair1Source::DigitalInputPair0
372 } else {
373 SaffireInputPair1Source::AnalogInputPair0
374 };
375
376 params.mixer_mode = if quads[2] > 0 {
377 SaffireMixerMode::StereoSeparated
378 } else {
379 SaffireMixerMode::StereoPaired
380 };
381 }
382}
383
384const SAFFIRE_INPUT_PAIR1_SRC_OFFSET: usize = 0xf8;
385const SAFFIRE_MIXER_MODE_OFFSET: usize = 0xfc;
386
387#[derive(Default, Debug)]
389pub struct SaffireSeparatedMixerProtocol;
390
391impl SaffireMixerSpecification for SaffireSeparatedMixerProtocol {
392 const MIXER_OFFSETS: &'static [usize] = &[
393 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, 0xd0, 0xd4, 0xd8, ];
460
461 const PHYS_INPUT_COUNT: usize = 4;
462 const REVERB_RETURN_COUNT: usize = 2;
463
464 #[inline(always)]
465 fn phys_src_pos(dst_idx: usize, src_idx: usize) -> usize {
466 ((dst_idx + 1) % 5) + ((src_idx % 2 * 15) + (src_idx / 2 * 5))
467 }
468
469 #[inline(always)]
470 fn reverb_return_pos(dst_idx: usize, src_idx: usize) -> usize {
471 10 + ((dst_idx + 1) % 5) + ((src_idx % 2 * 15) + (src_idx / 2 * 5))
472 }
473
474 #[inline(always)]
475 fn stream_src_pos(dst_idx: usize, src_idx: usize) -> usize {
476 30 + ((dst_idx + 1) % 5) + ((src_idx + 1) % 5) * 5
477 }
478}
479
480#[derive(Default, Debug)]
482pub struct SaffirePairedMixerProtocol;
483
484impl SaffireMixerSpecification for SaffirePairedMixerProtocol {
485 const MIXER_OFFSETS: &'static [usize] = &[
486 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, ];
535
536 const PHYS_INPUT_COUNT: usize = 2;
537 const REVERB_RETURN_COUNT: usize = 1;
538
539 #[inline(always)]
540 fn stream_src_pos(dst_idx: usize, src_idx: usize) -> usize {
541 ((src_idx + 1) % 5 * 5) + ((dst_idx + 1) % 5)
542 }
543
544 #[inline(always)]
545 fn phys_src_pos(dst_idx: usize, src_idx: usize) -> usize {
546 25 + src_idx * 5 + (dst_idx + 1) % 5
547 }
548
549 #[inline(always)]
550 fn reverb_return_pos(dst_idx: usize, _: usize) -> usize {
551 35 + (dst_idx + 1) % 5
552 }
553}
554
555#[derive(Default, Debug)]
557pub struct SaffireLeClkProtocol;
558
559impl MediaClockFrequencyOperation for SaffireLeClkProtocol {
560 const FREQ_LIST: &'static [u32] = &[44100, 48000, 88200, 96000];
561}
562
563impl SamplingClockSourceOperation for SaffireLeClkProtocol {
564 const DST: SignalAddr = SignalAddr::Subunit(SignalSubunitAddr {
565 subunit: MUSIC_SUBUNIT_0,
566 plug_id: 0x05,
567 });
568
569 const SRC_LIST: &'static [SignalAddr] = &[
570 SignalAddr::Subunit(SignalSubunitAddr {
572 subunit: MUSIC_SUBUNIT_0,
573 plug_id: 0x06,
574 }),
575 SignalAddr::Unit(SignalUnitAddr::Ext(0x04)),
577 ];
578}
579
580#[derive(Default, Debug)]
582pub struct SaffireStoreConfigProtocol;
583
584impl SaffireStoreConfigSpecification for SaffireStoreConfigProtocol {
585 const STORE_CONFIG_OFFSETS: &'static [usize] = &[0x148];
586}
587
588#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
590pub struct SaffireLeMeter {
591 pub phys_inputs: [i32; 6],
593 pub phys_outputs: [i32; 8],
595 pub stream_inputs: [i32; 4],
597 pub dig_input_detect: bool,
599}
600
601#[derive(Default, Debug)]
603pub struct SaffireLeMeterProtocol;
604
605impl SaffireLeMeterProtocol {
607 pub const LEVEL_MIN: i32 = 0;
609 pub const LEVEL_MAX: i32 = 0x7fffffff;
611 pub const LEVEL_STEP: i32 = 1;
613
614 const OFFSETS: &'static [usize] = &[
615 0x0168, 0x016c, 0x0170, 0x0174, 0x0178, 0x017c, 0x0180, 0x0184, 0x0188, 0x018c, 0x0190, 0x0194, 0x0198, 0x019c, 0x01a0, 0x01a4, 0x01a8, 0x01ac, 0x01b0, ];
635
636 pub fn cache(
638 req: &FwReq,
639 node: &FwNode,
640 meter: &mut SaffireLeMeter,
641 timeout_ms: u32,
642 ) -> Result<(), Error> {
643 let mut raw = [0u8; Self::OFFSETS.len() * 4];
644 saffire_read_quadlets(req, node, Self::OFFSETS, &mut raw, timeout_ms).map(|_| {
645 let mut quadlet = [0; 4];
646 let vals: Vec<i32> = (0..Self::OFFSETS.len())
647 .map(|i| {
648 let pos = i * 4;
649 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
650 i32::from_be_bytes(quadlet)
651 })
652 .collect();
653
654 meter.phys_inputs[0] = vals[0];
655 meter.phys_inputs[2] = vals[1];
656 meter.phys_inputs[4] = vals[2];
657 meter.phys_inputs[1] = vals[3];
658 meter.phys_inputs[3] = vals[4];
659 meter.phys_inputs[5] = vals[5];
660
661 meter.phys_outputs[0] = vals[6];
662 meter.phys_outputs[2] = vals[7];
663 meter.phys_outputs[1] = vals[8];
664 meter.phys_outputs[3] = vals[9];
665 meter.phys_outputs[4] = vals[10];
666 meter.phys_outputs[6] = vals[11];
667 meter.phys_outputs[5] = vals[12];
668 meter.phys_outputs[7] = vals[13];
669
670 meter.stream_inputs[0] = vals[14];
671 meter.stream_inputs[2] = vals[15];
672 meter.stream_inputs[1] = vals[16];
673 meter.stream_inputs[3] = vals[17];
674
675 meter.dig_input_detect = vals[18] > 0;
676 })
677 }
678}
679
680#[derive(Default, Debug)]
682pub struct SaffireLeOutputProtocol;
683
684impl SaffireOutputSpecification for SaffireLeOutputProtocol {
685 const OUTPUT_OFFSETS: &'static [usize] = &[0x15c, 0x160, 0x164];
687
688 const MUTE_COUNT: usize = 3;
689 const VOL_COUNT: usize = 3;
690 const HWCTL_COUNT: usize = 0;
691 const DIM_COUNT: usize = 0;
692 const PAD_COUNT: usize = 0;
693}
694
695#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
697pub struct SaffireLeSpecificParameters {
698 pub analog_input_2_3_high_gains: [bool; 2],
699}
700
701#[derive(Default, Debug)]
703pub struct SaffireLeSpecificProtocol;
704
705impl SaffireParametersSerdes<SaffireLeSpecificParameters> for SaffireLeSpecificProtocol {
706 const OFFSETS: &'static [usize] = &[
707 0x154, 0x158, ];
710
711 fn serialize(params: &SaffireLeSpecificParameters, raw: &mut [u8]) {
712 raw[..4].copy_from_slice(&(params.analog_input_2_3_high_gains[0] as u32).to_be_bytes());
713 raw[4..8].copy_from_slice(&(params.analog_input_2_3_high_gains[1] as u32).to_be_bytes());
714 }
715
716 fn deserialize(params: &mut SaffireLeSpecificParameters, raw: &[u8]) {
717 let mut quadlet = [0u8; 4];
718
719 let quads: Vec<u32> = (0..raw.len())
720 .step_by(4)
721 .map(|pos| {
722 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
723 u32::from_be_bytes(quadlet)
724 })
725 .collect();
726
727 params
728 .analog_input_2_3_high_gains
729 .iter_mut()
730 .enumerate()
731 .for_each(|(i, enabled)| *enabled = quads[i] > 0);
732 }
733}
734
735#[derive(Debug, Copy, Clone, PartialEq, Eq)]
737pub enum SaffireLeSpdifOutputSource {
738 MixerOutputPair01,
740 MixerOutputPair67,
742}
743
744impl Default for SaffireLeSpdifOutputSource {
745 fn default() -> Self {
746 Self::MixerOutputPair01
747 }
748}
749
750#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
752pub struct SaffireLeMixerLowRateState {
753 pub phys_src_gains: [[i16; 6]; 4],
755 pub stream_src_gains: [[i16; 8]; 4],
757 pub spdif_out_src: SaffireLeSpdifOutputSource,
759}
760
761#[derive(Default, Debug)]
763pub struct SaffireLeMixerLowRateProtocol;
764
765impl SaffireParametersSerdes<SaffireLeMixerLowRateState> for SaffireLeMixerLowRateProtocol {
766 const OFFSETS: &'static [usize] = &[
767 0x000, 0x004, 0x008, 0x00c, 0x010, 0x014, 0x018, 0x01c, 0x020, 0x024, 0x028, 0x02c, 0x030, 0x034, 0x038, 0x03c, 0x040, 0x044, 0x048, 0x04c, 0x050, 0x054, 0x058, 0x05c, 0x060, 0x064, 0x068, 0x06c, 0x070, 0x074, 0x078, 0x07c, 0x080, 0x084, 0x088, 0x08c, 0x090, 0x094, 0x098, 0x09c, 0x0a0, 0x0a4, 0x0a8, 0x0ac, 0x0b0, 0x0b4, 0x0b8, 0x0bc, 0x0c0, 0x0c4, 0x0c8, 0x0cc, 0x0d0, 0x0d4, 0x0d8, 0x0dc, 0x100,
839 ];
840
841 fn serialize(params: &SaffireLeMixerLowRateState, raw: &mut [u8]) {
842 params
843 .stream_src_gains
844 .iter()
845 .enumerate()
846 .for_each(|(dst_idx, gains)| {
847 gains.iter().enumerate().for_each(|(src_idx, &gain)| {
848 let pos = SaffireLeMixerLowRateProtocol::stream_src_pos(dst_idx, src_idx) * 4;
849 let gain = gain as i32;
850 raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
851 });
852 });
853
854 params
855 .phys_src_gains
856 .iter()
857 .enumerate()
858 .for_each(|(dst_idx, gains)| {
859 gains.iter().enumerate().for_each(|(src_idx, &gain)| {
860 let pos = SaffireLeMixerLowRateProtocol::phys_src_pos(dst_idx, src_idx) * 4;
861 let gain = gain as i32;
862 raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
863 });
864 });
865
866 let val = match params.spdif_out_src {
867 SaffireLeSpdifOutputSource::MixerOutputPair67 => 1u32,
868 SaffireLeSpdifOutputSource::MixerOutputPair01 => 0,
869 };
870 raw[224..228].copy_from_slice(&val.to_be_bytes());
871 }
872
873 fn deserialize(params: &mut SaffireLeMixerLowRateState, raw: &[u8]) {
874 let mut quadlet = [0u8; 4];
875
876 let quads: Vec<u32> = (0..raw.len())
877 .step_by(4)
878 .map(|pos| {
879 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
880 u32::from_be_bytes(quadlet)
881 })
882 .collect();
883
884 params
885 .stream_src_gains
886 .iter_mut()
887 .enumerate()
888 .for_each(|(dst_idx, gains)| {
889 gains.iter_mut().enumerate().for_each(|(src_idx, gain)| {
890 let pos = SaffireLeMixerLowRateProtocol::stream_src_pos(dst_idx, src_idx);
891 *gain = quads[pos] as i16;
892 })
893 });
894
895 params
896 .phys_src_gains
897 .iter_mut()
898 .enumerate()
899 .for_each(|(dst_idx, gains)| {
900 gains.iter_mut().enumerate().for_each(|(src_idx, gain)| {
901 let pos = SaffireLeMixerLowRateProtocol::phys_src_pos(dst_idx, src_idx);
902 *gain = quads[pos] as i16;
903 })
904 });
905
906 params.spdif_out_src = if quads[56] != 0 {
907 SaffireLeSpdifOutputSource::MixerOutputPair67
908 } else {
909 SaffireLeSpdifOutputSource::MixerOutputPair01
910 };
911 }
912}
913
914impl SaffireLeMixerLowRateProtocol {
915 pub const LEVEL_MIN: i16 = 0;
917 pub const LEVEL_MAX: i16 = 0x7fff;
919 pub const LEVEL_STEP: i16 = 0x100;
921
922 #[inline(always)]
923 fn stream_src_pos(dst_idx: usize, src_idx: usize) -> usize {
924 assert!(dst_idx < 4);
925 assert!(src_idx < 8);
926
927 Self::compute_pos(dst_idx, src_idx, 4, 8)
928 }
929
930 #[inline(always)]
931 fn phys_src_pos(dst_idx: usize, src_idx: usize) -> usize {
932 assert!(dst_idx < 4);
933 assert!(src_idx < 6);
934
935 32 + Self::compute_pos(dst_idx, src_idx, 4, 6)
936 }
937
938 #[inline(always)]
939 fn compute_pos(dst_idx: usize, src_idx: usize, dst_count: usize, src_count: usize) -> usize {
940 let pair_gap = dst_count * src_count / 2;
941 ((1 - dst_idx % 2) * 2 + dst_idx / 2 % 2) + (src_idx % 2 * pair_gap + src_idx / 2 * 4)
942 }
943}
944
945#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
947pub struct SaffireLeMixerMiddleRateState {
948 pub monitor_src_phys_input_gains: [i16; 6],
950 pub monitor_out_src_pair_gains: [[i16; 1]; 4],
952 pub stream_src_pair_gains: [[i16; 2]; 4],
954 pub spdif_out_src: SaffireLeSpdifOutputSource,
956}
957
958impl SaffireParametersSerdes<SaffireLeMixerMiddleRateState> for SaffireLeMixerMiddleRateProtocol {
959 const OFFSETS: &'static [usize] = &[
960 0x108, 0x10c, 0x110, 0x114, 0x118, 0x11c, 0x120, 0x124, 0x128, 0x12c, 0x130, 0x134, 0x138, 0x13c, 0x140, 0x144, 0x148, 0x14c, 0x150,
985 ];
986
987 fn serialize(params: &SaffireLeMixerMiddleRateState, raw: &mut [u8]) {
988 params
989 .monitor_src_phys_input_gains
990 .iter()
991 .enumerate()
992 .for_each(|(src_idx, &gain)| {
993 let gain = gain as i32;
994 let pos =
995 SaffireLeMixerMiddleRateProtocol::monitor_analog_input_pos(0, src_idx) * 4;
996 raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
997 });
998
999 params
1000 .monitor_out_src_pair_gains
1001 .iter()
1002 .enumerate()
1003 .for_each(|(dst_idx, gains)| {
1004 gains.iter().enumerate().for_each(|(src_idx, &gain)| {
1005 let gain = gain as i32;
1006 let pos =
1007 SaffireLeMixerMiddleRateProtocol::mixer_monitor_src_pos(dst_idx, src_idx)
1008 * 4;
1009 raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
1010 });
1011 });
1012
1013 params
1014 .stream_src_pair_gains
1015 .iter()
1016 .enumerate()
1017 .for_each(|(dst_idx, gains)| {
1018 gains.iter().enumerate().for_each(|(src_idx, &gain)| {
1019 let gain = gain as i32;
1020 let pos =
1021 SaffireLeMixerMiddleRateProtocol::mixer_stream_input_pos(dst_idx, src_idx)
1022 * 4;
1023 raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
1024 });
1025 });
1026
1027 let val = if params.spdif_out_src == SaffireLeSpdifOutputSource::MixerOutputPair67 {
1028 1u32
1029 } else {
1030 0
1031 };
1032 raw[72..76].copy_from_slice(&val.to_be_bytes());
1033 }
1034
1035 fn deserialize(params: &mut SaffireLeMixerMiddleRateState, raw: &[u8]) {
1036 let mut quadlet = [0; 4];
1037
1038 let quads: Vec<i16> = (0..raw.len())
1039 .step_by(4)
1040 .map(|pos| {
1041 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
1042 i32::from_be_bytes(quadlet) as i16
1043 })
1044 .collect();
1045
1046 params
1047 .monitor_src_phys_input_gains
1048 .iter_mut()
1049 .enumerate()
1050 .for_each(|(src_idx, gain)| {
1051 let pos = SaffireLeMixerMiddleRateProtocol::monitor_analog_input_pos(0, src_idx);
1052 *gain = quads[pos];
1053 });
1054
1055 params
1056 .monitor_out_src_pair_gains
1057 .iter_mut()
1058 .enumerate()
1059 .for_each(|(dst_idx, gains)| {
1060 gains.iter_mut().enumerate().for_each(|(src_idx, gain)| {
1061 let pos =
1062 SaffireLeMixerMiddleRateProtocol::mixer_monitor_src_pos(dst_idx, src_idx);
1063 *gain = quads[pos];
1064 });
1065 });
1066
1067 params
1068 .stream_src_pair_gains
1069 .iter_mut()
1070 .enumerate()
1071 .for_each(|(dst_idx, gains)| {
1072 gains.iter_mut().enumerate().for_each(|(src_idx, gain)| {
1073 let pos =
1074 SaffireLeMixerMiddleRateProtocol::mixer_stream_input_pos(dst_idx, src_idx);
1075 *gain = quads[pos];
1076 });
1077 });
1078
1079 params.spdif_out_src = if quads[18] > 0 {
1080 SaffireLeSpdifOutputSource::MixerOutputPair67
1081 } else {
1082 SaffireLeSpdifOutputSource::MixerOutputPair01
1083 };
1084 }
1085}
1086
1087#[derive(Default, Debug)]
1089pub struct SaffireLeMixerMiddleRateProtocol;
1090
1091impl SaffireLeMixerMiddleRateProtocol {
1092 pub const LEVEL_MIN: i16 = 0;
1094 pub const LEVEL_MAX: i16 = 0x7fff;
1096 pub const LEVEL_STEP: i16 = 0x100;
1098
1099 #[inline(always)]
1100 fn monitor_analog_input_pos(_: usize, src_idx: usize) -> usize {
1101 src_idx % 2 * 3 + src_idx / 2
1102 }
1103
1104 #[inline(always)]
1105 fn mixer_monitor_src_pos(dst_idx: usize, src_idx: usize) -> usize {
1106 6 + (dst_idx * 3) + src_idx
1107 }
1108
1109 #[inline(always)]
1110 fn mixer_stream_input_pos(dst_idx: usize, src_idx: usize) -> usize {
1111 6 + (dst_idx * 3) + src_idx + 1
1112 }
1113}
1114
1115#[derive(Default, Debug)]
1117pub struct SaffireLeThroughProtocol;
1118
1119impl SaffireThroughSpecification for SaffireLeThroughProtocol {
1120 const THROUGH_OFFSETS: &'static [usize] = &[0x01bc, 0x01c0];
1121}
1122
1123#[derive(Default, Debug)]
1125pub struct SaffireLeStoreConfigProtocol;
1126
1127impl SaffireStoreConfigSpecification for SaffireLeStoreConfigProtocol {
1128 const STORE_CONFIG_OFFSETS: &'static [usize] = &[0x1b8];
1129}
1130
1131#[derive(Debug, Clone, PartialEq, Eq)]
1133pub struct SaffireMixerState {
1134 pub phys_inputs: Vec<Vec<i16>>,
1136 pub reverb_returns: Vec<Vec<i16>>,
1138 pub stream_inputs: Vec<Vec<i16>>,
1140}
1141
1142pub trait SaffireMixerSpecification {
1144 const MIXER_OFFSETS: &'static [usize];
1146
1147 const PHYS_INPUT_COUNT: usize;
1149
1150 const REVERB_RETURN_COUNT: usize;
1152
1153 fn stream_src_pos(dst_idx: usize, src_idx: usize) -> usize;
1154 fn phys_src_pos(dst_idx: usize, src_idx: usize) -> usize;
1155 fn reverb_return_pos(dst_idx: usize, src_idx: usize) -> usize;
1156}
1157
1158impl<O: SaffireMixerSpecification> SaffireParametersSerdes<SaffireMixerState> for O {
1159 const OFFSETS: &'static [usize] = O::MIXER_OFFSETS;
1160
1161 fn serialize(params: &SaffireMixerState, raw: &mut [u8]) {
1162 params
1163 .phys_inputs
1164 .iter()
1165 .enumerate()
1166 .for_each(|(dst_idx, gains)| {
1167 gains.iter().enumerate().for_each(|(src_idx, &gain)| {
1168 let pos = O::phys_src_pos(dst_idx, src_idx) * 4;
1169 let gain = gain as i32;
1170 raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
1171 });
1172 });
1173
1174 params
1175 .reverb_returns
1176 .iter()
1177 .enumerate()
1178 .for_each(|(dst_idx, gains)| {
1179 gains.iter().enumerate().for_each(|(src_idx, &gain)| {
1180 let pos = O::reverb_return_pos(dst_idx, src_idx) * 4;
1181 let gain = gain as i32;
1182 raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
1183 });
1184 });
1185
1186 params
1187 .stream_inputs
1188 .iter()
1189 .enumerate()
1190 .for_each(|(dst_idx, gains)| {
1191 gains.iter().enumerate().for_each(|(src_idx, &gain)| {
1192 let pos = O::stream_src_pos(dst_idx, src_idx) * 4;
1193 let gain = gain as i32;
1194 raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
1195 });
1196 });
1197 }
1198
1199 fn deserialize(params: &mut SaffireMixerState, raw: &[u8]) {
1200 let mut quadlet = [0; 4];
1201
1202 let quads: Vec<i16> = (0..raw.len())
1203 .step_by(4)
1204 .map(|pos| {
1205 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
1206 i32::from_be_bytes(quadlet) as i16
1207 })
1208 .collect();
1209
1210 params
1211 .phys_inputs
1212 .iter_mut()
1213 .enumerate()
1214 .for_each(|(dst_idx, gains)| {
1215 gains.iter_mut().enumerate().for_each(|(src_idx, gain)| {
1216 let pos = O::phys_src_pos(dst_idx, src_idx);
1217 *gain = quads[pos];
1218 });
1219 });
1220
1221 params
1222 .reverb_returns
1223 .iter_mut()
1224 .enumerate()
1225 .for_each(|(dst_idx, gains)| {
1226 gains.iter_mut().enumerate().for_each(|(src_idx, gain)| {
1227 let pos = O::reverb_return_pos(dst_idx, src_idx);
1228 *gain = quads[pos];
1229 });
1230 });
1231
1232 params
1233 .stream_inputs
1234 .iter_mut()
1235 .enumerate()
1236 .for_each(|(dst_idx, gains)| {
1237 gains.iter_mut().enumerate().for_each(|(src_idx, gain)| {
1238 let pos = O::stream_src_pos(dst_idx, src_idx);
1239 *gain = quads[pos];
1240 });
1241 });
1242 }
1243}
1244
1245pub trait SaffireMixerOperation: SaffireMixerSpecification {
1247 const STREAM_INPUT_COUNT: usize = 5;
1249
1250 const OUTPUT_PAIR_COUNT: usize = 5;
1252
1253 const LEVEL_MIN: i16 = 0x0000;
1255 const LEVEL_MAX: i16 = 0x7fff;
1257 const LEVEL_STEP: i16 = 0x100;
1259
1260 fn create_mixer_state() -> SaffireMixerState {
1261 SaffireMixerState {
1262 phys_inputs: vec![vec![0; Self::PHYS_INPUT_COUNT]; Self::OUTPUT_PAIR_COUNT],
1263 reverb_returns: vec![vec![0; Self::REVERB_RETURN_COUNT]; Self::OUTPUT_PAIR_COUNT],
1264 stream_inputs: vec![vec![0; Self::STREAM_INPUT_COUNT]; Self::OUTPUT_PAIR_COUNT],
1265 }
1266 }
1267}
1268
1269impl<O: SaffireMixerSpecification> SaffireMixerOperation for O {}
1270
1271#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
1273pub struct SaffireReverbParameters {
1274 pub amounts: [i32; 2],
1275 pub room_sizes: [i32; 2],
1276 pub diffusions: [i32; 2],
1277 pub tones: [i32; 2],
1278}
1279
1280#[derive(Default, Debug)]
1290pub struct SaffireReverbProtocol;
1291
1292impl SaffireParametersSerdes<SaffireReverbParameters> for SaffireReverbProtocol {
1293 const OFFSETS: &'static [usize] = &[
1294 0x1004, 0x1008, 0x100c, 0x1010, 0x1014, 0x1018, 0x101c, 0x1020, 0x1024, 0x1028, ];
1307
1308 fn serialize(params: &SaffireReverbParameters, raw: &mut [u8]) {
1309 raw[..4].copy_from_slice(¶ms.amounts[0].to_be_bytes());
1310 raw[4..8].copy_from_slice(¶ms.room_sizes[0].to_be_bytes());
1311 raw[8..12].copy_from_slice(¶ms.diffusions[0].to_be_bytes());
1312 Self::build_tone(&mut raw[12..20], params.tones[0]);
1313
1314 raw[20..24].copy_from_slice(¶ms.amounts[1].to_be_bytes());
1315 raw[24..28].copy_from_slice(¶ms.room_sizes[1].to_be_bytes());
1316 raw[28..32].copy_from_slice(¶ms.diffusions[1].to_be_bytes());
1317 Self::build_tone(&mut raw[32..40], params.tones[1]);
1318 }
1319
1320 fn deserialize(params: &mut SaffireReverbParameters, raw: &[u8]) {
1321 let mut quadlet = [0u8; 4];
1322
1323 let quads: Vec<i32> = (0..raw.len())
1324 .step_by(4)
1325 .map(|pos| {
1326 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
1327 i32::from_be_bytes(quadlet)
1328 })
1329 .collect();
1330
1331 params.amounts[0] = quads[0];
1332 params.room_sizes[0] = quads[1];
1333 params.diffusions[0] = quads[2];
1334 params.tones[0] = Self::parse_tone(&quads[3..5]);
1335 params.amounts[1] = quads[5];
1336 params.room_sizes[1] = quads[6];
1337 params.diffusions[1] = quads[7];
1338 params.tones[1] = Self::parse_tone(&quads[8..10]);
1339 }
1340}
1341
1342impl SaffireReverbProtocol {
1343 pub const AMOUNT_MIN: i32 = 0x00000000;
1344 pub const AMOUNT_MAX: i32 = 0x7fffffff;
1345 pub const AMOUNT_STEP: i32 = 0x00000001;
1346
1347 pub const ROOM_SIZE_MIN: i32 = 0x00000000;
1348 pub const ROOM_SIZE_MAX: i32 = 0x7fffffff;
1349 pub const ROOM_SIZE_STEP: i32 = 0x00000001;
1350
1351 pub const DIFFUSION_MIN: i32 = 0x00000000;
1352 pub const DIFFUSION_MAX: i32 = 0x7fffffff;
1353 pub const DIFFUSION_STEP: i32 = 0x00000001;
1354
1355 pub const TONE_MIN: i32 = i32::MIN + 1;
1356 pub const TONE_MAX: i32 = i32::MAX;
1357 pub const TONE_STEP: i32 = 0x00000001;
1358
1359 fn parse_tone(vals: &[i32]) -> i32 {
1360 assert_eq!(vals.len(), 2);
1361 let mut tone = vals[1];
1362 if vals[0] > 0 {
1363 tone *= -1;
1364 }
1365 tone
1366 }
1367
1368 fn build_tone(vals: &mut [u8], tone: i32) {
1369 assert_eq!(vals.len(), 8);
1370 vals[..4].copy_from_slice(&((tone < 0) as u32).to_be_bytes());
1371 vals[4..].copy_from_slice(&(tone.abs() as u32).to_be_bytes());
1372 }
1373}
1374
1375#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
1377pub struct SaffireCompressorParameters {
1378 pub input_gains: [i32; 2],
1379 pub enables: [bool; 2],
1380 pub output_volumes: [i32; 2],
1381}
1382
1383#[derive(Default, Debug)]
1396pub struct SaffireCompressorProtocol;
1397
1398impl SaffireParametersSerdes<SaffireCompressorParameters> for SaffireCompressorProtocol {
1399 const OFFSETS: &'static [usize] = &[
1400 0x0c00, 0x0c04, 0x0c08, 0x0c0c, 0x0c10, 0x0c14, 0x0c18, 0x0c1c, 0x0c28, 0x0c2c, 0x0c30, 0x0c34, 0x0c38, 0x0c3c, 0x0c40, 0x0c48,
1403 ];
1404
1405 fn serialize(params: &SaffireCompressorParameters, raw: &mut [u8]) {
1406 raw[20..24].copy_from_slice(&(params.enables[0] as u32).to_be_bytes());
1407 raw[24..28].copy_from_slice(¶ms.input_gains[0].to_be_bytes());
1408 raw[28..32].copy_from_slice(¶ms.output_volumes[0].to_be_bytes());
1409 raw[52..56].copy_from_slice(&(params.enables[1] as u32).to_be_bytes());
1410 raw[56..60].copy_from_slice(¶ms.input_gains[1].to_be_bytes());
1411 raw[60..64].copy_from_slice(¶ms.output_volumes[1].to_be_bytes());
1412 }
1413
1414 fn deserialize(params: &mut SaffireCompressorParameters, raw: &[u8]) {
1415 let mut quadlet = [0u8; 4];
1416
1417 let quads: Vec<i32> = (0..raw.len())
1418 .step_by(4)
1419 .map(|pos| {
1420 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
1421 i32::from_be_bytes(quadlet)
1422 })
1423 .collect();
1424
1425 params.enables[0] = quads[5] > 0;
1426 params.enables[1] = quads[13] > 0;
1427 params.input_gains[0] = quads[6];
1428 params.input_gains[1] = quads[14];
1429 params.output_volumes[0] = quads[7];
1430 params.output_volumes[1] = quads[15];
1431 }
1432}
1433
1434impl SaffireCompressorProtocol {
1435 pub const GAIN_MIN: i32 = 0x0fffffff;
1436 pub const GAIN_MAX: i32 = 0x7fffffff;
1437 pub const GAIN_STEP: i32 = 1;
1438
1439 pub const VOLUME_MIN: i32 = 0x0fffffff;
1440 pub const VOLUME_MAX: i32 = 0x7fffffff;
1441 pub const VOLUME_STEP: i32 = 1;
1442}
1443
1444#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
1446pub struct SaffireEqualizerParameters {
1447 pub enables: [bool; 2],
1448 pub input_gains: [i32; 2],
1449 pub output_volumes: [i32; 2],
1450}
1451
1452#[derive(Default, Debug)]
1492pub struct SaffireEqualizerProtocol;
1493
1494impl SaffireParametersSerdes<SaffireEqualizerParameters> for SaffireEqualizerProtocol {
1495 const OFFSETS: &'static [usize] = &[
1496 0x0800, 0x0804, 0x0808, 0x080c, 0x0810, 0x0814, 0x0828, 0x082c, 0x0830, 0x0834, 0x0840, 0x0844, 0x0850, 0x08c8, 0x08cc, 0x08d0, 0x08d4, 0x08e0, 0x08e4, 0x08f0, 0x0968, 0x096c, 0x0970, 0x0974, 0x0980, 0x0984, 0x0990, 0x0a08, 0x0a0c, 0x0a10, 0x0a14, 0x0a20, 0x0a24, 0x0a30, 0x0878, 0x087c, 0x0880, 0x0884, 0x0890, 0x0894, 0x08a0, 0x0918, 0x091c, 0x0920, 0x0924, 0x0930, 0x0934, 0x0940, 0x09b8, 0x09bc, 0x09c0, 0x09c4, 0x09d0, 0x09d4, 0x09e0, 0x0a58, 0x0a5c, 0x0a60, 0x0a64, 0x0a70, 0x0a74, 0x0a80,
1505 ];
1506
1507 fn serialize(params: &SaffireEqualizerParameters, raw: &mut [u8]) {
1508 raw[20..24].copy_from_slice(&(params.enables[0] as u32).to_be_bytes());
1509 raw[24..28].copy_from_slice(¶ms.input_gains[0].to_be_bytes());
1510 raw[28..32].copy_from_slice(¶ms.output_volumes[0].to_be_bytes());
1511 raw[52..56].copy_from_slice(&(params.enables[1] as u32).to_be_bytes());
1512 raw[56..60].copy_from_slice(¶ms.input_gains[1].to_be_bytes());
1513 raw[60..64].copy_from_slice(¶ms.output_volumes[1].to_be_bytes());
1514 }
1515
1516 fn deserialize(params: &mut SaffireEqualizerParameters, raw: &[u8]) {
1517 let mut quadlet = [0u8; 4];
1518
1519 let quads: Vec<i32> = (0..raw.len())
1520 .step_by(4)
1521 .map(|pos| {
1522 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
1523 i32::from_be_bytes(quadlet)
1524 })
1525 .collect();
1526
1527 params.enables[0] = quads[5] > 0;
1528 params.enables[1] = quads[13] > 0;
1529 params.input_gains[0] = quads[6];
1530 params.input_gains[1] = quads[14];
1531 params.output_volumes[0] = quads[7];
1532 params.output_volumes[1] = quads[15];
1533 }
1534}
1535
1536#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
1538pub struct SaffireAmplifierParameters {
1539 pub enables: [bool; 2],
1540 pub output_volumes: [i32; 2],
1541}
1542
1543#[derive(Default, Debug)]
1549pub struct SaffireAmplifierProtocol;
1550
1551impl SaffireParametersSerdes<SaffireAmplifierParameters> for SaffireAmplifierProtocol {
1552 const OFFSETS: &'static [usize] = &[0x1400, 0x17e8, 0x17ec, 0x1bd4];
1553
1554 fn serialize(params: &SaffireAmplifierParameters, raw: &mut [u8]) {
1555 raw[..4].copy_from_slice(&(params.enables[0] as u32).to_be_bytes());
1556 raw[4..8].copy_from_slice(&(params.enables[1] as u32).to_be_bytes());
1557 raw[8..12].copy_from_slice(¶ms.output_volumes[0].to_be_bytes());
1558 raw[12..16].copy_from_slice(¶ms.output_volumes[1].to_be_bytes());
1559 }
1560
1561 fn deserialize(params: &mut SaffireAmplifierParameters, raw: &[u8]) {
1562 let mut quadlet = [0u8; 4];
1563
1564 let quads: Vec<i32> = (0..raw.len())
1565 .step_by(4)
1566 .map(|pos| {
1567 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
1568 i32::from_be_bytes(quadlet)
1569 })
1570 .collect();
1571
1572 params.enables[0] = quads[0] > 0;
1573 params.enables[1] = quads[1] > 0;
1574 params.output_volumes[0] = quads[2];
1575 params.output_volumes[1] = quads[3];
1576 }
1577}
1578
1579#[derive(Debug, Copy, Clone, Eq, PartialEq)]
1581pub enum SaffireChStripCompOrder {
1582 Pre,
1583 Post,
1584}
1585
1586impl Default for SaffireChStripCompOrder {
1587 fn default() -> Self {
1588 Self::Pre
1589 }
1590}
1591
1592#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
1594pub struct SaffireChStripParameters {
1595 pub paired_mode: SaffireMixerMode,
1596 pub comp_orders: [SaffireChStripCompOrder; 2],
1597}
1598
1599impl SaffireParametersSerdes<SaffireChStripParameters> for SaffireChStripProtocol {
1600 const OFFSETS: &'static [usize] = &[0x7d0, 0x7d4, 0x7d8];
1601
1602 fn serialize(params: &SaffireChStripParameters, raw: &mut [u8]) {
1603 raw[..4].copy_from_slice(
1604 &(match params.paired_mode {
1605 SaffireMixerMode::StereoSeparated => 1u32,
1606 SaffireMixerMode::StereoPaired => 0,
1607 })
1608 .to_be_bytes(),
1609 );
1610
1611 params
1612 .comp_orders
1613 .iter()
1614 .enumerate()
1615 .for_each(|(i, comp_order)| {
1616 let pos = 4 + i * 4;
1617 raw[pos..(pos + 4)].copy_from_slice(
1618 &(match comp_order {
1619 SaffireChStripCompOrder::Pre => 1u32,
1620 SaffireChStripCompOrder::Post => 0,
1621 })
1622 .to_be_bytes(),
1623 );
1624 });
1625 }
1626
1627 fn deserialize(params: &mut SaffireChStripParameters, raw: &[u8]) {
1628 let mut quadlet = [0u8; 4];
1629
1630 let quads: Vec<u32> = (0..raw.len())
1631 .step_by(4)
1632 .map(|pos| {
1633 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
1634 u32::from_be_bytes(quadlet)
1635 })
1636 .collect();
1637
1638 params.paired_mode = if quads[0] > 0 {
1639 SaffireMixerMode::StereoSeparated
1640 } else {
1641 SaffireMixerMode::StereoPaired
1642 };
1643 params
1644 .comp_orders
1645 .iter_mut()
1646 .enumerate()
1647 .for_each(|(i, comp_order)| {
1648 *comp_order = if quads[1 + i] > 0 {
1649 SaffireChStripCompOrder::Pre
1650 } else {
1651 SaffireChStripCompOrder::Post
1652 };
1653 });
1654 }
1655}
1656
1657#[derive(Default, Debug)]
1659pub struct SaffireChStripProtocol;
1660
1661#[cfg(test)]
1662mod test {
1663 use super::*;
1664
1665 #[test]
1666 fn saffire_output_protocol_serdes() {
1667 let mut params = SaffireOutputProtocol::create_output_parameters();
1668
1669 params
1670 .mutes
1671 .iter_mut()
1672 .step_by(2)
1673 .for_each(|mute| *mute = true);
1674
1675 params
1676 .vols
1677 .iter_mut()
1678 .enumerate()
1679 .for_each(|(i, vol)| *vol = i as u8);
1680
1681 params
1682 .hwctls
1683 .iter_mut()
1684 .step_by(2)
1685 .for_each(|hwctl| *hwctl = true);
1686
1687 params
1688 .dims
1689 .iter_mut()
1690 .step_by(2)
1691 .for_each(|dim| *dim = true);
1692
1693 params
1694 .pads
1695 .iter_mut()
1696 .step_by(2)
1697 .for_each(|pad| *pad = true);
1698
1699 let mut raw = vec![0u8; SaffireOutputProtocol::OFFSETS.len() * 4];
1700 SaffireOutputProtocol::serialize(¶ms, &mut raw);
1701 let mut p = SaffireOutputProtocol::create_output_parameters();
1702 SaffireOutputProtocol::deserialize(&mut p, &raw);
1703
1704 assert_eq!(params, p);
1705 }
1706
1707 #[test]
1708 fn saffire_le_output_protocol_serdes() {
1709 let mut params = SaffireLeOutputProtocol::create_output_parameters();
1710
1711 params
1712 .mutes
1713 .iter_mut()
1714 .step_by(2)
1715 .for_each(|mute| *mute = true);
1716
1717 params
1718 .vols
1719 .iter_mut()
1720 .enumerate()
1721 .for_each(|(i, vol)| *vol = i as u8);
1722
1723 params
1724 .hwctls
1725 .iter_mut()
1726 .step_by(2)
1727 .for_each(|hwctl| *hwctl = true);
1728
1729 params
1730 .dims
1731 .iter_mut()
1732 .step_by(2)
1733 .for_each(|dim| *dim = true);
1734
1735 params
1736 .pads
1737 .iter_mut()
1738 .step_by(2)
1739 .for_each(|pad| *pad = true);
1740
1741 let mut raw = vec![0u8; SaffireLeOutputProtocol::OFFSETS.len() * 4];
1742 SaffireLeOutputProtocol::serialize(¶ms, &mut raw);
1743 let mut p = SaffireLeOutputProtocol::create_output_parameters();
1744 SaffireLeOutputProtocol::deserialize(&mut p, &raw);
1745
1746 assert_eq!(params, p);
1747 }
1748
1749 #[test]
1750 fn saffire_le_through_protocol_serdes() {
1751 let params = SaffireThroughParameters {
1752 midi: true,
1753 ac3: true,
1754 };
1755 let mut raw = vec![0u8; SaffireLeThroughProtocol::OFFSETS.len() * 4];
1756 SaffireLeThroughProtocol::serialize(¶ms, &mut raw);
1757 let mut p = SaffireThroughParameters::default();
1758 SaffireLeThroughProtocol::deserialize(&mut p, &raw);
1759 assert_eq!(params, p);
1760 }
1761
1762 #[test]
1763 fn saffire_specific_protocols_serdes() {
1764 let params = SaffireSpecificParameters {
1765 mode_192khz: true,
1766 input_pair_1_src: SaffireInputPair1Source::DigitalInputPair0,
1767 mixer_mode: SaffireMixerMode::StereoSeparated,
1768 };
1769 let mut raw = vec![0u8; SaffireSpecificProtocol::OFFSETS.len() * 4];
1770 SaffireSpecificProtocol::serialize(¶ms, &mut raw);
1771 let mut p = SaffireSpecificParameters::default();
1772 SaffireSpecificProtocol::deserialize(&mut p, &raw);
1773 }
1774
1775 #[test]
1776 fn saffire_separated_mixer_phys_src_pos() {
1777 [
1778 (0, 0, 1),
1779 (0, 1, 2),
1780 (0, 2, 3),
1781 (0, 3, 4),
1782 (0, 4, 0),
1783 (1, 0, 16),
1784 (1, 1, 17),
1785 (1, 2, 18),
1786 (1, 3, 19),
1787 (1, 4, 15),
1788 (2, 0, 6),
1789 (2, 1, 7),
1790 (2, 2, 8),
1791 (2, 3, 9),
1792 (2, 4, 5),
1793 (3, 0, 21),
1794 (3, 1, 22),
1795 (3, 2, 23),
1796 (3, 3, 24),
1797 (3, 4, 20),
1798 ]
1799 .iter()
1800 .for_each(|&(src_idx, dst_idx, expected)| {
1801 let pos = SaffireSeparatedMixerProtocol::phys_src_pos(dst_idx, src_idx);
1802 assert_eq!(pos, expected);
1803 });
1804 }
1805
1806 #[test]
1807 fn saffire_separated_mixer_reverb_return_pos() {
1808 [
1809 (0, 0, 11),
1810 (0, 1, 12),
1811 (0, 2, 13),
1812 (0, 3, 14),
1813 (0, 4, 10),
1814 (1, 0, 26),
1815 (1, 1, 27),
1816 (1, 2, 28),
1817 (1, 3, 29),
1818 (1, 4, 25),
1819 ]
1820 .iter()
1821 .for_each(|&(src_idx, dst_idx, expected)| {
1822 let pos = SaffireSeparatedMixerProtocol::reverb_return_pos(dst_idx, src_idx);
1823 assert_eq!(pos, expected);
1824 });
1825 }
1826
1827 #[test]
1828 fn saffire_separated_mixer_stream_src_pos() {
1829 [
1830 (0, 0, 36),
1831 (0, 1, 37),
1832 (0, 2, 38),
1833 (0, 3, 39),
1834 (0, 4, 35),
1835 (1, 0, 41),
1836 (1, 1, 42),
1837 (1, 2, 43),
1838 (1, 3, 44),
1839 (1, 4, 40),
1840 (2, 0, 46),
1841 (2, 1, 47),
1842 (2, 2, 48),
1843 (2, 3, 49),
1844 (2, 4, 45),
1845 (3, 0, 51),
1846 (3, 1, 52),
1847 (3, 2, 53),
1848 (3, 3, 54),
1849 (3, 4, 50),
1850 (4, 0, 31),
1851 (4, 1, 32),
1852 (4, 2, 33),
1853 (4, 3, 34),
1854 (4, 4, 30),
1855 ]
1856 .iter()
1857 .for_each(|&(src_idx, dst_idx, expected)| {
1858 let pos = SaffireSeparatedMixerProtocol::stream_src_pos(dst_idx, src_idx);
1859 assert_eq!(pos, expected);
1860 });
1861 }
1862
1863 #[test]
1864 fn saffire_separated_mixer_protocol_serdes() {
1865 let mut params = SaffireSeparatedMixerProtocol::create_mixer_state();
1866 params
1867 .phys_inputs
1868 .iter_mut()
1869 .enumerate()
1870 .for_each(|(i, gains)| {
1871 gains
1872 .iter_mut()
1873 .enumerate()
1874 .for_each(|(j, gain)| *gain = (i * 100 + j) as i16)
1875 });
1876 params
1877 .reverb_returns
1878 .iter_mut()
1879 .enumerate()
1880 .for_each(|(i, gains)| {
1881 gains
1882 .iter_mut()
1883 .enumerate()
1884 .for_each(|(j, gain)| *gain = (i * 100 + j) as i16)
1885 });
1886 params
1887 .stream_inputs
1888 .iter_mut()
1889 .enumerate()
1890 .for_each(|(i, gains)| {
1891 gains
1892 .iter_mut()
1893 .enumerate()
1894 .for_each(|(j, gain)| *gain = (i * 100 + j) as i16)
1895 });
1896 let mut raw = vec![0u8; SaffireSeparatedMixerProtocol::OFFSETS.len() * 4];
1897 SaffireSeparatedMixerProtocol::serialize(¶ms, &mut raw);
1898 let mut p = SaffireSeparatedMixerProtocol::create_mixer_state();
1899 SaffireSeparatedMixerProtocol::deserialize(&mut p, &raw);
1900
1901 assert_eq!(params, p);
1902 }
1903
1904 #[test]
1905 fn saffire_paired_mixer_stream_src_pos() {
1906 [
1907 (0, 0, 6),
1908 (0, 1, 7),
1909 (0, 2, 8),
1910 (0, 3, 9),
1911 (0, 4, 5),
1912 (1, 0, 11),
1913 (1, 1, 12),
1914 (1, 2, 13),
1915 (1, 3, 14),
1916 (1, 4, 10),
1917 (2, 0, 16),
1918 (2, 1, 17),
1919 (2, 2, 18),
1920 (2, 3, 19),
1921 (2, 4, 15),
1922 (3, 0, 21),
1923 (3, 1, 22),
1924 (3, 2, 23),
1925 (3, 3, 24),
1926 (3, 4, 20),
1927 (4, 0, 1),
1928 (4, 1, 2),
1929 (4, 2, 3),
1930 (4, 3, 4),
1931 (4, 4, 0),
1932 ]
1933 .iter()
1934 .for_each(|&(src_idx, dst_idx, expected)| {
1935 let pos = SaffirePairedMixerProtocol::stream_src_pos(dst_idx, src_idx);
1936 assert_eq!(pos, expected);
1937 });
1938 }
1939
1940 #[test]
1941 fn saffire_paired_mixer_phys_src_pos() {
1942 [
1943 (0, 0, 26),
1944 (0, 1, 27),
1945 (0, 2, 28),
1946 (0, 3, 29),
1947 (0, 4, 25),
1948 (1, 0, 31),
1949 (1, 1, 32),
1950 (1, 2, 33),
1951 (1, 3, 34),
1952 (1, 4, 30),
1953 ]
1954 .iter()
1955 .for_each(|&(src_idx, dst_idx, expected)| {
1956 let pos = SaffirePairedMixerProtocol::phys_src_pos(dst_idx, src_idx);
1957 assert_eq!(pos, expected);
1958 });
1959 }
1960
1961 #[test]
1962 fn saffire_paired_mixer_reverb_return_pos() {
1963 [(0, 36), (1, 37), (2, 38), (3, 39), (4, 35)]
1964 .iter()
1965 .for_each(|&(dst_idx, expected)| {
1966 let pos = SaffirePairedMixerProtocol::reverb_return_pos(dst_idx, 0);
1967 assert_eq!(pos, expected);
1968 });
1969 }
1970
1971 #[test]
1972 fn saffire_paired_mixer_protocol_serdes() {
1973 let mut params = SaffirePairedMixerProtocol::create_mixer_state();
1974 params
1975 .phys_inputs
1976 .iter_mut()
1977 .enumerate()
1978 .for_each(|(i, gains)| {
1979 gains
1980 .iter_mut()
1981 .enumerate()
1982 .for_each(|(j, gain)| *gain = (i * 100 + j) as i16)
1983 });
1984 params
1985 .reverb_returns
1986 .iter_mut()
1987 .enumerate()
1988 .for_each(|(i, gains)| {
1989 gains
1990 .iter_mut()
1991 .enumerate()
1992 .for_each(|(j, gain)| *gain = (i * 100 + j) as i16)
1993 });
1994 params
1995 .stream_inputs
1996 .iter_mut()
1997 .enumerate()
1998 .for_each(|(i, gains)| {
1999 gains
2000 .iter_mut()
2001 .enumerate()
2002 .for_each(|(j, gain)| *gain = (i * 100 + j) as i16)
2003 });
2004 let mut raw = vec![0u8; SaffirePairedMixerProtocol::OFFSETS.len() * 4];
2005 SaffirePairedMixerProtocol::serialize(¶ms, &mut raw);
2006 let mut p = SaffirePairedMixerProtocol::create_mixer_state();
2007 SaffirePairedMixerProtocol::deserialize(&mut p, &raw);
2008
2009 assert_eq!(params, p);
2010 }
2011
2012 #[test]
2013 fn saffire_reverb_protocol_serdes() {
2014 let params = SaffireReverbParameters {
2015 amounts: [-101, 102],
2016 room_sizes: [111, -112],
2017 diffusions: [-113, 113],
2018 tones: [114, -114],
2019 };
2020 let mut raw = vec![0u8; SaffireReverbProtocol::OFFSETS.len() * 4];
2021 SaffireReverbProtocol::serialize(¶ms, &mut raw);
2022 let mut p = SaffireReverbParameters::default();
2023 SaffireReverbProtocol::deserialize(&mut p, &raw);
2024
2025 assert_eq!(params, p);
2026 }
2027
2028 #[test]
2029 fn saffire_compressor_protocol_serdes() {
2030 let params = SaffireCompressorParameters {
2031 input_gains: [-200, 200],
2032 enables: [true, false],
2033 output_volumes: [201, -201],
2034 };
2035 let mut raw = vec![0u8; SaffireCompressorProtocol::OFFSETS.len() * 4];
2036 SaffireCompressorProtocol::serialize(¶ms, &mut raw);
2037 let mut p = SaffireCompressorParameters::default();
2038 SaffireCompressorProtocol::deserialize(&mut p, &raw);
2039
2040 assert_eq!(params, p);
2041 }
2042
2043 #[test]
2044 fn saffire_equalizer_protocol_serdes() {
2045 let params = SaffireEqualizerParameters {
2046 input_gains: [-200, 200],
2047 enables: [true, false],
2048 output_volumes: [201, -201],
2049 };
2050 let mut raw = vec![0u8; SaffireEqualizerProtocol::OFFSETS.len() * 4];
2051 SaffireEqualizerProtocol::serialize(¶ms, &mut raw);
2052 let mut p = SaffireEqualizerParameters::default();
2053 SaffireEqualizerProtocol::deserialize(&mut p, &raw);
2054
2055 assert_eq!(params, p);
2056 }
2057
2058 #[test]
2059 fn saffire_amplifier_protocol_serdes() {
2060 let params = SaffireAmplifierParameters {
2061 enables: [false, true],
2062 output_volumes: [400, -401],
2063 };
2064 let mut raw = vec![0u8; SaffireAmplifierProtocol::OFFSETS.len() * 4];
2065 SaffireAmplifierProtocol::serialize(¶ms, &mut raw);
2066 let mut p = SaffireAmplifierParameters::default();
2067 SaffireAmplifierProtocol::deserialize(&mut p, &raw);
2068
2069 assert_eq!(params, p);
2070 }
2071
2072 #[test]
2073 fn saffire_ch_strip_protocol_serdes() {
2074 let params = SaffireChStripParameters {
2075 paired_mode: SaffireMixerMode::StereoSeparated,
2076 comp_orders: [SaffireChStripCompOrder::Pre, SaffireChStripCompOrder::Post],
2077 };
2078 let mut raw = vec![0u8; SaffireChStripProtocol::OFFSETS.len() * 4];
2079 SaffireChStripProtocol::serialize(¶ms, &mut raw);
2080 let mut p = SaffireChStripParameters::default();
2081 SaffireChStripProtocol::deserialize(&mut p, &raw);
2082
2083 assert_eq!(params, p);
2084 }
2085
2086 #[test]
2087 fn saffire_le_specific_protocol_serdes() {
2088 let params = SaffireLeSpecificParameters {
2089 analog_input_2_3_high_gains: [true, false],
2090 };
2091 let mut raw = vec![0u8; SaffireLeSpecificProtocol::OFFSETS.len() * 4];
2092 SaffireLeSpecificProtocol::serialize(¶ms, &mut raw);
2093 let mut p = SaffireLeSpecificParameters::default();
2094 SaffireLeSpecificProtocol::deserialize(&mut p, &raw);
2095
2096 assert_eq!(params, p);
2097 }
2098
2099 #[test]
2100 fn saffire_le_mixer_low_rate_stream_src_pos() {
2101 [
2103 (0, 0, 2),
2104 (0, 1, 0),
2105 (0, 2, 3),
2106 (0, 3, 1),
2107 (1, 0, 18),
2108 (1, 1, 16),
2109 (1, 2, 19),
2110 (1, 3, 17),
2111 (2, 0, 6),
2112 (2, 1, 4),
2113 (2, 2, 7),
2114 (2, 3, 5),
2115 (3, 0, 22),
2116 (3, 1, 20),
2117 (3, 2, 23),
2118 (3, 3, 21),
2119 (4, 0, 10),
2120 (4, 1, 8),
2121 (4, 2, 11),
2122 (4, 3, 9),
2123 (5, 0, 26),
2124 (5, 1, 24),
2125 (5, 2, 27),
2126 (5, 3, 25),
2127 (6, 0, 14),
2128 (6, 1, 12),
2129 (6, 2, 15),
2130 (6, 3, 13),
2131 (7, 0, 30),
2132 (7, 1, 28),
2133 (7, 2, 31),
2134 (7, 3, 29),
2135 ]
2136 .iter()
2137 .for_each(|&(src_idx, dst_idx, expected)| {
2138 let idx = SaffireLeMixerLowRateProtocol::stream_src_pos(dst_idx, src_idx);
2139 assert_eq!(idx, expected, "{}-{}", dst_idx, src_idx);
2140 })
2141 }
2142
2143 #[test]
2144 fn saffire_le_mixer_low_rate_phys_src_pos() {
2145 [
2147 (0, 0, 34),
2148 (0, 1, 32),
2149 (0, 2, 35),
2150 (0, 3, 33),
2151 (1, 0, 46),
2152 (1, 1, 44),
2153 (1, 2, 47),
2154 (1, 3, 45),
2155 (2, 0, 38),
2156 (2, 1, 36),
2157 (2, 2, 39),
2158 (2, 3, 37),
2159 (3, 0, 50),
2160 (3, 1, 48),
2161 (3, 2, 51),
2162 (3, 3, 49),
2163 (4, 0, 42),
2164 (4, 1, 40),
2165 (4, 2, 43),
2166 (4, 3, 41),
2167 (5, 0, 54),
2168 (5, 1, 52),
2169 (5, 2, 55),
2170 (5, 3, 53),
2171 ]
2172 .iter()
2173 .for_each(|&(src_idx, dst_idx, expected)| {
2174 let idx = SaffireLeMixerLowRateProtocol::phys_src_pos(dst_idx, src_idx);
2175 assert_eq!(idx, expected, "{}-{}", dst_idx, src_idx);
2176 })
2177 }
2178
2179 #[test]
2180 fn saffire_le_mixer_middle_rate_monitor_pair_from_analog_input_pos() {
2181 [(0, 0), (1, 3), (2, 1), (3, 4), (4, 2), (5, 5)]
2183 .iter()
2184 .for_each(|&(src_idx, expected)| {
2185 let idx = SaffireLeMixerMiddleRateProtocol::monitor_analog_input_pos(0, src_idx);
2186 assert_eq!(idx, expected);
2187 });
2188 }
2189
2190 #[test]
2191 fn saffire_le_mixer_middle_rate_monitor_src_pos() {
2192 [(0, 6), (1, 9), (2, 12), (3, 15)]
2194 .iter()
2195 .for_each(|&(dst_idx, expected)| {
2196 let idx = SaffireLeMixerMiddleRateProtocol::mixer_monitor_src_pos(dst_idx, 0);
2197 assert_eq!(idx, expected);
2198 });
2199 }
2200
2201 #[test]
2202 fn saffire_le_mixer_middle_rate_mixer_stream_input_pos() {
2203 [
2205 (0, 0, 7),
2206 (0, 1, 8),
2207 (1, 0, 10),
2208 (1, 1, 11),
2209 (2, 0, 13),
2210 (2, 1, 14),
2211 (3, 0, 16),
2212 (3, 1, 17),
2213 ]
2214 .iter()
2215 .for_each(|&(dst_idx, src_idx, expected)| {
2216 let idx = SaffireLeMixerMiddleRateProtocol::mixer_stream_input_pos(dst_idx, src_idx);
2217 assert_eq!(idx, expected);
2218 });
2219 }
2220
2221 #[test]
2222 fn saffire_le_mixer_low_rate_protocol_serdes() {
2223 let mut params = SaffireLeMixerLowRateState::default();
2224
2225 params
2226 .phys_src_gains
2227 .iter_mut()
2228 .enumerate()
2229 .for_each(|(i, gains)| {
2230 gains
2231 .iter_mut()
2232 .enumerate()
2233 .for_each(|(j, gain)| *gain = (i * 100 + j) as i16);
2234 });
2235
2236 params
2237 .stream_src_gains
2238 .iter_mut()
2239 .enumerate()
2240 .for_each(|(i, gains)| {
2241 gains
2242 .iter_mut()
2243 .enumerate()
2244 .for_each(|(j, gain)| *gain = (i * 100 + j) as i16);
2245 });
2246
2247 params.spdif_out_src = SaffireLeSpdifOutputSource::MixerOutputPair67;
2248
2249 let mut raw = vec![0u8; SaffireLeMixerLowRateProtocol::OFFSETS.len() * 4];
2250 SaffireLeMixerLowRateProtocol::serialize(¶ms, &mut raw);
2251 let mut p = SaffireLeMixerLowRateState::default();
2252 SaffireLeMixerLowRateProtocol::deserialize(&mut p, &raw);
2253
2254 assert_eq!(params, p);
2255 }
2256
2257 #[test]
2258 fn saffire_le_mixer_middle_rate_protocol_serdes() {
2259 let mut params = SaffireLeMixerMiddleRateState::default();
2260
2261 params
2262 .monitor_src_phys_input_gains
2263 .iter_mut()
2264 .enumerate()
2265 .for_each(|(i, gain)| *gain = i as i16);
2266
2267 params
2268 .monitor_out_src_pair_gains
2269 .iter_mut()
2270 .enumerate()
2271 .for_each(|(i, gains)| {
2272 gains
2273 .iter_mut()
2274 .enumerate()
2275 .for_each(|(j, gain)| *gain = (i * 100 + j) as i16);
2276 });
2277
2278 params
2279 .stream_src_pair_gains
2280 .iter_mut()
2281 .enumerate()
2282 .for_each(|(i, gains)| {
2283 gains
2284 .iter_mut()
2285 .enumerate()
2286 .for_each(|(j, gain)| *gain = (i * 100 + j) as i16);
2287 });
2288
2289 params.spdif_out_src = SaffireLeSpdifOutputSource::MixerOutputPair67;
2290
2291 let mut raw = vec![0u8; SaffireLeMixerMiddleRateProtocol::OFFSETS.len() * 4];
2292 SaffireLeMixerMiddleRateProtocol::serialize(¶ms, &mut raw);
2293 let mut p = SaffireLeMixerMiddleRateState::default();
2294 SaffireLeMixerMiddleRateProtocol::deserialize(&mut p, &raw);
2295
2296 assert_eq!(params, p);
2297 }
2298}