1use super::tcelectronic::*;
31
32const DESKTOP_HW_STATE_NOTIFY_FLAG: u32 = 0x00010000;
33const DESKTOP_CONFIG_NOTIFY_FLAG: u32 = 0x00020000;
34const DESKTOP_MIXER_STATE_NOTIFY_FLAG: u32 = 0x00040000;
35const DESKTOP_PANEL_NOTIFY_FLAG: u32 = 0x00080000;
36
37#[derive(Default, Debug)]
39pub struct Desktopk6Protocol;
40
41impl TcatOperation for Desktopk6Protocol {}
42
43impl TcatGlobalSectionSpecification for Desktopk6Protocol {}
44
45pub type Desktopk6HwStateSegment = TcKonnektSegment<DesktopHwState>;
47
48pub type Desktopk6ConfigSegment = TcKonnektSegment<DesktopConfig>;
50
51pub type Desktopk6MixerStateSegment = TcKonnektSegment<DesktopMixerState>;
53
54pub type Desktopk6PanelSegment = TcKonnektSegment<DesktopPanel>;
56
57pub type Desktopk6MeterSegment = TcKonnektSegment<DesktopMeter>;
59
60macro_rules! segment_default {
61 ($p:ty, $t:ty) => {
62 impl Default for TcKonnektSegment<$t> {
63 fn default() -> Self {
64 Self {
65 data: <$t>::default(),
66 raw: vec![0; <$p as TcKonnektSegmentSerdes<$t>>::SIZE],
67 }
68 }
69 }
70 };
71}
72
73segment_default!(Desktopk6Protocol, DesktopHwState);
74segment_default!(Desktopk6Protocol, DesktopConfig);
75segment_default!(Desktopk6Protocol, DesktopMixerState);
76segment_default!(Desktopk6Protocol, DesktopPanel);
77segment_default!(Desktopk6Protocol, DesktopMeter);
78
79#[derive(Debug, Copy, Clone, PartialEq, Eq)]
81pub enum MeterTarget {
82 Input,
84 Pre,
86 Post,
88}
89
90impl Default for MeterTarget {
91 fn default() -> Self {
92 Self::Input
93 }
94}
95
96const METER_TARGETS: &[MeterTarget] = &[MeterTarget::Input, MeterTarget::Pre, MeterTarget::Post];
97
98const METER_TARGET_LABEL: &str = "meter-target";
99
100fn serialize_meter_target(target: &MeterTarget, raw: &mut [u8]) -> Result<(), String> {
101 serialize_position(METER_TARGETS, target, raw, METER_TARGET_LABEL)
102}
103
104fn deserialize_meter_target(target: &mut MeterTarget, raw: &[u8]) -> Result<(), String> {
105 deserialize_position(METER_TARGETS, target, raw, METER_TARGET_LABEL)
106}
107
108#[derive(Debug, Copy, Clone, PartialEq, Eq)]
110pub enum InputScene {
111 MicInst,
113 DualInst,
115 StereoIn,
117}
118
119impl Default for InputScene {
120 fn default() -> Self {
121 Self::MicInst
122 }
123}
124
125const INPUT_SCENES: &[InputScene] = &[
126 InputScene::MicInst,
127 InputScene::DualInst,
128 InputScene::StereoIn,
129];
130
131const INPUT_SCENE_LABEL: &str = "inputscene";
132
133fn serialize_input_scene(scene: &InputScene, raw: &mut [u8]) -> Result<(), String> {
134 serialize_position(INPUT_SCENES, scene, raw, INPUT_SCENE_LABEL)
135}
136
137fn deserialize_input_scene(scene: &mut InputScene, raw: &[u8]) -> Result<(), String> {
138 deserialize_position(INPUT_SCENES, scene, raw, INPUT_SCENE_LABEL)
139}
140
141#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
143pub struct DesktopHwState {
144 pub meter_target: MeterTarget,
146 pub mixer_output_monaural: bool,
148 pub knob_assign_to_hp: bool,
150 pub mixer_output_dim_enabled: bool,
152 pub mixer_output_dim_volume: i32,
154 pub input_scene: InputScene,
156 pub reverb_to_master: bool,
158 pub reverb_to_hp: bool,
160 pub master_knob_backlight: bool,
162 pub mic_0_phantom: bool,
164 pub mic_0_boost: bool,
166}
167
168impl DesktopHwState {
169 const REVERB_TO_MAIN_MASK: u32 = 0x00000001;
170 const REVERB_TO_HP_MASK: u32 = 0x00000002;
171}
172
173impl TcKonnektSegmentSerdes<DesktopHwState> for Desktopk6Protocol {
174 const NAME: &'static str = "hardware-state";
175 const OFFSET: usize = 0x0008;
176 const SIZE: usize = 144;
177
178 fn serialize(params: &DesktopHwState, raw: &mut [u8]) -> Result<(), String> {
179 serialize_meter_target(¶ms.meter_target, &mut raw[..4])?;
180 serialize_bool(¶ms.mixer_output_monaural, &mut raw[4..8]);
181 serialize_bool(¶ms.knob_assign_to_hp, &mut raw[8..12]);
182 serialize_bool(¶ms.mixer_output_dim_enabled, &mut raw[12..16]);
183 serialize_i32(¶ms.mixer_output_dim_volume, &mut raw[16..20]);
184 serialize_input_scene(¶ms.input_scene, &mut raw[20..24])?;
185
186 let mut val = 0;
187 if params.reverb_to_master {
188 val |= DesktopHwState::REVERB_TO_MAIN_MASK;
189 }
190 if params.reverb_to_hp {
191 val |= DesktopHwState::REVERB_TO_HP_MASK;
192 }
193 serialize_u32(&val, &mut raw[28..32]);
194
195 serialize_bool(¶ms.master_knob_backlight, &mut raw[32..36]);
196 serialize_bool(¶ms.mic_0_phantom, &mut raw[52..56]);
197 serialize_bool(¶ms.mic_0_boost, &mut raw[56..60]);
198
199 Ok(())
200 }
201
202 fn deserialize(params: &mut DesktopHwState, raw: &[u8]) -> Result<(), String> {
203 deserialize_meter_target(&mut params.meter_target, &raw[..4])?;
204 deserialize_bool(&mut params.mixer_output_monaural, &raw[4..8]);
205 deserialize_bool(&mut params.knob_assign_to_hp, &raw[8..12]);
206 deserialize_bool(&mut params.mixer_output_dim_enabled, &raw[12..16]);
207 deserialize_i32(&mut params.mixer_output_dim_volume, &raw[16..20]);
208 deserialize_input_scene(&mut params.input_scene, &raw[20..24])?;
209
210 let mut val = 0;
211 deserialize_u32(&mut val, &raw[28..32]);
212 params.reverb_to_master = val & DesktopHwState::REVERB_TO_MAIN_MASK > 0;
213 params.reverb_to_hp = val & DesktopHwState::REVERB_TO_HP_MASK > 0;
214
215 deserialize_bool(&mut params.master_knob_backlight, &raw[32..36]);
216 deserialize_bool(&mut params.mic_0_phantom, &raw[52..56]);
217 deserialize_bool(&mut params.mic_0_boost, &raw[56..60]);
218
219 Ok(())
220 }
221}
222
223impl TcKonnektMutableSegmentOperation<DesktopHwState> for Desktopk6Protocol {}
224
225impl TcKonnektNotifiedSegmentOperation<DesktopHwState> for Desktopk6Protocol {
226 const NOTIFY_FLAG: u32 = DESKTOP_HW_STATE_NOTIFY_FLAG;
227}
228
229#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
231pub struct DesktopConfig {
232 pub standalone_rate: TcKonnektStandaloneClockRate,
234}
235
236impl TcKonnektSegmentSerdes<DesktopConfig> for Desktopk6Protocol {
237 const NAME: &'static str = "configuration";
238 const OFFSET: usize = 0x0098;
239 const SIZE: usize = 32;
240
241 fn serialize(params: &DesktopConfig, raw: &mut [u8]) -> Result<(), String> {
242 serialize_standalone_clock_rate(¶ms.standalone_rate, &mut raw[4..8])
243 }
244
245 fn deserialize(params: &mut DesktopConfig, raw: &[u8]) -> Result<(), String> {
246 deserialize_standalone_clock_rate(&mut params.standalone_rate, &raw[4..8])
247 }
248}
249
250impl TcKonnektMutableSegmentOperation<DesktopConfig> for Desktopk6Protocol {}
251
252impl TcKonnektNotifiedSegmentOperation<DesktopConfig> for Desktopk6Protocol {
253 const NOTIFY_FLAG: u32 = DESKTOP_CONFIG_NOTIFY_FLAG;
254}
255
256impl AsRef<TcKonnektStandaloneClockRate> for DesktopConfig {
257 fn as_ref(&self) -> &TcKonnektStandaloneClockRate {
258 &self.standalone_rate
259 }
260}
261
262impl AsMut<TcKonnektStandaloneClockRate> for DesktopConfig {
263 fn as_mut(&mut self) -> &mut TcKonnektStandaloneClockRate {
264 &mut self.standalone_rate
265 }
266}
267
268#[derive(Debug, Copy, Clone, PartialEq, Eq)]
270pub enum DesktopHpSrc {
271 Stream23,
273 Mixer01,
275}
276
277impl Default for DesktopHpSrc {
278 fn default() -> Self {
279 Self::Stream23
280 }
281}
282
283fn serialize_hp_src(src: &DesktopHpSrc, raw: &mut [u8]) -> Result<(), String> {
284 assert!(raw.len() >= 4);
285
286 let val = match src {
287 DesktopHpSrc::Stream23 => 0x05,
288 DesktopHpSrc::Mixer01 => 0x0b,
289 };
290
291 serialize_u32(&val, raw);
292
293 Ok(())
294}
295
296fn deserialize_hp_src(src: &mut DesktopHpSrc, raw: &[u8]) -> Result<(), String> {
297 assert!(raw.len() >= 4);
298
299 let mut val = 0u32;
300 deserialize_u32(&mut val, raw);
301
302 *src = match val {
303 0x05 => DesktopHpSrc::Stream23,
304 _ => DesktopHpSrc::Mixer01,
305 };
306
307 Ok(())
308}
309
310#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
312pub struct DesktopMixerState {
313 pub mic_inst_level: [i32; 2],
316 pub mic_inst_pan: [i32; 2],
318 pub mic_inst_send: [i32; 2],
321 pub dual_inst_level: [i32; 2],
324 pub dual_inst_pan: [i32; 2],
326 pub dual_inst_send: [i32; 2],
329 pub stereo_in_level: i32,
331 pub stereo_in_pan: i32,
333 pub stereo_in_send: i32,
335 pub hp_src: DesktopHpSrc,
337}
338
339impl TcKonnektSegmentSerdes<DesktopMixerState> for Desktopk6Protocol {
340 const NAME: &'static str = "mixer-state";
341 const OFFSET: usize = 0x00b8;
342 const SIZE: usize = 688;
343
344 fn serialize(params: &DesktopMixerState, raw: &mut [u8]) -> Result<(), String> {
345 serialize_i32(¶ms.mic_inst_level[0], &mut raw[12..16]);
346 serialize_i32(¶ms.mic_inst_pan[0], &mut raw[16..20]);
347 serialize_i32(¶ms.mic_inst_send[0], &mut raw[20..24]);
348 serialize_i32(¶ms.mic_inst_level[1], &mut raw[28..32]);
349 serialize_i32(¶ms.mic_inst_pan[1], &mut raw[32..36]);
350 serialize_i32(¶ms.mic_inst_send[1], &mut raw[40..44]);
351
352 serialize_i32(¶ms.dual_inst_level[0], &mut raw[228..232]);
353 serialize_i32(¶ms.dual_inst_pan[0], &mut raw[232..236]);
354 serialize_i32(¶ms.dual_inst_send[0], &mut raw[240..244]);
355 serialize_i32(¶ms.dual_inst_level[1], &mut raw[248..252]);
356 serialize_i32(¶ms.dual_inst_pan[1], &mut raw[252..256]);
357 serialize_i32(¶ms.dual_inst_send[1], &mut raw[260..264]);
358
359 serialize_i32(¶ms.stereo_in_level, &mut raw[444..448]);
360 serialize_i32(¶ms.stereo_in_pan, &mut raw[448..452]);
361 serialize_i32(¶ms.stereo_in_send, &mut raw[452..456]);
362
363 serialize_hp_src(¶ms.hp_src, &mut raw[648..652])
364 }
365
366 fn deserialize(params: &mut DesktopMixerState, raw: &[u8]) -> Result<(), String> {
367 deserialize_i32(&mut params.mic_inst_level[0], &raw[12..16]);
368 deserialize_i32(&mut params.mic_inst_pan[0], &raw[16..20]);
369 deserialize_i32(&mut params.mic_inst_send[0], &raw[20..24]);
370 deserialize_i32(&mut params.mic_inst_level[1], &raw[28..32]);
371 deserialize_i32(&mut params.mic_inst_pan[1], &raw[32..36]);
372 deserialize_i32(&mut params.mic_inst_send[1], &raw[40..44]);
373
374 deserialize_i32(&mut params.dual_inst_level[0], &raw[228..232]);
375 deserialize_i32(&mut params.dual_inst_pan[0], &raw[232..236]);
376 deserialize_i32(&mut params.dual_inst_send[0], &raw[240..244]);
377 deserialize_i32(&mut params.dual_inst_level[1], &raw[248..252]);
378 deserialize_i32(&mut params.dual_inst_pan[1], &raw[252..256]);
379 deserialize_i32(&mut params.dual_inst_send[1], &raw[260..264]);
380
381 deserialize_i32(&mut params.stereo_in_level, &raw[444..448]);
382 deserialize_i32(&mut params.stereo_in_pan, &raw[448..452]);
383 deserialize_i32(&mut params.stereo_in_send, &raw[452..456]);
384
385 deserialize_hp_src(&mut params.hp_src, &raw[648..652])
386 }
387}
388
389impl TcKonnektMutableSegmentOperation<DesktopMixerState> for Desktopk6Protocol {}
390
391impl TcKonnektNotifiedSegmentOperation<DesktopMixerState> for Desktopk6Protocol {
392 const NOTIFY_FLAG: u32 = DESKTOP_MIXER_STATE_NOTIFY_FLAG;
393}
394
395#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
397pub struct DesktopPanel {
398 pub panel_button_count: u32,
400 pub main_knob_value: i32,
402 pub phone_knob_value: i32,
404 pub mix_knob_value: u32,
406 pub reverb_led_on: bool,
408 pub reverb_knob_value: i32,
410 pub firewire_led: FireWireLedState,
412}
413
414impl TcKonnektSegmentSerdes<DesktopPanel> for Desktopk6Protocol {
415 const NAME: &'static str = "hardware-panel";
416 const OFFSET: usize = 0x2008;
417 const SIZE: usize = 64;
418
419 fn serialize(params: &DesktopPanel, raw: &mut [u8]) -> Result<(), String> {
420 serialize_u32(¶ms.panel_button_count, &mut raw[..4]);
421 serialize_i32(¶ms.main_knob_value, &mut raw[4..8]);
422 serialize_i32(¶ms.phone_knob_value, &mut raw[8..12]);
423 serialize_u32(¶ms.mix_knob_value, &mut raw[12..16]);
424 serialize_bool(¶ms.reverb_led_on, &mut raw[16..20]);
425 serialize_i32(¶ms.reverb_knob_value, &mut raw[24..28]);
426 serialize_fw_led_state(¶ms.firewire_led, &mut raw[36..40])?;
427 Ok(())
428 }
429
430 fn deserialize(params: &mut DesktopPanel, raw: &[u8]) -> Result<(), String> {
431 deserialize_u32(&mut params.panel_button_count, &raw[..4]);
432 deserialize_i32(&mut params.main_knob_value, &raw[4..8]);
433 deserialize_i32(&mut params.phone_knob_value, &raw[8..12]);
434 deserialize_u32(&mut params.mix_knob_value, &raw[12..16]);
435 deserialize_bool(&mut params.reverb_led_on, &raw[16..20]);
436 deserialize_i32(&mut params.reverb_knob_value, &raw[24..28]);
437 deserialize_fw_led_state(&mut params.firewire_led, &raw[36..40])?;
438 Ok(())
439 }
440}
441
442impl TcKonnektMutableSegmentOperation<DesktopPanel> for Desktopk6Protocol {}
443
444impl TcKonnektNotifiedSegmentOperation<DesktopPanel> for Desktopk6Protocol {
445 const NOTIFY_FLAG: u32 = DESKTOP_PANEL_NOTIFY_FLAG;
446}
447
448impl AsRef<FireWireLedState> for DesktopPanel {
449 fn as_ref(&self) -> &FireWireLedState {
450 &self.firewire_led
451 }
452}
453
454impl AsMut<FireWireLedState> for DesktopPanel {
455 fn as_mut(&mut self) -> &mut FireWireLedState {
456 &mut self.firewire_led
457 }
458}
459
460#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
462pub struct DesktopMeter {
463 pub analog_inputs: [i32; 2],
464 pub mixer_outputs: [i32; 2],
465 pub stream_inputs: [i32; 2],
466}
467
468impl TcKonnektSegmentSerdes<DesktopMeter> for Desktopk6Protocol {
469 const NAME: &'static str = "hardware-meter";
470 const OFFSET: usize = 0x20e4;
471 const SIZE: usize = 92;
472
473 fn serialize(params: &DesktopMeter, raw: &mut [u8]) -> Result<(), String> {
474 serialize_i32(¶ms.analog_inputs[0], &mut raw[..4]);
475 serialize_i32(¶ms.analog_inputs[1], &mut raw[4..8]);
476 serialize_i32(¶ms.mixer_outputs[0], &mut raw[40..44]);
477 serialize_i32(¶ms.mixer_outputs[1], &mut raw[44..48]);
478 serialize_i32(¶ms.stream_inputs[0], &mut raw[48..52]);
479 serialize_i32(¶ms.stream_inputs[1], &mut raw[52..56]);
480 Ok(())
481 }
482
483 fn deserialize(params: &mut DesktopMeter, raw: &[u8]) -> Result<(), String> {
484 deserialize_i32(&mut params.analog_inputs[0], &raw[..4]);
485 deserialize_i32(&mut params.analog_inputs[1], &raw[4..8]);
486 deserialize_i32(&mut params.mixer_outputs[0], &raw[40..44]);
487 deserialize_i32(&mut params.mixer_outputs[1], &raw[44..48]);
488 deserialize_i32(&mut params.stream_inputs[0], &raw[48..52]);
489 deserialize_i32(&mut params.stream_inputs[1], &raw[52..56]);
490 Ok(())
491 }
492}