firewire_dice_protocols/tcelectronic/shell/
k24d.rs

1// SPDX-License-Identifier: LGPL-3.0-or-later
2// Copyright (c) 2020 Takashi Sakamoto
3
4//! Protocol defined by TC Electronic for Konnekt 24d.
5//!
6//! The module includes structure, enumeration, and trait and its implementation for protocol
7//! defined by TC Electronic for Konnekt 24d.
8//!
9//! ## Diagram of internal signal flow
10//!
11//! ```text
12//!
13//! XLR input 1 ----or--+
14//! Phone input 1 --+   |
15//!                     +--> analog-input-1/2 --------------------------> stream-output-1/2
16//!                     |        |
17//! XLR input 2 ----or--+        |
18//! Phone input 2 --+            |
19//!                              |
20//! Phone input 3/4  -----------------------> analog-input-3/4 ---+-----> stream-output-3/4
21//!                              |                  |             |
22//!                        (internal mode)          |             |
23//!                              v                  |             |
24//!                         ++=========++           |             |
25//!                         || channel ||           |             |
26//!                    +--> || strip   || -------+-------------+--------> stream-output-5/6
27//!                    |    || effects ||        |  |          |  |
28//!           (plugin mode) ||   1/2   ||        |  |          |  |
29//!                    |    ++=========++        |  |          |  |
30//!                    |                         |  |          |  |
31//!                    |        ++=========++    |  |          |  |
32//! Coaxial input -----|------> || digital ||    |  |          |  |
33//!                    |        || input   || ---------+-------------+--> stream-output-9..16
34//! Optical input -----|------> || select  ||    |  |  |       |  |  |
35//!                    |        ++=========++    |  |  |       |  |  |
36//!                    |                     (internal mode)   |  |  |
37//!                    |                         v  v  v       |  |  |
38//!                    |                     ++============++  |  |  |
39//!                    |                     ||   12 x 2   ||  |  |  |
40//!                    |  +--(plugin mode)-> ||            || ----------> stream-output-7/8
41//!                    |  |                  ||   reverb   ||  |  |  |
42//!                    |  |                  ++============++  |  |  |
43//!                    |  |                         v          v  v  v
44//!                    |  |                     ++=====================++
45//!                    |  |                     ||       16 x 2        ||
46//! stream-input-1/2 --|--|-------------------> ||                     ||
47//!                    |  |                     ||       mixer         ||
48//!                    |  |                     ++=====================++
49//!                    |  |                                v
50//!                    |  |                         mixer-output-1/2 ---> analog-output-1/2
51//!                    |  |
52//! stream-input-3/4 --|--|---------------------------------------------> analog-output-3/4
53//!                    |  |
54//! stream-input-5/6 --+  |
55//!                       |
56//! stream-input-7/8 -----+
57//!
58//! stream-input-9..16 -------------------------------------------------> digital-output-1..8
59//!
60//! ```
61
62use super::*;
63
64/// Protocol implementation of Konnekt 24d.
65#[derive(Default, Debug)]
66pub struct K24dProtocol;
67
68impl TcatOperation for K24dProtocol {}
69
70impl TcatGlobalSectionSpecification for K24dProtocol {}
71
72/// Segment for knob. 0x0000..0x0027 (36 quads).
73pub type K24dKnobSegment = TcKonnektSegment<K24dKnob>;
74
75/// Segment for configuration. 0x0028..0x0073 (76 quads).
76pub type K24dConfigSegment = TcKonnektSegment<K24dConfig>;
77
78/// Segment for state of mixer. 0x0074..0x01cf (87 quads).
79pub type K24dMixerStateSegment = TcKonnektSegment<K24dMixerState>;
80
81/// Segment for state of reverb effect. 0x01d0..0x0213. (17 quads)
82pub type K24dReverbStateSegment = TcKonnektSegment<K24dReverbState>;
83
84/// Segment for states of channel strip effect. 0x0218..0x0337 (72 quads).
85pub type K24dChStripStatesSegment = TcKonnektSegment<K24dChStripStates>;
86
87// NOTE: Segment for tuner. 0x0338..0x033b (8 quads).
88
89/// Segment for mixer meter. 0x105c..0x10b7 (23 quads).
90pub type K24dMixerMeterSegment = TcKonnektSegment<K24dMixerMeter>;
91
92/// Segment for state of hardware. 0x100c..0x1027 (7 quads).
93pub type K24dHwStateSegment = TcKonnektSegment<K24dHwState>;
94
95/// Segment for meter of reverb effect. 0x10b8..0x010cf (6 quads).
96pub type K24dReverbMeterSegment = TcKonnektSegment<K24dReverbMeter>;
97
98/// Segment for meters of channel strip effect. 0x10d0..0x110b (15 quads).
99pub type K24dChStripMetersSegment = TcKonnektSegment<K24dChStripMeters>;
100
101macro_rules! segment_default {
102    ($p:ty, $t:ty) => {
103        impl Default for TcKonnektSegment<$t> {
104            fn default() -> Self {
105                Self {
106                    data: <$t>::default(),
107                    raw: vec![0; <$p as TcKonnektSegmentSerdes<$t>>::SIZE],
108                }
109            }
110        }
111    };
112}
113
114segment_default!(K24dProtocol, K24dKnob);
115segment_default!(K24dProtocol, K24dConfig);
116segment_default!(K24dProtocol, K24dMixerState);
117segment_default!(K24dProtocol, K24dReverbState);
118segment_default!(K24dProtocol, K24dChStripStates);
119segment_default!(K24dProtocol, K24dMixerMeter);
120segment_default!(K24dProtocol, K24dHwState);
121segment_default!(K24dProtocol, K24dReverbMeter);
122segment_default!(K24dProtocol, K24dChStripMeters);
123
124/// State of knob.
125#[derive(Debug, Copy, Clone, PartialEq, Eq)]
126pub struct K24dKnob {
127    /// Target of 1st knob.
128    pub knob0_target: ShellKnob0Target,
129    /// Target of 2nd knob.
130    pub knob1_target: ShellKnob1Target,
131    /// Loaded program number.
132    pub prog: TcKonnektLoadedProgram,
133}
134
135impl Default for K24dKnob {
136    fn default() -> Self {
137        Self {
138            knob0_target: K24dProtocol::KNOB0_TARGETS[0],
139            knob1_target: K24dProtocol::KNOB1_TARGETS[0],
140            prog: Default::default(),
141        }
142    }
143}
144
145impl ShellKnob0TargetSpecification for K24dProtocol {
146    const KNOB0_TARGETS: &'static [ShellKnob0Target] = &[
147        ShellKnob0Target::Analog0,
148        ShellKnob0Target::Analog1,
149        ShellKnob0Target::Analog2_3,
150        ShellKnob0Target::Configurable,
151    ];
152}
153
154impl ShellKnob1TargetSpecification for K24dProtocol {
155    const KNOB1_TARGETS: &'static [ShellKnob1Target] = &[
156        ShellKnob1Target::Digital0_1,
157        ShellKnob1Target::Digital2_3,
158        ShellKnob1Target::Digital4_5,
159        ShellKnob1Target::Digital6_7,
160        ShellKnob1Target::Stream,
161        ShellKnob1Target::Reverb,
162        ShellKnob1Target::Mixer,
163        ShellKnob1Target::TunerPitchTone,
164    ];
165}
166
167impl TcKonnektSegmentSerdes<K24dKnob> for K24dProtocol {
168    const NAME: &'static str = "knob";
169    const OFFSET: usize = 0x0004;
170    const SIZE: usize = SHELL_KNOB_SEGMENT_SIZE;
171
172    fn serialize(params: &K24dKnob, raw: &mut [u8]) -> Result<(), String> {
173        serialize_knob0_target::<K24dProtocol>(&params.knob0_target, &mut raw[..4])?;
174        serialize_knob1_target::<K24dProtocol>(&params.knob1_target, &mut raw[4..8])?;
175        serialize_loaded_program(&params.prog, &mut raw[8..12])?;
176        Ok(())
177    }
178
179    fn deserialize(params: &mut K24dKnob, raw: &[u8]) -> Result<(), String> {
180        deserialize_knob0_target::<K24dProtocol>(&mut params.knob0_target, &raw[..4])?;
181        deserialize_knob1_target::<K24dProtocol>(&mut params.knob1_target, &raw[4..8])?;
182        deserialize_loaded_program(&mut params.prog, &raw[8..12])?;
183        Ok(())
184    }
185}
186
187impl TcKonnektMutableSegmentOperation<K24dKnob> for K24dProtocol {}
188
189impl TcKonnektNotifiedSegmentOperation<K24dKnob> for K24dProtocol {
190    const NOTIFY_FLAG: u32 = SHELL_KNOB_NOTIFY_FLAG;
191}
192
193impl AsRef<ShellKnob0Target> for K24dKnob {
194    fn as_ref(&self) -> &ShellKnob0Target {
195        &self.knob0_target
196    }
197}
198
199impl AsMut<ShellKnob0Target> for K24dKnob {
200    fn as_mut(&mut self) -> &mut ShellKnob0Target {
201        &mut self.knob0_target
202    }
203}
204
205impl AsRef<ShellKnob1Target> for K24dKnob {
206    fn as_ref(&self) -> &ShellKnob1Target {
207        &self.knob1_target
208    }
209}
210
211impl AsMut<ShellKnob1Target> for K24dKnob {
212    fn as_mut(&mut self) -> &mut ShellKnob1Target {
213        &mut self.knob1_target
214    }
215}
216
217impl AsRef<TcKonnektLoadedProgram> for K24dKnob {
218    fn as_ref(&self) -> &TcKonnektLoadedProgram {
219        &self.prog
220    }
221}
222
223impl AsMut<TcKonnektLoadedProgram> for K24dKnob {
224    fn as_mut(&mut self) -> &mut TcKonnektLoadedProgram {
225        &mut self.prog
226    }
227}
228
229/// Configuration.
230#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
231pub struct K24dConfig {
232    /// Configuration for optical interface.
233    pub opt: ShellOptIfaceConfig,
234    /// Source of coaxial output.
235    pub coax_out_src: ShellCoaxOutPairSrc,
236    /// Source of analog output 3/4.
237    pub out_23_src: ShellPhysOutSrc,
238    /// Source of sampling clock at standalone mode.
239    pub standalone_src: ShellStandaloneClockSource,
240    /// Rate of sampling clock at standalone mode.
241    pub standalone_rate: TcKonnektStandaloneClockRate,
242}
243
244impl ShellStandaloneClockSpecification for K24dProtocol {
245    const STANDALONE_CLOCK_SOURCES: &'static [ShellStandaloneClockSource] = &[
246        ShellStandaloneClockSource::Optical,
247        ShellStandaloneClockSource::Coaxial,
248        ShellStandaloneClockSource::Internal,
249    ];
250}
251
252impl TcKonnektSegmentSerdes<K24dConfig> for K24dProtocol {
253    const NAME: &'static str = "configuration";
254    const OFFSET: usize = 0x0028;
255    const SIZE: usize = 76;
256
257    fn serialize(params: &K24dConfig, raw: &mut [u8]) -> Result<(), String> {
258        serialize_opt_iface_config(&params.opt, &mut raw[..12])?;
259        serialize_coax_out_pair_source(&params.coax_out_src, &mut raw[12..16])?;
260        serialize_phys_out_src(&params.out_23_src, &mut raw[16..20])?;
261        serialize_standalone_clock_source::<K24dProtocol>(
262            &params.standalone_src,
263            &mut raw[20..24],
264        )?;
265        serialize_standalone_clock_rate(&params.standalone_rate, &mut raw[24..28])?;
266        Ok(())
267    }
268
269    fn deserialize(params: &mut K24dConfig, raw: &[u8]) -> Result<(), String> {
270        deserialize_opt_iface_config(&mut params.opt, &raw[..12])?;
271        deserialize_coax_out_pair_source(&mut params.coax_out_src, &raw[12..16])?;
272        deserialize_phys_out_src(&mut params.out_23_src, &raw[16..20])?;
273        deserialize_standalone_clock_source::<K24dProtocol>(
274            &mut params.standalone_src,
275            &raw[20..24],
276        )?;
277        deserialize_standalone_clock_rate(&mut params.standalone_rate, &raw[24..28])?;
278        Ok(())
279    }
280}
281
282impl TcKonnektMutableSegmentOperation<K24dConfig> for K24dProtocol {}
283
284impl TcKonnektNotifiedSegmentOperation<K24dConfig> for K24dProtocol {
285    const NOTIFY_FLAG: u32 = SHELL_CONFIG_NOTIFY_FLAG;
286}
287
288impl AsRef<ShellOptIfaceConfig> for K24dConfig {
289    fn as_ref(&self) -> &ShellOptIfaceConfig {
290        &self.opt
291    }
292}
293
294impl AsMut<ShellOptIfaceConfig> for K24dConfig {
295    fn as_mut(&mut self) -> &mut ShellOptIfaceConfig {
296        &mut self.opt
297    }
298}
299
300impl AsRef<ShellCoaxOutPairSrc> for K24dConfig {
301    fn as_ref(&self) -> &ShellCoaxOutPairSrc {
302        &self.coax_out_src
303    }
304}
305
306impl AsMut<ShellCoaxOutPairSrc> for K24dConfig {
307    fn as_mut(&mut self) -> &mut ShellCoaxOutPairSrc {
308        &mut self.coax_out_src
309    }
310}
311
312impl AsRef<ShellStandaloneClockSource> for K24dConfig {
313    fn as_ref(&self) -> &ShellStandaloneClockSource {
314        &self.standalone_src
315    }
316}
317
318impl AsMut<ShellStandaloneClockSource> for K24dConfig {
319    fn as_mut(&mut self) -> &mut ShellStandaloneClockSource {
320        &mut self.standalone_src
321    }
322}
323
324impl AsRef<TcKonnektStandaloneClockRate> for K24dConfig {
325    fn as_ref(&self) -> &TcKonnektStandaloneClockRate {
326        &self.standalone_rate
327    }
328}
329
330impl AsMut<TcKonnektStandaloneClockRate> for K24dConfig {
331    fn as_mut(&mut self) -> &mut TcKonnektStandaloneClockRate {
332        &mut self.standalone_rate
333    }
334}
335
336/// State of mixer.
337#[derive(Debug, Clone, PartialEq, Eq)]
338pub struct K24dMixerState {
339    /// The common structure for state of mixer.
340    pub mixer: ShellMixerState,
341    /// The parameter of return from reverb effect.
342    pub reverb_return: ShellReverbReturn,
343    /// Whether to use channel strip effect as plugin. It results in output of channel strip effect
344    /// on tx stream.
345    pub use_ch_strip_as_plugin: bool,
346    /// Whether to use reverb effect at middle sampling rate (88.2/96.0 kHz).
347    pub use_reverb_at_mid_rate: bool,
348    /// Whether to use mixer function.
349    pub enabled: bool,
350}
351
352impl Default for K24dMixerState {
353    fn default() -> Self {
354        K24dMixerState {
355            mixer: K24dProtocol::create_mixer_state(),
356            reverb_return: Default::default(),
357            use_ch_strip_as_plugin: Default::default(),
358            use_reverb_at_mid_rate: Default::default(),
359            enabled: Default::default(),
360        }
361    }
362}
363
364impl ShellMixerStateSpecification for K24dProtocol {
365    const MONITOR_SRC_MAP: [Option<ShellMixerMonitorSrcType>; SHELL_MIXER_MONITOR_SRC_COUNT] = [
366        Some(ShellMixerMonitorSrcType::Stream),
367        None,
368        None,
369        None,
370        Some(ShellMixerMonitorSrcType::Analog),
371        Some(ShellMixerMonitorSrcType::Analog),
372        Some(ShellMixerMonitorSrcType::AdatSpdif),
373        Some(ShellMixerMonitorSrcType::Adat),
374        Some(ShellMixerMonitorSrcType::Adat),
375        Some(ShellMixerMonitorSrcType::AdatSpdif),
376    ];
377}
378
379impl TcKonnektSegmentSerdes<K24dMixerState> for K24dProtocol {
380    const NAME: &'static str = "mixer-state";
381    const OFFSET: usize = 0x0074;
382    const SIZE: usize = ShellMixerState::SIZE + 32;
383
384    fn serialize(params: &K24dMixerState, raw: &mut [u8]) -> Result<(), String> {
385        serialize_mixer_state::<K24dProtocol>(&params.mixer, raw)?;
386        serialize_reverb_return(&params.reverb_return, &mut raw[316..328])?;
387        serialize_bool(&params.use_ch_strip_as_plugin, &mut raw[328..332]);
388        serialize_bool(&params.use_reverb_at_mid_rate, &mut raw[332..336]);
389        serialize_bool(&params.enabled, &mut raw[340..344]);
390        Ok(())
391    }
392
393    fn deserialize(params: &mut K24dMixerState, raw: &[u8]) -> Result<(), String> {
394        deserialize_mixer_state::<K24dProtocol>(&mut params.mixer, raw)?;
395        deserialize_reverb_return(&mut params.reverb_return, &raw[316..328])?;
396        deserialize_bool(&mut params.use_ch_strip_as_plugin, &raw[328..332]);
397        deserialize_bool(&mut params.use_reverb_at_mid_rate, &raw[332..336]);
398        deserialize_bool(&mut params.enabled, &raw[340..344]);
399        Ok(())
400    }
401}
402
403impl TcKonnektMutableSegmentOperation<K24dMixerState> for K24dProtocol {}
404
405impl TcKonnektNotifiedSegmentOperation<K24dMixerState> for K24dProtocol {
406    const NOTIFY_FLAG: u32 = SHELL_MIXER_NOTIFY_FLAG;
407}
408
409impl AsRef<ShellMixerState> for K24dMixerState {
410    fn as_ref(&self) -> &ShellMixerState {
411        &self.mixer
412    }
413}
414
415impl AsMut<ShellMixerState> for K24dMixerState {
416    fn as_mut(&mut self) -> &mut ShellMixerState {
417        &mut self.mixer
418    }
419}
420
421impl AsRef<ShellReverbReturn> for K24dMixerState {
422    fn as_ref(&self) -> &ShellReverbReturn {
423        &self.reverb_return
424    }
425}
426
427impl AsMut<ShellReverbReturn> for K24dMixerState {
428    fn as_mut(&mut self) -> &mut ShellReverbReturn {
429        &mut self.reverb_return
430    }
431}
432
433/// Configuration for reverb effect.
434#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
435pub struct K24dReverbState(pub ReverbState);
436
437impl TcKonnektSegmentSerdes<K24dReverbState> for K24dProtocol {
438    const NAME: &'static str = "reverb-state";
439    const OFFSET: usize = 0x01d0;
440    const SIZE: usize = ReverbState::SIZE;
441
442    fn serialize(params: &K24dReverbState, raw: &mut [u8]) -> Result<(), String> {
443        serialize_reverb_state(&params.0, raw)
444    }
445
446    fn deserialize(params: &mut K24dReverbState, raw: &[u8]) -> Result<(), String> {
447        deserialize_reverb_state(&mut params.0, raw)
448    }
449}
450
451impl TcKonnektMutableSegmentOperation<K24dReverbState> for K24dProtocol {}
452
453impl TcKonnektNotifiedSegmentOperation<K24dReverbState> for K24dProtocol {
454    const NOTIFY_FLAG: u32 = SHELL_REVERB_NOTIFY_FLAG;
455}
456
457impl AsRef<ReverbState> for K24dReverbState {
458    fn as_ref(&self) -> &ReverbState {
459        &self.0
460    }
461}
462
463impl AsMut<ReverbState> for K24dReverbState {
464    fn as_mut(&mut self) -> &mut ReverbState {
465        &mut self.0
466    }
467}
468
469/// Configuration for channel strip effect.
470#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
471pub struct K24dChStripStates(pub [ChStripState; SHELL_CH_STRIP_COUNT]);
472
473impl TcKonnektSegmentSerdes<K24dChStripStates> for K24dProtocol {
474    const NAME: &'static str = "channel-strip-state";
475    const OFFSET: usize = 0x0218;
476    const SIZE: usize = ChStripState::SIZE * SHELL_CH_STRIP_COUNT + 4;
477
478    fn serialize(params: &K24dChStripStates, raw: &mut [u8]) -> Result<(), String> {
479        serialize_ch_strip_states(&params.0, raw)
480    }
481
482    fn deserialize(params: &mut K24dChStripStates, raw: &[u8]) -> Result<(), String> {
483        deserialize_ch_strip_states(&mut params.0, raw)
484    }
485}
486
487impl TcKonnektMutableSegmentOperation<K24dChStripStates> for K24dProtocol {}
488
489impl TcKonnektNotifiedSegmentOperation<K24dChStripStates> for K24dProtocol {
490    const NOTIFY_FLAG: u32 = SHELL_CH_STRIP_NOTIFY_FLAG;
491}
492
493impl AsRef<[ChStripState]> for K24dChStripStates {
494    fn as_ref(&self) -> &[ChStripState] {
495        &self.0
496    }
497}
498
499impl AsMut<[ChStripState]> for K24dChStripStates {
500    fn as_mut(&mut self) -> &mut [ChStripState] {
501        &mut self.0
502    }
503}
504
505/// Hardware state.
506#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
507pub struct K24dHwState(pub ShellHwState);
508
509impl TcKonnektSegmentSerdes<K24dHwState> for K24dProtocol {
510    const NAME: &'static str = "hardware-state";
511    const OFFSET: usize = 0x100c;
512    const SIZE: usize = ShellHwState::SIZE;
513
514    fn serialize(params: &K24dHwState, raw: &mut [u8]) -> Result<(), String> {
515        serialize_hw_state(&params.0, raw)
516    }
517
518    fn deserialize(params: &mut K24dHwState, raw: &[u8]) -> Result<(), String> {
519        deserialize_hw_state(&mut params.0, raw)
520    }
521}
522
523impl TcKonnektMutableSegmentOperation<K24dHwState> for K24dProtocol {}
524
525impl TcKonnektNotifiedSegmentOperation<K24dHwState> for K24dProtocol {
526    const NOTIFY_FLAG: u32 = SHELL_HW_STATE_NOTIFY_FLAG;
527}
528
529impl AsRef<ShellHwState> for K24dHwState {
530    fn as_ref(&self) -> &ShellHwState {
531        &self.0
532    }
533}
534
535impl AsMut<ShellHwState> for K24dHwState {
536    fn as_mut(&mut self) -> &mut ShellHwState {
537        &mut self.0
538    }
539}
540
541impl AsRef<FireWireLedState> for K24dHwState {
542    fn as_ref(&self) -> &FireWireLedState {
543        &self.0.firewire_led
544    }
545}
546
547impl AsMut<FireWireLedState> for K24dHwState {
548    fn as_mut(&mut self) -> &mut FireWireLedState {
549        &mut self.0.firewire_led
550    }
551}
552
553const K24D_METER_ANALOG_INPUT_COUNT: usize = 2;
554const K24D_METER_DIGITAL_INPUT_COUNT: usize = 2;
555
556/// Hardware metering for mixer function.
557#[derive(Debug, Clone, PartialEq, Eq)]
558pub struct K24dMixerMeter(pub ShellMixerMeter);
559
560impl Default for K24dMixerMeter {
561    fn default() -> Self {
562        K24dMixerMeter(K24dProtocol::create_meter_state())
563    }
564}
565
566impl ShellMixerMeterSpecification for K24dProtocol {
567    const ANALOG_INPUT_COUNT: usize = K24D_METER_ANALOG_INPUT_COUNT;
568    const DIGITAL_INPUT_COUNT: usize = K24D_METER_DIGITAL_INPUT_COUNT;
569}
570
571impl TcKonnektSegmentSerdes<K24dMixerMeter> for K24dProtocol {
572    const NAME: &'static str = "mixer-meter";
573    const OFFSET: usize = 0x105c;
574    const SIZE: usize = ShellMixerMeter::SIZE;
575
576    fn serialize(params: &K24dMixerMeter, raw: &mut [u8]) -> Result<(), String> {
577        serialize_mixer_meter::<K24dProtocol>(&params.0, raw)
578    }
579
580    fn deserialize(params: &mut K24dMixerMeter, raw: &[u8]) -> Result<(), String> {
581        deserialize_mixer_meter::<K24dProtocol>(&mut params.0, raw)
582    }
583}
584
585impl AsRef<ShellMixerMeter> for K24dMixerMeter {
586    fn as_ref(&self) -> &ShellMixerMeter {
587        &self.0
588    }
589}
590
591impl AsMut<ShellMixerMeter> for K24dMixerMeter {
592    fn as_mut(&mut self) -> &mut ShellMixerMeter {
593        &mut self.0
594    }
595}
596
597/// Hardware metering for reverb effect.
598#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
599pub struct K24dReverbMeter(pub ReverbMeter);
600
601impl TcKonnektSegmentSerdes<K24dReverbMeter> for K24dProtocol {
602    const NAME: &'static str = "reverb-meter";
603    const OFFSET: usize = 0x10b8;
604    const SIZE: usize = ReverbMeter::SIZE;
605
606    fn serialize(params: &K24dReverbMeter, raw: &mut [u8]) -> Result<(), String> {
607        serialize_reverb_meter(&params.0, raw)
608    }
609
610    fn deserialize(params: &mut K24dReverbMeter, raw: &[u8]) -> Result<(), String> {
611        deserialize_reverb_meter(&mut params.0, raw)
612    }
613}
614
615impl AsRef<ReverbMeter> for K24dReverbMeter {
616    fn as_ref(&self) -> &ReverbMeter {
617        &self.0
618    }
619}
620
621impl AsMut<ReverbMeter> for K24dReverbMeter {
622    fn as_mut(&mut self) -> &mut ReverbMeter {
623        &mut self.0
624    }
625}
626
627/// Hardware metering for channel strip effect.
628#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
629pub struct K24dChStripMeters(pub [ChStripMeter; SHELL_CH_STRIP_COUNT]);
630
631impl TcKonnektSegmentSerdes<K24dChStripMeters> for K24dProtocol {
632    const NAME: &'static str = "channel-strip-meter";
633    const OFFSET: usize = 0x10d0;
634    const SIZE: usize = ChStripMeter::SIZE * SHELL_CH_STRIP_COUNT + 4;
635
636    fn serialize(params: &K24dChStripMeters, raw: &mut [u8]) -> Result<(), String> {
637        serialize_ch_strip_meters(&params.0, raw)
638    }
639
640    fn deserialize(params: &mut K24dChStripMeters, raw: &[u8]) -> Result<(), String> {
641        deserialize_ch_strip_meters(&mut params.0, raw)
642    }
643}
644
645impl AsRef<[ChStripMeter]> for K24dChStripMeters {
646    fn as_ref(&self) -> &[ChStripMeter] {
647        &self.0
648    }
649}
650
651impl AsMut<[ChStripMeter]> for K24dChStripMeters {
652    fn as_mut(&mut self) -> &mut [ChStripMeter] {
653        &mut self.0
654    }
655}