1pub mod ff400;
7pub mod ff800;
8
9use super::*;
10
11pub trait RmeFfFormerSpecification {
13 const ANALOG_INPUT_COUNT: usize;
15 const SPDIF_INPUT_COUNT: usize;
17 const ADAT_INPUT_COUNT: usize;
19 const STREAM_INPUT_COUNT: usize;
21
22 const ANALOG_OUTPUT_COUNT: usize;
24 const SPDIF_OUTPUT_COUNT: usize;
26 const ADAT_OUTPUT_COUNT: usize;
28
29 const PHYS_INPUT_COUNT: usize =
31 Self::ANALOG_INPUT_COUNT + Self::SPDIF_INPUT_COUNT + Self::ADAT_INPUT_COUNT;
32 const PHYS_OUTPUT_COUNT: usize =
34 Self::ANALOG_OUTPUT_COUNT + Self::SPDIF_OUTPUT_COUNT + Self::ADAT_OUTPUT_COUNT;
35}
36
37#[derive(Default, Debug, Clone, PartialEq, Eq)]
42pub struct FormerMeterState {
43 pub analog_inputs: Vec<i32>,
45 pub spdif_inputs: Vec<i32>,
47 pub adat_inputs: Vec<i32>,
49 pub stream_inputs: Vec<i32>,
51 pub analog_outputs: Vec<i32>,
53 pub spdif_outputs: Vec<i32>,
55 pub adat_outputs: Vec<i32>,
57}
58
59pub trait RmeFfFormerMeterSpecification: RmeFfFormerSpecification {
61 const METER_OFFSET: u64;
62
63 const LEVEL_MIN: i32 = 0x00000000;
64 const LEVEL_MAX: i32 = 0x7fffff00;
65 const LEVEL_STEP: i32 = 0x100;
66
67 fn create_meter_state() -> FormerMeterState {
68 FormerMeterState {
69 analog_inputs: vec![0; Self::ANALOG_INPUT_COUNT],
70 spdif_inputs: vec![0; Self::SPDIF_INPUT_COUNT],
71 adat_inputs: vec![0; Self::ADAT_INPUT_COUNT],
72 stream_inputs: vec![0; Self::STREAM_INPUT_COUNT],
73 analog_outputs: vec![0; Self::ANALOG_OUTPUT_COUNT],
74 spdif_outputs: vec![0; Self::SPDIF_OUTPUT_COUNT],
75 adat_outputs: vec![0; Self::ADAT_OUTPUT_COUNT],
76 }
77 }
78}
79
80const METER_LEVEL_MASK: i32 = 0x7fffff00;
81
82fn serialize_meter(
85 params: &FormerMeterState,
86 phys_input_count: usize,
87 stream_input_count: usize,
88 phys_output_count: usize,
89) -> Vec<u8> {
90 let offset = 4 * (phys_input_count + stream_input_count + phys_output_count) * 2;
91 let mut raw = vec![0; offset];
92 raw.reserve(
93 params.analog_inputs.len()
94 + params.spdif_inputs.len()
95 + params.stream_inputs.len()
96 + params.analog_outputs.len()
97 + params.spdif_outputs.len()
98 + params.adat_outputs.len(),
99 );
100 params
101 .analog_inputs
102 .iter()
103 .chain(params.spdif_inputs.iter())
104 .chain(params.adat_inputs.iter())
105 .chain(params.stream_inputs.iter())
106 .chain(params.analog_outputs.iter())
107 .chain(params.spdif_outputs.iter())
108 .chain(params.adat_outputs.iter())
109 .for_each(|meter| {
110 raw.extend_from_slice(&(meter & METER_LEVEL_MASK).to_le_bytes());
111 });
112 raw
113}
114
115fn deserialize_meter(
116 params: &mut FormerMeterState,
117 raw: &[u8],
118 phys_input_count: usize,
119 stream_input_count: usize,
120 phys_output_count: usize,
121) {
122 let mut quadlet = [0; 4];
124 let offset = 4 * (phys_input_count + stream_input_count + phys_output_count) * 2;
125 params
126 .analog_inputs
127 .iter_mut()
128 .chain(params.spdif_inputs.iter_mut())
129 .chain(params.adat_inputs.iter_mut())
130 .chain(params.stream_inputs.iter_mut())
131 .chain(params.analog_outputs.iter_mut())
132 .chain(params.spdif_outputs.iter_mut())
133 .chain(params.adat_outputs.iter_mut())
134 .enumerate()
135 .for_each(|(i, meter)| {
136 let pos = offset + i * 4;
137 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
138 *meter = i32::from_le_bytes(quadlet) & METER_LEVEL_MASK;
139 });
140}
141
142impl<O: RmeFfFormerSpecification> RmeFfOffsetParamsSerialize<FormerMeterState> for O {
143 fn serialize_offsets(params: &FormerMeterState) -> Vec<u8> {
144 serialize_meter(
145 params,
146 Self::PHYS_INPUT_COUNT,
147 Self::STREAM_INPUT_COUNT,
148 Self::PHYS_OUTPUT_COUNT,
149 )
150 }
151}
152
153impl<O: RmeFfFormerMeterSpecification> RmeFfOffsetParamsDeserialize<FormerMeterState> for O {
154 fn deserialize_offsets(params: &mut FormerMeterState, raw: &[u8]) {
155 deserialize_meter(
156 params,
157 raw,
158 Self::PHYS_INPUT_COUNT,
159 Self::STREAM_INPUT_COUNT,
160 Self::PHYS_OUTPUT_COUNT,
161 );
162 }
163}
164
165impl<O: RmeFfFormerMeterSpecification + RmeFfOffsetParamsDeserialize<FormerMeterState>>
166 RmeFfCacheableParamsOperation<FormerMeterState> for O
167{
168 fn cache_wholly(
169 req: &mut FwReq,
170 node: &mut FwNode,
171 params: &mut FormerMeterState,
172 timeout_ms: u32,
173 ) -> Result<(), Error> {
174 let length = 8 * (Self::PHYS_INPUT_COUNT + Self::PHYS_OUTPUT_COUNT * 2)
182 + 4 * (Self::PHYS_INPUT_COUNT + Self::STREAM_INPUT_COUNT + Self::PHYS_OUTPUT_COUNT);
183 let mut raw = vec![0; length];
184 req.transaction_sync(
185 node,
186 FwTcode::ReadBlockRequest,
187 Self::METER_OFFSET,
188 raw.len(),
189 &mut raw,
190 timeout_ms,
191 )
192 .map(|_| Self::deserialize_offsets(params, &raw))
193 }
194}
195
196#[derive(Default, Debug, Clone, PartialEq, Eq)]
201pub struct FormerOutputVolumeState(pub Vec<i32>);
202
203pub trait RmeFormerOutputSpecification: RmeFfFormerSpecification {
205 const VOL_MIN: i32 = 0x00000000;
206 const VOL_ZERO: i32 = 0x00008000;
207 const VOL_MAX: i32 = 0x00010000;
208 const VOL_STEP: i32 = 1;
209
210 fn create_output_volume_state() -> FormerOutputVolumeState {
211 FormerOutputVolumeState(vec![0; Self::PHYS_OUTPUT_COUNT])
212 }
213}
214
215impl<O: RmeFfFormerSpecification> RmeFormerOutputSpecification for O {}
216
217fn serialize_output_volumes(params: &FormerOutputVolumeState, phys_output_count: usize) -> Vec<u8> {
218 assert!(params.0.len() >= phys_output_count);
219
220 params.0.iter().flat_map(|vol| vol.to_le_bytes()).collect()
221}
222
223fn deserialize_output_volumes(
224 params: &mut FormerOutputVolumeState,
225 raw: &[u8],
226 phys_output_count: usize,
227) {
228 assert!(raw.len() >= phys_output_count * 4);
229
230 let mut quadlet = [0; 4];
231 params.0.iter_mut().enumerate().for_each(|(i, vol)| {
232 let pos = i * 4;
233 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
234 *vol = i32::from_le_bytes(quadlet);
235 });
236}
237
238impl<O: RmeFormerOutputSpecification> RmeFfOffsetParamsSerialize<FormerOutputVolumeState> for O {
239 fn serialize_offsets(params: &FormerOutputVolumeState) -> Vec<u8> {
240 serialize_output_volumes(params, Self::PHYS_OUTPUT_COUNT)
241 }
242}
243
244impl<O: RmeFormerOutputSpecification> RmeFfOffsetParamsDeserialize<FormerOutputVolumeState> for O {
245 fn deserialize_offsets(params: &mut FormerOutputVolumeState, raw: &[u8]) {
246 deserialize_output_volumes(params, raw, Self::PHYS_OUTPUT_COUNT)
247 }
248}
249
250#[derive(Default, Debug, Clone, PartialEq, Eq)]
255pub struct FormerMixerSrc {
256 pub analog_gains: Vec<i32>,
258 pub spdif_gains: Vec<i32>,
260 pub adat_gains: Vec<i32>,
262 pub stream_gains: Vec<i32>,
264}
265
266#[derive(Default, Debug, Clone, PartialEq, Eq)]
268pub struct FormerMixerState(pub Vec<FormerMixerSrc>);
269
270pub trait RmeFormerMixerSpecification: RmeFfFormerSpecification {
272 const MIXER_OFFSET: u64;
273 const AVAIL_COUNT: usize;
274
275 const DST_COUNT: usize =
276 Self::ANALOG_OUTPUT_COUNT + Self::SPDIF_OUTPUT_COUNT + Self::ADAT_OUTPUT_COUNT;
277
278 const GAIN_MIN: i32 = 0x00000000;
279 const GAIN_ZERO: i32 = 0x00008000;
280 const GAIN_MAX: i32 = 0x00010000;
281 const GAIN_STEP: i32 = 1;
282
283 fn create_mixer_state() -> FormerMixerState {
284 FormerMixerState(vec![
285 FormerMixerSrc {
286 analog_gains: vec![0; Self::ANALOG_INPUT_COUNT],
287 spdif_gains: vec![0; Self::SPDIF_INPUT_COUNT],
288 adat_gains: vec![0; Self::ADAT_INPUT_COUNT],
289 stream_gains: vec![0; Self::STREAM_INPUT_COUNT],
290 };
291 Self::DST_COUNT
292 ])
293 }
294}
295
296fn calculate_mixer_length(avail_count: usize) -> usize {
297 avail_count * 2 * 4
298}
299
300fn calculate_mixer_total_length(dst_count: usize, avail_count: usize) -> usize {
301 calculate_mixer_length(avail_count) * dst_count
302}
303
304fn serialize_mixer(params: &FormerMixerState, dst_count: usize, avail_count: usize) -> Vec<u8> {
305 let mut raw = vec![0; calculate_mixer_total_length(dst_count, avail_count)];
306
307 params.0.iter().enumerate().for_each(|(i, mixer)| {
308 mixer
309 .analog_gains
310 .iter()
311 .chain(mixer.spdif_gains.iter())
312 .chain(mixer.adat_gains.iter())
313 .enumerate()
314 .for_each(|(j, gain)| {
315 let pos = ((avail_count * 2) * i + j) * 4;
316 raw[pos..(pos + 4)].copy_from_slice(&gain.to_le_bytes());
317 });
318
319 mixer.stream_gains.iter().enumerate().for_each(|(j, gain)| {
320 let pos = ((avail_count * 2) * i + (avail_count + j)) * 4;
321 raw[pos..(pos + 4)].copy_from_slice(&gain.to_le_bytes());
322 });
323 });
324
325 raw
326}
327
328fn deserialize_mixer(
329 params: &mut FormerMixerState,
330 raw: &[u8],
331 dst_count: usize,
332 avail_count: usize,
333) {
334 assert!(raw.len() >= calculate_mixer_total_length(dst_count, avail_count));
335
336 let mut quadlet = [0; 4];
337 params.0.iter_mut().enumerate().for_each(|(i, mixer)| {
338 mixer
339 .analog_gains
340 .iter_mut()
341 .chain(mixer.spdif_gains.iter_mut())
342 .chain(mixer.adat_gains.iter_mut())
343 .enumerate()
344 .for_each(|(j, gain)| {
345 let pos = ((avail_count * 2) * i + j) * 4;
346 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
347 *gain = i32::from_le_bytes(quadlet)
348 });
349
350 mixer
351 .stream_gains
352 .iter_mut()
353 .enumerate()
354 .for_each(|(j, gain)| {
355 let pos = ((avail_count * 2) * i + (avail_count + j)) * 4;
356 quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
357 *gain = i32::from_le_bytes(quadlet)
358 });
359 });
360}
361
362impl<O: RmeFormerMixerSpecification> RmeFfOffsetParamsSerialize<FormerMixerState> for O {
363 fn serialize_offsets(params: &FormerMixerState) -> Vec<u8> {
364 serialize_mixer(params, Self::DST_COUNT, Self::AVAIL_COUNT)
365 }
366}
367
368impl<O: RmeFormerMixerSpecification> RmeFfOffsetParamsDeserialize<FormerMixerState> for O {
369 fn deserialize_offsets(params: &mut FormerMixerState, raw: &[u8]) {
370 deserialize_mixer(params, raw, Self::DST_COUNT, Self::AVAIL_COUNT)
371 }
372}
373
374impl<O> RmeFfWhollyUpdatableParamsOperation<FormerMixerState> for O
375where
376 O: RmeFormerMixerSpecification + RmeFfOffsetParamsDeserialize<FormerMixerState>,
377{
378 fn update_wholly(
379 req: &mut FwReq,
380 node: &mut FwNode,
381 params: &FormerMixerState,
382 timeout_ms: u32,
383 ) -> Result<(), Error> {
384 let mut raw = Self::serialize_offsets(params);
385
386 let mixer_length = calculate_mixer_length(Self::AVAIL_COUNT);
387
388 (0..(raw.len() / mixer_length)).try_for_each(|i| {
389 let pos = i * mixer_length;
390 req.transaction_sync(
391 node,
392 FwTcode::WriteBlockRequest,
393 Self::MIXER_OFFSET + pos as u64,
394 mixer_length,
395 &mut raw[pos..(pos + mixer_length)],
396 timeout_ms,
397 )
398 })
399 }
400}
401
402impl<O> RmeFfPartiallyUpdatableParamsOperation<FormerMixerState> for O
403where
404 O: RmeFormerMixerSpecification + RmeFfOffsetParamsDeserialize<FormerMixerState>,
405{
406 fn update_partially(
407 req: &mut FwReq,
408 node: &mut FwNode,
409 params: &mut FormerMixerState,
410 update: FormerMixerState,
411 timeout_ms: u32,
412 ) -> Result<(), Error> {
413 let old = Self::serialize_offsets(params);
414 let mut new = Self::serialize_offsets(&update);
415
416 let mixer_length = calculate_mixer_length(Self::AVAIL_COUNT);
417
418 (0..(new.len() / mixer_length))
419 .try_for_each(|i| {
420 let pos = i * mixer_length;
421 if new[pos..(pos + mixer_length)] != old[pos..(pos + mixer_length)] {
422 req.transaction_sync(
423 node,
424 FwTcode::WriteBlockRequest,
425 Self::MIXER_OFFSET + pos as u64,
426 mixer_length,
427 &mut new[pos..(pos + mixer_length)],
428 timeout_ms,
429 )
430 } else {
431 Ok(())
432 }
433 })
434 .map(|_| *params = update)
435 }
436}
437
438const FORMER_CONFIG_SIZE: usize = 12;
439
440fn write_config<T: RmeFfOffsetParamsSerialize<U>, U>(
441 req: &mut FwReq,
442 node: &mut FwNode,
443 offset: u64,
444 config: &U,
445 timeout_ms: u32,
446) -> Result<(), Error> {
447 let mut raw = T::serialize_offsets(config);
448
449 req.transaction_sync(
450 node,
451 FwTcode::WriteBlockRequest,
452 offset,
453 raw.len(),
454 &mut raw,
455 timeout_ms,
456 )
457}
458
459const FORMER_STATUS_SIZE: usize = 8;
460
461fn read_status<T: RmeFfOffsetParamsDeserialize<U>, U>(
462 req: &mut FwReq,
463 node: &mut FwNode,
464 offset: u64,
465 status: &mut U,
466 timeout_ms: u32,
467) -> Result<(), Error> {
468 let mut raw = [0; FORMER_STATUS_SIZE];
469 req.transaction_sync(
470 node,
471 FwTcode::ReadBlockRequest,
472 offset,
473 raw.len(),
474 &mut raw,
475 timeout_ms,
476 )
477 .map(|_| T::deserialize_offsets(status, &raw))
478}
479
480#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
482pub struct FormerSpdifOutput {
483 pub format: SpdifFormat,
485 pub emphasis: bool,
487 pub non_audio: bool,
489}
490
491#[derive(Debug, Copy, Clone, PartialEq, Eq)]
493pub enum FormerLineInNominalLevel {
494 Low,
495 Consumer,
497 Professional,
499}
500
501impl Default for FormerLineInNominalLevel {
502 fn default() -> Self {
503 Self::Low
504 }
505}
506
507#[cfg(test)]
508mod test {
509 use super::*;
510
511 #[test]
512 fn meter_serdes() {
513 let mut orig = FormerMeterState {
514 analog_inputs: vec![0, 1],
515 spdif_inputs: vec![2, 3],
516 adat_inputs: vec![4, 5],
517 stream_inputs: vec![6, 7],
518 analog_outputs: vec![8, 9],
519 spdif_outputs: vec![10, 11],
520 adat_outputs: vec![12, 13],
521 };
522 orig.analog_inputs
523 .iter_mut()
524 .chain(orig.spdif_inputs.iter_mut())
525 .chain(orig.adat_inputs.iter_mut())
526 .chain(orig.stream_inputs.iter_mut())
527 .chain(orig.analog_outputs.iter_mut())
528 .chain(orig.spdif_outputs.iter_mut())
529 .chain(orig.adat_outputs.iter_mut())
530 .for_each(|gain| *gain <<= 8);
531 let raw = serialize_meter(&orig, 6, 2, 6);
532 let mut target = FormerMeterState {
533 analog_inputs: vec![0; 2],
534 spdif_inputs: vec![0; 2],
535 adat_inputs: vec![0; 2],
536 stream_inputs: vec![0; 2],
537 analog_outputs: vec![0; 2],
538 spdif_outputs: vec![0; 2],
539 adat_outputs: vec![0; 2],
540 };
541 deserialize_meter(&mut target, &raw, 6, 2, 6);
542
543 assert_eq!(target, orig);
544 }
545
546 #[test]
547 fn mixer_serdes() {
548 let orig = FormerMixerState(vec![
549 FormerMixerSrc {
550 analog_gains: vec![0, 1],
551 spdif_gains: vec![2, 3],
552 adat_gains: vec![4, 5],
553 stream_gains: vec![6, 7],
554 },
555 FormerMixerSrc {
556 analog_gains: vec![8, 9],
557 spdif_gains: vec![10, 11],
558 adat_gains: vec![12, 13],
559 stream_gains: vec![14, 15],
560 },
561 ]);
562 let raw = serialize_mixer(&orig, 6, 8);
563 let mut target = FormerMixerState(vec![
564 FormerMixerSrc {
565 analog_gains: vec![0; 2],
566 spdif_gains: vec![0; 2],
567 adat_gains: vec![0; 2],
568 stream_gains: vec![0; 2],
569 },
570 FormerMixerSrc {
571 analog_gains: vec![0; 2],
572 spdif_gains: vec![0; 2],
573 adat_gains: vec![0; 2],
574 stream_gains: vec![0; 2],
575 },
576 ]);
577 deserialize_mixer(&mut target, &raw, 6, 8);
578
579 assert_eq!(target, orig);
580 }
581
582 #[test]
583 fn output_volume_serdes() {
584 let orig = FormerOutputVolumeState(vec![0, 1, 2, 3]);
585 let raw = serialize_output_volumes(&orig, 4);
586 let mut target = FormerOutputVolumeState(vec![0; 4]);
587 deserialize_output_volumes(&mut target, &raw, 4);
588
589 assert_eq!(target, orig);
590 }
591}