1use {
140 super::{tcat::*, *},
141 std::ops::Range,
142};
143
144#[derive(Default, Debug)]
146pub struct Io14fwProtocol;
147
148impl TcatOperation for Io14fwProtocol {}
149
150impl TcatGlobalSectionSpecification for Io14fwProtocol {}
151
152impl AlesisOperation for Io14fwProtocol {}
153
154impl IofwMeterSpecification for Io14fwProtocol {
155 const ANALOG_INPUT_COUNT: usize = 4;
156 const DIGITAL_B_INPUT_COUNT: usize = 2;
157}
158
159impl IofwOutputSpecification for Io14fwProtocol {
160 const ANALOG_OUTPUT_COUNT: usize = 4;
161 const HAS_OPT_IFACE_B: bool = false;
162}
163
164impl IofwMixerSpecification for Io14fwProtocol {
165 const ANALOG_INPUT_PAIR_COUNT: usize = 2;
166 const DIGITAL_B_INPUT_PAIR_COUNT: usize = 1;
167}
168
169#[derive(Default, Debug)]
171pub struct Io26fwProtocol;
172
173impl TcatOperation for Io26fwProtocol {}
174
175impl TcatGlobalSectionSpecification for Io26fwProtocol {}
176
177impl AlesisOperation for Io26fwProtocol {}
178
179impl IofwMeterSpecification for Io26fwProtocol {
180 const ANALOG_INPUT_COUNT: usize = 8;
181 const DIGITAL_B_INPUT_COUNT: usize = 8;
182}
183
184impl IofwOutputSpecification for Io26fwProtocol {
185 const ANALOG_OUTPUT_COUNT: usize = 8;
186 const HAS_OPT_IFACE_B: bool = true;
187}
188
189impl IofwMixerSpecification for Io26fwProtocol {
190 const ANALOG_INPUT_PAIR_COUNT: usize = 4;
191 const DIGITAL_B_INPUT_PAIR_COUNT: usize = 4;
192}
193
194const BASE_OFFSET: usize = 0x00200000;
195
196const MIXER_PARAMS_OFFSET: usize = 0x0038;
197const MIXER_OUTPUT_VOLUME_OFFSET: usize = 0x0438;
199const METER_OFFSET: usize = 0x04c0;
205const OUT_LEVEL_OFFSET: usize = 0x0564;
208const KNOB_PARAMS_OFFSET: usize = 0x0574;
213const METER_SIZE: usize = 160;
217
218const MIXER_PARAMS_SIZE: usize = 0x454;
219const KNOB_PARAMS_SIZE: usize = 8;
226pub trait AlesisParametersSerdes<T> {
231 const NAME: &'static str;
233
234 const OFFSET_RANGES: &'static [Range<usize>];
236
237 fn serialize_params(params: &T, raw: &mut [u8]) -> Result<(), String>;
239
240 fn deserialize_params(params: &mut T, raw: &[u8]) -> Result<(), String>;
242}
243
244pub trait IofwMeterSpecification {
246 const ANALOG_INPUT_COUNT: usize;
248
249 const DIGITAL_B_INPUT_COUNT: usize;
251
252 const STREAM_INPUT_COUNT: usize = 8;
254
255 const DIGITAL_A_INPUT_COUNT: usize = 8;
257
258 const MIXER_OUTPUT_COUNT: usize = 8;
260
261 const LEVEL_MIN: i32 = 0;
263
264 const LEVEL_MAX: i32 = i16::MAX as i32;
266
267 fn create_meter_params() -> IofwMeterParams {
269 IofwMeterParams {
270 analog_inputs: vec![0; Self::ANALOG_INPUT_COUNT],
271 stream_inputs: [0; 8],
272 digital_a_inputs: [0; 8],
273 digital_b_inputs: vec![0; Self::DIGITAL_B_INPUT_COUNT],
274 mixer_outputs: [0; 8],
275 }
276 }
277}
278
279pub trait IofwOutputSpecification {
281 const ANALOG_OUTPUT_COUNT: usize;
283
284 const HAS_OPT_IFACE_B: bool;
286
287 fn create_output_params() -> IofwOutputParams {
289 IofwOutputParams {
290 nominal_levels: vec![Default::default(); Self::ANALOG_OUTPUT_COUNT],
291 digital_67_src: Default::default(),
292 spdif_out_src: Default::default(),
293 headphone2_3_out_src: Default::default(),
294 }
295 }
296}
297
298impl<O> AlesisMutableParametersOperation<IofwOutputParams> for O where
299 O: AlesisOperation + IofwOutputSpecification + AlesisParametersSerdes<IofwOutputParams>
300{
301}
302
303pub trait IofwMixerSpecification {
305 const ANALOG_INPUT_PAIR_COUNT: usize;
307
308 const DIGITAL_B_INPUT_PAIR_COUNT: usize;
310
311 const STREAM_INPUT_PAIR_COUNT: usize = 4;
313
314 const DIGITAL_A_INPUT_PAIR_COUNT: usize = 4;
316
317 const MIXER_OUTPUT_PAIR_COUNT: usize = 4;
319
320 const GAIN_MIN: i32 = 0;
322
323 const GAIN_MAX: i32 = 0x007fffff;
325
326 const VOLUME_MIN: u32 = 0;
328
329 const VOLUME_MAX: u32 = 0x100;
331
332 fn create_mixer_params() -> IofwMixerParams {
334 IofwMixerParams {
335 mixer_pairs: [
336 IofwMixerPair {
337 monitor_pair: IofwMonitorPair {
338 analog_input_pairs: vec![Default::default(); Self::ANALOG_INPUT_PAIR_COUNT],
339 digital_a_input_pairs: [Default::default(); 4],
340 digital_b_input_pairs: vec![
341 Default::default();
342 Self::DIGITAL_B_INPUT_PAIR_COUNT
343 ],
344 output_volumes: [Default::default(); 2],
345 output_mutes: [Default::default(); 2],
346 },
347 stream_inputs_to_left: [Default::default(); 8],
348 stream_inputs_to_right: [Default::default(); 8],
349 },
350 IofwMixerPair {
351 monitor_pair: IofwMonitorPair {
352 analog_input_pairs: vec![Default::default(); Self::ANALOG_INPUT_PAIR_COUNT],
353 digital_a_input_pairs: [Default::default(); 4],
354 digital_b_input_pairs: vec![
355 Default::default();
356 Self::DIGITAL_B_INPUT_PAIR_COUNT
357 ],
358 output_volumes: [Default::default(); 2],
359 output_mutes: [Default::default(); 2],
360 },
361 stream_inputs_to_left: [Default::default(); 8],
362 stream_inputs_to_right: [Default::default(); 8],
363 },
364 IofwMixerPair {
365 monitor_pair: IofwMonitorPair {
366 analog_input_pairs: vec![Default::default(); Self::ANALOG_INPUT_PAIR_COUNT],
367 digital_a_input_pairs: [Default::default(); 4],
368 digital_b_input_pairs: vec![
369 Default::default();
370 Self::DIGITAL_B_INPUT_PAIR_COUNT
371 ],
372 output_volumes: [Default::default(); 2],
373 output_mutes: [Default::default(); 2],
374 },
375 stream_inputs_to_left: [Default::default(); 8],
376 stream_inputs_to_right: [Default::default(); 8],
377 },
378 IofwMixerPair {
379 monitor_pair: IofwMonitorPair {
380 analog_input_pairs: vec![Default::default(); Self::ANALOG_INPUT_PAIR_COUNT],
381 digital_a_input_pairs: [Default::default(); 4],
382 digital_b_input_pairs: vec![
383 Default::default();
384 Self::DIGITAL_B_INPUT_PAIR_COUNT
385 ],
386 output_volumes: [Default::default(); 2],
387 output_mutes: [Default::default(); 2],
388 },
389 stream_inputs_to_left: [Default::default(); 8],
390 stream_inputs_to_right: [Default::default(); 8],
391 },
392 ],
393 master_knob: Default::default(),
394 blend_knob: Default::default(),
395 }
396 }
397}
398
399impl<O> AlesisMutableParametersOperation<IofwMixerParams> for O where
400 O: AlesisOperation + IofwMixerSpecification + AlesisParametersSerdes<IofwMixerParams>
401{
402}
403
404fn compute_params_size(ranges: &[Range<usize>]) -> usize {
405 ranges
406 .iter()
407 .fold(0usize, |size, range| size + range.end - range.start)
408}
409
410fn generate_err(name: &str, cause: &str, raw: &[u8]) -> Error {
411 let msg = format!("params: {}, cause: {}, raw: {:02x?}", name, cause, raw);
412 Error::new(GeneralProtocolError::VendorDependent, &msg)
413}
414
415pub trait AlesisOperation: TcatOperation {
417 fn read_params(
419 req: &FwReq,
420 node: &FwNode,
421 offset: usize,
422 raw: &mut [u8],
423 timeout_ms: u32,
424 ) -> Result<(), Error> {
425 Self::read(req, node, BASE_OFFSET + offset, raw, timeout_ms)
426 }
427
428 fn write_params(
430 req: &FwReq,
431 node: &FwNode,
432 offset: usize,
433 raw: &mut [u8],
434 timeout_ms: u32,
435 ) -> Result<(), Error> {
436 Self::write(req, node, BASE_OFFSET + offset, raw, timeout_ms)
437 }
438}
439
440pub trait AlesisParametersOperation<T>: AlesisOperation + AlesisParametersSerdes<T> {
442 fn cache_whole_params(
444 req: &FwReq,
445 node: &FwNode,
446 params: &mut T,
447 timeout_ms: u32,
448 ) -> Result<(), Error> {
449 let size = compute_params_size(Self::OFFSET_RANGES);
450 let mut raw = vec![0u8; size];
451
452 let mut pos = 0;
453
454 Self::OFFSET_RANGES.iter().try_for_each(|range| {
455 let size = range.end - range.start;
456 Self::read_params(
457 req,
458 node,
459 range.start,
460 &mut raw[pos..(pos + size)],
461 timeout_ms,
462 )
463 .map(|_| pos += size)
464 })?;
465
466 Self::deserialize_params(params, &raw)
467 .map_err(|cause| generate_err(Self::NAME, &cause, &raw))
468 }
469}
470
471impl<O: AlesisOperation + AlesisParametersSerdes<T>, T> AlesisParametersOperation<T> for O {}
472
473pub trait AlesisMutableParametersOperation<T>: AlesisOperation + AlesisParametersSerdes<T> {
475 fn update_partial_params(
477 req: &FwReq,
478 node: &FwNode,
479 params: &T,
480 prev: &mut T,
481 timeout_ms: u32,
482 ) -> Result<(), Error> {
483 let size = compute_params_size(Self::OFFSET_RANGES);
484
485 let mut new = vec![0u8; size];
486 let mut old = vec![0u8; size];
487 Self::serialize_params(params, &mut new)
488 .map_err(|cause| generate_err(Self::NAME, &cause, &new))?;
489 Self::serialize_params(prev, &mut old)
490 .map_err(|cause| generate_err(Self::NAME, &cause, &old))?;
491
492 let mut pos = 0;
493
494 Self::OFFSET_RANGES.iter().try_for_each(|range| {
495 let size = range.end - range.start;
496
497 if new[pos..(pos + size)] != old[pos..(pos + size)] {
498 (0..size).step_by(4).try_for_each(|offset| {
499 let p = pos + offset;
500 if new[p..(p + 4)] != old[p..(p + 4)] {
501 Self::write_params(
502 req,
503 node,
504 range.start + offset,
505 &mut new[p..(p + 4)],
506 timeout_ms,
507 )
508 } else {
509 Ok(())
510 }
511 })
512 } else {
513 Ok(())
514 }
515 .map(|_| pos += size)
516 })?;
517
518 Self::deserialize_params(prev, &new).map_err(|cause| generate_err(Self::NAME, &cause, &new))
519 }
520}
521
522pub trait AlesisFluctuatedParametersOperation<T>:
524 AlesisOperation + AlesisParametersSerdes<T>
525{
526 const FLUCTUATED_OFFSET_RANGES: &'static [Range<usize>];
528
529 fn cache_partial_params(
531 req: &FwReq,
532 node: &FwNode,
533 params: &mut T,
534 timeout_ms: u32,
535 ) -> Result<(), Error> {
536 let size = compute_params_size(Self::OFFSET_RANGES);
537
538 let mut raw = vec![0u8; size];
539 Self::serialize_params(params, &mut raw)
540 .map_err(|cause| generate_err(Self::NAME, &cause, &raw))?;
541
542 Self::FLUCTUATED_OFFSET_RANGES
543 .iter()
544 .try_for_each(|range| {
545 let mut pos = 0;
546 for r in Self::OFFSET_RANGES {
547 if !r.contains(&range.start) {
548 pos += r.end - r.start;
549 } else {
550 pos += range.start - r.start;
551 break;
552 }
553 }
554 assert!(
555 pos < size,
556 "Programming error. The offset range should be found."
557 );
558
559 let end = pos + range.end - range.start;
560 Self::read_params(req, node, range.start, &mut raw[pos..end], timeout_ms)
561 })
562 .and_then(|_| {
563 Self::deserialize_params(params, &raw)
564 .map_err(|cause| generate_err(Self::NAME, &cause, &raw))
565 })
566 }
567}
568
569#[derive(Default, Debug, Clone, PartialEq, Eq)]
571pub struct IofwMeterParams {
572 pub analog_inputs: Vec<i16>,
574 pub stream_inputs: [i16; 8],
576 pub digital_a_inputs: [i16; 8],
578 pub digital_b_inputs: Vec<i16>,
580 pub mixer_outputs: [i16; 8],
582}
583
584impl<O: IofwMeterSpecification> AlesisParametersSerdes<IofwMeterParams> for O {
585 const NAME: &'static str = "meter";
586
587 const OFFSET_RANGES: &'static [Range<usize>] = &[Range {
588 start: METER_OFFSET,
589 end: METER_OFFSET + METER_SIZE,
590 }];
591
592 fn serialize_params(params: &IofwMeterParams, raw: &mut [u8]) -> Result<(), String> {
593 [
594 (¶ms.analog_inputs[..], 0),
595 (¶ms.stream_inputs[..], 32),
596 (¶ms.digital_a_inputs[..], 64),
597 (¶ms.mixer_outputs[..], 128),
598 ]
599 .iter()
600 .for_each(|(levels, offset)| {
601 levels.iter().enumerate().for_each(|(i, &level)| {
602 let pos = *offset + i * 4;
603 let val = (level as i32) << 8;
604 raw[pos..(pos + 4)].copy_from_slice(&val.to_be_bytes());
605 });
606 });
607
608 params
609 .digital_b_inputs
610 .iter()
611 .rev()
612 .enumerate()
613 .for_each(|(i, &level)| {
614 let pos = 96 + (7 - i) * 4;
615 let val = (level as i32) << 8;
616 raw[pos..(pos + 4)].copy_from_slice(&val.to_be_bytes());
617 });
618
619 Ok(())
620 }
621
622 fn deserialize_params(params: &mut IofwMeterParams, raw: &[u8]) -> Result<(), String> {
623 [
624 (&mut params.analog_inputs[..], 0),
625 (&mut params.stream_inputs[..], 32),
626 (&mut params.digital_a_inputs[..], 64),
627 (&mut params.mixer_outputs[..], 128),
628 ]
629 .iter_mut()
630 .for_each(|(levels, offset)| {
631 levels.iter_mut().enumerate().for_each(|(i, level)| {
632 let pos = *offset + i * 4;
633 let mut val = 0i32;
634 deserialize_i32(&mut val, &raw[pos..(pos + 4)]);
635 *level = ((val & 0x00ffff00) >> 8) as i16;
636 });
637 });
638
639 params
640 .digital_b_inputs
641 .iter_mut()
642 .rev()
643 .enumerate()
644 .for_each(|(i, level)| {
645 let pos = 96 + (7 - i) * 4;
646 let mut val = 0i32;
647 deserialize_i32(&mut val, &raw[pos..(pos + 4)]);
648 *level = ((val & 0x00ffff00) >> 8) as i16;
649 });
650
651 Ok(())
652 }
653}
654
655#[derive(Default, Debug, Clone, PartialEq, Eq)]
657pub struct IofwOutputParams {
658 pub nominal_levels: Vec<NominalSignalLevel>,
660 pub digital_67_src: DigitalB67Src,
662 pub spdif_out_src: MixerOutPair,
664 pub headphone2_3_out_src: MixerOutPair,
666}
667
668#[derive(Debug, Copy, Clone, PartialEq, Eq)]
670pub enum NominalSignalLevel {
671 Consumer,
673 Professional,
675}
676
677impl Default for NominalSignalLevel {
678 fn default() -> Self {
679 NominalSignalLevel::Consumer
680 }
681}
682
683fn serialize_nominal_signal_levels(
684 levels: &[NominalSignalLevel],
685 raw: &mut [u8],
686) -> Result<(), String> {
687 assert!(raw.len() >= 4);
688
689 let val = levels
690 .iter()
691 .enumerate()
692 .filter(|(_, &level)| level == NominalSignalLevel::Professional)
693 .fold(0u32, |val, (i, _)| val | (1 << i));
694
695 serialize_u32(&val, raw);
696
697 Ok(())
698}
699
700fn deserialize_nominal_signal_levels(
701 levels: &mut [NominalSignalLevel],
702 raw: &[u8],
703) -> Result<(), String> {
704 assert!(raw.len() >= 4);
705
706 let mut val = 0u32;
707 deserialize_u32(&mut val, raw);
708
709 levels.iter_mut().enumerate().for_each(|(i, level)| {
710 *level = if val & (1 << i) > 0 {
711 NominalSignalLevel::Professional
712 } else {
713 NominalSignalLevel::Consumer
714 };
715 });
716
717 Ok(())
718}
719
720#[derive(Debug, Copy, Clone, PartialEq, Eq)]
722pub enum DigitalB67Src {
723 Spdif12,
725 Adat67,
727}
728
729impl Default for DigitalB67Src {
730 fn default() -> Self {
731 Self::Spdif12
732 }
733}
734
735fn serialize_digital_b67_src(src: &DigitalB67Src, raw: &mut [u8]) -> Result<(), String> {
736 assert!(raw.len() >= 4);
737
738 let val = match src {
739 DigitalB67Src::Spdif12 => 0,
740 DigitalB67Src::Adat67 => 1,
741 };
742 serialize_u32(&val, raw);
743
744 Ok(())
745}
746
747fn deserialize_digital_b67_src(src: &mut DigitalB67Src, raw: &[u8]) -> Result<(), String> {
748 assert!(raw.len() >= 4);
749
750 let mut val = 0u32;
751 deserialize_u32(&mut val, raw);
752
753 *src = match val {
754 0 => DigitalB67Src::Spdif12,
755 1 => DigitalB67Src::Adat67,
756 _ => Err(format!("Digital B 7/8 source not found for value: {}", val))?,
757 };
758
759 Ok(())
760}
761
762#[derive(Debug, Copy, Clone, PartialEq, Eq)]
764pub enum MixerOutPair {
765 Mixer01,
767 Mixer23,
769 Mixer45,
771 Mixer67,
773}
774
775impl Default for MixerOutPair {
776 fn default() -> Self {
777 Self::Mixer01
778 }
779}
780
781fn serialize_mixer_out_pair(pair: &MixerOutPair, raw: &mut [u8]) -> Result<(), String> {
782 assert!(raw.len() >= 4);
783
784 let val = match pair {
785 MixerOutPair::Mixer01 => 0,
786 MixerOutPair::Mixer23 => 1,
787 MixerOutPair::Mixer45 => 2,
788 MixerOutPair::Mixer67 => 3,
789 };
790 serialize_u32(&val, raw);
791
792 Ok(())
793}
794
795fn deserialize_mixer_out_pair(pair: &mut MixerOutPair, raw: &[u8]) -> Result<(), String> {
796 assert!(raw.len() >= 4);
797
798 let mut val = 0u32;
799 deserialize_u32(&mut val, raw);
800
801 *pair = match val {
802 0 => MixerOutPair::Mixer01,
803 1 => MixerOutPair::Mixer23,
804 2 => MixerOutPair::Mixer45,
805 3 => MixerOutPair::Mixer67,
806 _ => Err(format!("Mixer output pair not found for value: {}", val))?,
807 };
808
809 Ok(())
810}
811
812impl<O: IofwOutputSpecification> AlesisParametersSerdes<IofwOutputParams> for O {
813 const NAME: &'static str = "output-params";
814
815 const OFFSET_RANGES: &'static [Range<usize>] = &[Range {
816 start: OUT_LEVEL_OFFSET,
817 end: OUT_LEVEL_OFFSET + 16,
818 }];
819
820 fn serialize_params(params: &IofwOutputParams, raw: &mut [u8]) -> Result<(), String> {
821 serialize_nominal_signal_levels(¶ms.nominal_levels, &mut raw[..4])?;
822 serialize_digital_b67_src(¶ms.digital_67_src, &mut raw[4..8])?;
823 serialize_mixer_out_pair(¶ms.spdif_out_src, &mut raw[8..12])?;
824 serialize_mixer_out_pair(¶ms.headphone2_3_out_src, &mut raw[12..16])?;
825 Ok(())
826 }
827
828 fn deserialize_params(params: &mut IofwOutputParams, raw: &[u8]) -> Result<(), String> {
829 deserialize_nominal_signal_levels(&mut params.nominal_levels, &raw[..4])?;
830 deserialize_digital_b67_src(&mut params.digital_67_src, &raw[4..8])?;
831 deserialize_mixer_out_pair(&mut params.spdif_out_src, &raw[8..12])?;
832 deserialize_mixer_out_pair(&mut params.headphone2_3_out_src, &raw[12..16])?;
833 Ok(())
834 }
835}
836
837#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
839pub struct IofwMonitorPairSourcePair {
840 pub gain_to_left: [i32; 2],
843 pub gain_to_right: [i32; 2],
846 pub mutes: [bool; 2],
848 pub solos: [bool; 2],
850 pub link: bool,
852}
853
854#[derive(Debug, Clone, PartialEq, Eq)]
858pub struct IofwMonitorPair {
859 pub analog_input_pairs: Vec<IofwMonitorPairSourcePair>,
861 pub digital_a_input_pairs: [IofwMonitorPairSourcePair; 4],
863 pub digital_b_input_pairs: Vec<IofwMonitorPairSourcePair>,
865 pub output_volumes: [u32; 2],
867 pub output_mutes: [bool; 2],
869}
870
871#[derive(Debug, Clone, PartialEq, Eq)]
874pub struct IofwMixerPair {
875 pub monitor_pair: IofwMonitorPair,
877 pub stream_inputs_to_left: [i32; 8],
879 pub stream_inputs_to_right: [i32; 8],
881}
882
883#[derive(Debug, Clone, PartialEq, Eq)]
885pub struct IofwMixerParams {
886 pub mixer_pairs: [IofwMixerPair; 4],
888 pub blend_knob: u32,
890 pub master_knob: u32,
892}
893
894impl<O: IofwMixerSpecification> AlesisParametersSerdes<IofwMixerParams> for O {
895 const NAME: &'static str = "mixer";
896
897 const OFFSET_RANGES: &'static [Range<usize>] = &[
898 Range {
899 start: MIXER_PARAMS_OFFSET,
900 end: MIXER_PARAMS_OFFSET + MIXER_PARAMS_SIZE,
901 },
902 Range {
903 start: KNOB_PARAMS_OFFSET,
904 end: KNOB_PARAMS_OFFSET + KNOB_PARAMS_SIZE,
905 },
906 ];
907
908 fn serialize_params(params: &IofwMixerParams, raw: &mut [u8]) -> Result<(), String> {
909 params.mixer_pairs.iter().enumerate().for_each(|(i, srcs)| {
910 let mut mutes_val = 0u32;
911 let mut solos_val = 0u32;
912 let mut links_val = 0u32;
913
914 let digital_b_pos = 2 * (4 - Self::DIGITAL_B_INPUT_PAIR_COUNT);
915 [
916 (&srcs.monitor_pair.analog_input_pairs[..], 0),
917 (&srcs.monitor_pair.digital_a_input_pairs[..], 16),
918 (
919 &srcs.monitor_pair.digital_b_input_pairs[..],
920 24 + digital_b_pos,
921 ),
922 ]
923 .iter()
924 .for_each(|(pairs, offset)| {
925 pairs
926 .iter()
927 .flat_map(|pair| pair.gain_to_left.iter())
928 .enumerate()
929 .for_each(|(j, gain)| {
930 let mixer_index = i * 2;
931 let pos = 4 * (mixer_index * (8 + 8 + 8 + 8) + *offset + j);
932 serialize_i32(gain, &mut raw[pos..(pos + 4)]);
933 });
934
935 pairs
936 .iter()
937 .flat_map(|pair| pair.gain_to_right.iter())
938 .enumerate()
939 .for_each(|(j, gain)| {
940 let mixer_index = i * 2 + 1;
941 let pos = 4 * (mixer_index * (8 + 8 + 8 + 8) + *offset + j);
942 serialize_i32(gain, &mut raw[pos..(pos + 4)]);
943 });
944
945 pairs
946 .iter()
947 .flat_map(|pair| pair.mutes.iter())
948 .enumerate()
949 .filter(|(_, &mute)| mute)
950 .for_each(|(j, _)| mutes_val |= 1 << (*offset + j));
951
952 pairs
953 .iter()
954 .flat_map(|pair| pair.solos.iter())
955 .enumerate()
956 .filter(|(_, &solo)| solo)
957 .for_each(|(j, _)| solos_val |= 1 << (*offset + j));
958
959 pairs
960 .iter()
961 .enumerate()
962 .filter(|(_, &pair)| pair.link)
963 .for_each(|(j, _)| links_val |= 1 << (*offset / 2 + j));
964 });
965
966 let pos = 0x0420 + 4 * i;
967 serialize_u32(&mutes_val, &mut raw[pos..(pos + 4)]);
968
969 let pos = 0x0434 + 4 * i;
970 serialize_u32(&solos_val, &mut raw[pos..(pos + 4)]);
971
972 let pos = 0x0444 + 4 * i;
973 serialize_u32(&links_val, &mut raw[pos..(pos + 4)]);
974
975 [
976 &srcs.stream_inputs_to_left[..],
977 &srcs.stream_inputs_to_right[..],
978 ]
979 .iter()
980 .enumerate()
981 .for_each(|(j, gains)| {
982 gains.iter().enumerate().for_each(|(k, gain)| {
983 let mixer_index = i * 2 + j;
984 let pos = 4 * (mixer_index * (8 + 8 + 8 + 8) + 8 + k);
985 serialize_i32(gain, &mut raw[pos..(pos + 4)]);
986 });
987 });
988 });
989
990 params
991 .mixer_pairs
992 .iter()
993 .flat_map(|srcs| srcs.monitor_pair.output_volumes.iter())
994 .enumerate()
995 .for_each(|(i, vol)| {
996 let pos = 0x400 + 4 * i;
997 serialize_u32(vol, &mut raw[pos..(pos + 4)]);
998 });
999
1000 let mut val = 0u32;
1001 params
1002 .mixer_pairs
1003 .iter()
1004 .flat_map(|srcs| srcs.monitor_pair.output_mutes.iter())
1005 .enumerate()
1006 .filter(|(_, &mute)| mute)
1007 .for_each(|(i, _)| val |= 1 << i);
1008 serialize_u32(&val, &mut raw[0x430..0x434]);
1009
1010 serialize_u32(¶ms.blend_knob, &mut raw[0x454..0x458]);
1011 serialize_u32(¶ms.master_knob, &mut raw[0x458..0x45c]);
1012
1013 Ok(())
1014 }
1015
1016 fn deserialize_params(params: &mut IofwMixerParams, raw: &[u8]) -> Result<(), String> {
1017 params
1018 .mixer_pairs
1019 .iter_mut()
1020 .enumerate()
1021 .for_each(|(i, srcs)| {
1022 let digital_b_pos = 2 * (4 - Self::DIGITAL_B_INPUT_PAIR_COUNT);
1023
1024 let pos = 0x0420 + 4 * i;
1025 let mut mutes_val = 0u32;
1026 deserialize_u32(&mut mutes_val, &raw[pos..(pos + 4)]);
1027
1028 let pos = 0x0434 + 4 * i;
1029 let mut solos_val = 0u32;
1030 deserialize_u32(&mut solos_val, &raw[pos..(pos + 4)]);
1031
1032 let pos = 0x0444 + 4 * i;
1033 let mut links_val = 0u32;
1034 deserialize_u32(&mut links_val, &raw[pos..(pos + 4)]);
1035
1036 [
1037 (&mut srcs.monitor_pair.analog_input_pairs[..], 0),
1038 (&mut srcs.monitor_pair.digital_a_input_pairs[..], 16),
1039 (
1040 &mut srcs.monitor_pair.digital_b_input_pairs[..],
1041 24 + digital_b_pos,
1042 ),
1043 ]
1044 .iter_mut()
1045 .for_each(|(pairs, offset)| {
1046 pairs
1047 .iter_mut()
1048 .flat_map(|pair| pair.gain_to_left.iter_mut())
1049 .enumerate()
1050 .for_each(|(j, gain)| {
1051 let mixer_index = i * 2;
1052 let pos = 4 * (mixer_index * (8 + 8 + 8 + 8) + *offset + j);
1053 deserialize_i32(gain, &raw[pos..(pos + 4)]);
1054 });
1055
1056 pairs
1057 .iter_mut()
1058 .flat_map(|pair| pair.gain_to_right.iter_mut())
1059 .enumerate()
1060 .for_each(|(j, gain)| {
1061 let mixer_index = i * 2 + 1;
1062 let pos = 4 * (mixer_index * (8 + 8 + 8 + 8) + *offset + j);
1063 deserialize_i32(gain, &raw[pos..(pos + 4)]);
1064 });
1065
1066 pairs
1067 .iter_mut()
1068 .flat_map(|pair| pair.mutes.iter_mut())
1069 .enumerate()
1070 .for_each(|(j, mute)| *mute = mutes_val & (1 << (*offset + j)) > 0);
1071
1072 pairs
1073 .iter_mut()
1074 .flat_map(|pair| pair.solos.iter_mut())
1075 .enumerate()
1076 .for_each(|(j, solo)| *solo = solos_val & (1 << (*offset + j)) > 0);
1077
1078 pairs
1079 .iter_mut()
1080 .enumerate()
1081 .for_each(|(j, pair)| pair.link = links_val & (1 << (*offset / 2 + j)) > 0);
1082 });
1083
1084 [
1085 &mut srcs.stream_inputs_to_left[..],
1086 &mut srcs.stream_inputs_to_right[..],
1087 ]
1088 .iter_mut()
1089 .enumerate()
1090 .for_each(|(j, gains)| {
1091 gains.iter_mut().enumerate().for_each(|(k, gain)| {
1092 let mixer_index = i * 2 + j;
1093 let pos = 4 * (mixer_index * (8 + 8 + 8 + 8) + 8 + k);
1094 deserialize_i32(gain, &raw[pos..(pos + 4)]);
1095 });
1096 });
1097 });
1098
1099 params
1100 .mixer_pairs
1101 .iter_mut()
1102 .flat_map(|srcs| srcs.monitor_pair.output_volumes.iter_mut())
1103 .enumerate()
1104 .for_each(|(i, vol)| {
1105 let pos = 0x400 + 4 * i;
1106 deserialize_u32(vol, &raw[pos..(pos + 4)]);
1107 });
1108
1109 let mut val = 0u32;
1110 deserialize_u32(&mut val, &raw[0x430..0x434]);
1111 params
1112 .mixer_pairs
1113 .iter_mut()
1114 .flat_map(|srcs| srcs.monitor_pair.output_mutes.iter_mut())
1115 .enumerate()
1116 .for_each(|(i, mute)| *mute = val & (1 << i) > 0);
1117
1118 deserialize_u32(&mut params.blend_knob, &raw[0x454..0x458]);
1119 deserialize_u32(&mut params.master_knob, &raw[0x458..0x45c]);
1120
1121 Ok(())
1122 }
1123}
1124
1125impl<O: AlesisOperation + AlesisParametersSerdes<IofwMixerParams>>
1126 AlesisFluctuatedParametersOperation<IofwMixerParams> for O
1127{
1128 const FLUCTUATED_OFFSET_RANGES: &'static [Range<usize>] = &[
1129 Range {
1131 start: MIXER_OUTPUT_VOLUME_OFFSET,
1132 end: MIXER_OUTPUT_VOLUME_OFFSET + 8,
1133 },
1134 Range {
1135 start: KNOB_PARAMS_OFFSET,
1136 end: KNOB_PARAMS_OFFSET + KNOB_PARAMS_SIZE,
1137 },
1138 ];
1139}
1140
1141#[cfg(test)]
1142mod test {
1143 use super::*;
1144
1145 #[test]
1146 fn io14_meter_params_serdes() {
1147 let mut params = <Io14fwProtocol as IofwMeterSpecification>::create_meter_params();
1148 params
1149 .analog_inputs
1150 .iter_mut()
1151 .chain(params.stream_inputs.iter_mut())
1152 .chain(params.digital_a_inputs.iter_mut())
1153 .chain(params.digital_b_inputs.iter_mut())
1154 .chain(params.mixer_outputs.iter_mut())
1155 .enumerate()
1156 .for_each(|(i, level)| *level = i as i16);
1157
1158 let size = compute_params_size(
1159 <Io14fwProtocol as AlesisParametersSerdes<IofwMeterParams>>::OFFSET_RANGES,
1160 );
1161 let mut raw = vec![0u8; size];
1162 Io14fwProtocol::serialize_params(¶ms, &mut raw).unwrap();
1163
1164 let mut target = <Io14fwProtocol as IofwMeterSpecification>::create_meter_params();
1165 Io14fwProtocol::deserialize_params(&mut target, &raw).unwrap();
1166
1167 assert_eq!(params, target);
1168 }
1169
1170 #[test]
1171 fn io26_meter_params_serdes() {
1172 let mut params = <Io26fwProtocol as IofwMeterSpecification>::create_meter_params();
1173 params
1174 .analog_inputs
1175 .iter_mut()
1176 .chain(params.stream_inputs.iter_mut())
1177 .chain(params.digital_a_inputs.iter_mut())
1178 .chain(params.digital_b_inputs.iter_mut())
1179 .chain(params.mixer_outputs.iter_mut())
1180 .enumerate()
1181 .for_each(|(i, level)| *level = i as i16);
1182
1183 let size = compute_params_size(
1184 <Io14fwProtocol as AlesisParametersSerdes<IofwMeterParams>>::OFFSET_RANGES,
1185 );
1186 let mut raw = vec![0u8; size];
1187 Io26fwProtocol::serialize_params(¶ms, &mut raw).unwrap();
1188
1189 let mut target = <Io26fwProtocol as IofwMeterSpecification>::create_meter_params();
1190 Io26fwProtocol::deserialize_params(&mut target, &raw).unwrap();
1191
1192 assert_eq!(params, target);
1193 }
1194
1195 #[test]
1196 fn io14_output_params_serdes() {
1197 let mut params = <Io14fwProtocol as IofwOutputSpecification>::create_output_params();
1198 params
1199 .nominal_levels
1200 .iter_mut()
1201 .enumerate()
1202 .filter(|(i, _)| i % 2 > 0)
1203 .for_each(|(_, level)| *level = NominalSignalLevel::Professional);
1204 params.digital_67_src = DigitalB67Src::Spdif12;
1205 params.spdif_out_src = MixerOutPair::Mixer45;
1206 params.headphone2_3_out_src = MixerOutPair::Mixer67;
1207
1208 let size = compute_params_size(
1209 <Io14fwProtocol as AlesisParametersSerdes<IofwOutputParams>>::OFFSET_RANGES,
1210 );
1211 let mut raw = vec![0u8; size];
1212 Io14fwProtocol::serialize_params(¶ms, &mut raw).unwrap();
1213
1214 let mut target = <Io14fwProtocol as IofwOutputSpecification>::create_output_params();
1215 Io14fwProtocol::deserialize_params(&mut target, &raw).unwrap();
1216
1217 assert_eq!(params, target);
1218 }
1219
1220 #[test]
1221 fn io26_output_params_serdes() {
1222 let mut params = <Io26fwProtocol as IofwOutputSpecification>::create_output_params();
1223 params
1224 .nominal_levels
1225 .iter_mut()
1226 .enumerate()
1227 .filter(|(i, _)| i % 2 > 0)
1228 .for_each(|(_, level)| *level = NominalSignalLevel::Professional);
1229 params.digital_67_src = DigitalB67Src::Adat67;
1230 params.spdif_out_src = MixerOutPair::Mixer01;
1231 params.headphone2_3_out_src = MixerOutPair::Mixer23;
1232
1233 let size = compute_params_size(
1234 <Io14fwProtocol as AlesisParametersSerdes<IofwOutputParams>>::OFFSET_RANGES,
1235 );
1236 let mut raw = vec![0u8; size];
1237 Io26fwProtocol::serialize_params(¶ms, &mut raw).unwrap();
1238
1239 let mut target = <Io26fwProtocol as IofwOutputSpecification>::create_output_params();
1240 Io26fwProtocol::deserialize_params(&mut target, &raw).unwrap();
1241
1242 assert_eq!(params, target);
1243 }
1244
1245 #[test]
1246 fn io14fw_mixer_params_serdes() {
1247 let mut params = Io14fwProtocol::create_mixer_params();
1248 params.mixer_pairs.iter_mut().for_each(|mixer_pair| {
1249 mixer_pair
1250 .monitor_pair
1251 .analog_input_pairs
1252 .iter_mut()
1253 .chain(mixer_pair.monitor_pair.digital_a_input_pairs.iter_mut())
1254 .chain(mixer_pair.monitor_pair.digital_b_input_pairs.iter_mut())
1255 .flat_map(|pair| pair.gain_to_left.iter_mut())
1256 .enumerate()
1257 .for_each(|(i, gain)| *gain = 2 * i as i32);
1258 mixer_pair
1259 .monitor_pair
1260 .analog_input_pairs
1261 .iter_mut()
1262 .chain(mixer_pair.monitor_pair.digital_a_input_pairs.iter_mut())
1263 .chain(mixer_pair.monitor_pair.digital_b_input_pairs.iter_mut())
1264 .flat_map(|pair| pair.gain_to_right.iter_mut())
1265 .enumerate()
1266 .for_each(|(i, gain)| *gain = 1 + 2 * i as i32);
1267 [
1268 &mut mixer_pair.stream_inputs_to_left[..],
1269 &mut mixer_pair.stream_inputs_to_right[..],
1270 ]
1271 .iter_mut()
1272 .enumerate()
1273 .for_each(|(i, gains)| {
1274 gains
1275 .iter_mut()
1276 .enumerate()
1277 .for_each(|(j, gain)| *gain = (i * 8 + j) as i32);
1278 });
1279 mixer_pair
1280 .monitor_pair
1281 .analog_input_pairs
1282 .iter_mut()
1283 .chain(mixer_pair.monitor_pair.digital_a_input_pairs.iter_mut())
1284 .chain(mixer_pair.monitor_pair.digital_b_input_pairs.iter_mut())
1285 .flat_map(|pair| pair.mutes.iter_mut())
1286 .enumerate()
1287 .for_each(|(i, mute)| *mute = i % 2 > 0);
1288 mixer_pair
1289 .monitor_pair
1290 .analog_input_pairs
1291 .iter_mut()
1292 .chain(mixer_pair.monitor_pair.digital_a_input_pairs.iter_mut())
1293 .chain(mixer_pair.monitor_pair.digital_b_input_pairs.iter_mut())
1294 .flat_map(|pair| pair.solos.iter_mut())
1295 .enumerate()
1296 .for_each(|(i, solo)| *solo = i % 2 > 0);
1297 mixer_pair
1298 .monitor_pair
1299 .analog_input_pairs
1300 .iter_mut()
1301 .chain(mixer_pair.monitor_pair.digital_a_input_pairs.iter_mut())
1302 .chain(mixer_pair.monitor_pair.digital_b_input_pairs.iter_mut())
1303 .enumerate()
1304 .for_each(|(i, pair)| pair.link = i % 2 > 0);
1305 });
1306 params
1307 .mixer_pairs
1308 .iter_mut()
1309 .flat_map(|pair| pair.monitor_pair.output_volumes.iter_mut())
1310 .enumerate()
1311 .for_each(|(i, vol)| *vol = 3 * i as u32);
1312 params
1313 .mixer_pairs
1314 .iter_mut()
1315 .flat_map(|pair| pair.monitor_pair.output_mutes.iter_mut())
1316 .enumerate()
1317 .for_each(|(i, mute)| *mute = i % 2 > 0);
1318 params.master_knob = 111;
1319 params.blend_knob = 111;
1320
1321 let size = compute_params_size(
1322 <Io14fwProtocol as AlesisParametersSerdes<IofwMixerParams>>::OFFSET_RANGES,
1323 );
1324 let mut raw = vec![0u8; size];
1325 Io14fwProtocol::serialize_params(¶ms, &mut raw).unwrap();
1326
1327 let mut p = Io14fwProtocol::create_mixer_params();
1328 Io14fwProtocol::deserialize_params(&mut p, &raw).unwrap();
1329
1330 assert_eq!(params, p);
1331 }
1332
1333 #[test]
1334 fn io26fw_mixer_params_serdes() {
1335 let mut params = Io26fwProtocol::create_mixer_params();
1336 params.mixer_pairs.iter_mut().for_each(|mixer_pair| {
1337 mixer_pair
1338 .monitor_pair
1339 .analog_input_pairs
1340 .iter_mut()
1341 .chain(mixer_pair.monitor_pair.digital_a_input_pairs.iter_mut())
1342 .chain(mixer_pair.monitor_pair.digital_b_input_pairs.iter_mut())
1343 .flat_map(|pair| pair.gain_to_left.iter_mut())
1344 .enumerate()
1345 .for_each(|(i, gain)| *gain = 2 * i as i32);
1346 mixer_pair
1347 .monitor_pair
1348 .analog_input_pairs
1349 .iter_mut()
1350 .chain(mixer_pair.monitor_pair.digital_a_input_pairs.iter_mut())
1351 .chain(mixer_pair.monitor_pair.digital_b_input_pairs.iter_mut())
1352 .flat_map(|pair| pair.gain_to_right.iter_mut())
1353 .enumerate()
1354 .for_each(|(i, gain)| *gain = 1 + 2 * i as i32);
1355 [
1356 &mut mixer_pair.stream_inputs_to_left[..],
1357 &mut mixer_pair.stream_inputs_to_right[..],
1358 ]
1359 .iter_mut()
1360 .enumerate()
1361 .for_each(|(i, gains)| {
1362 gains
1363 .iter_mut()
1364 .enumerate()
1365 .for_each(|(j, gain)| *gain = (i * 8 + j) as i32);
1366 });
1367 mixer_pair
1368 .monitor_pair
1369 .analog_input_pairs
1370 .iter_mut()
1371 .chain(mixer_pair.monitor_pair.digital_a_input_pairs.iter_mut())
1372 .chain(mixer_pair.monitor_pair.digital_b_input_pairs.iter_mut())
1373 .flat_map(|pair| pair.mutes.iter_mut())
1374 .enumerate()
1375 .for_each(|(i, mute)| *mute = i % 2 > 0);
1376 mixer_pair
1377 .monitor_pair
1378 .analog_input_pairs
1379 .iter_mut()
1380 .chain(mixer_pair.monitor_pair.digital_a_input_pairs.iter_mut())
1381 .chain(mixer_pair.monitor_pair.digital_b_input_pairs.iter_mut())
1382 .flat_map(|pair| pair.solos.iter_mut())
1383 .enumerate()
1384 .for_each(|(i, solo)| *solo = i % 2 > 0);
1385 mixer_pair
1386 .monitor_pair
1387 .analog_input_pairs
1388 .iter_mut()
1389 .chain(mixer_pair.monitor_pair.digital_a_input_pairs.iter_mut())
1390 .chain(mixer_pair.monitor_pair.digital_b_input_pairs.iter_mut())
1391 .enumerate()
1392 .for_each(|(i, pair)| pair.link = i % 2 > 0);
1393 });
1394 params
1395 .mixer_pairs
1396 .iter_mut()
1397 .flat_map(|pair| pair.monitor_pair.output_volumes.iter_mut())
1398 .enumerate()
1399 .for_each(|(i, vol)| *vol = 3 * i as u32);
1400 params
1401 .mixer_pairs
1402 .iter_mut()
1403 .flat_map(|pair| pair.monitor_pair.output_mutes.iter_mut())
1404 .enumerate()
1405 .for_each(|(i, mute)| *mute = i % 2 > 0);
1406 params.master_knob = 111;
1407 params.blend_knob = 111;
1408 let size = compute_params_size(
1409 <Io26fwProtocol as AlesisParametersSerdes<IofwMixerParams>>::OFFSET_RANGES,
1410 );
1411 let mut raw = vec![0u8; size];
1412 Io26fwProtocol::serialize_params(¶ms, &mut raw).unwrap();
1413
1414 let mut p = Io26fwProtocol::create_mixer_params();
1415 Io26fwProtocol::deserialize_params(&mut p, &raw).unwrap();
1416
1417 assert_eq!(params, p);
1418 }
1419}