use super::{ch_strip::*, reverb::*, *};
#[derive(Default, Debug)]
pub struct Studiok48Protocol;
impl TcatOperation for Studiok48Protocol {}
impl TcatGlobalSectionSpecification for Studiok48Protocol {}
pub type Studiok48LineOutLevelSegment = TcKonnektSegment<StudioLineOutLevel>;
pub type Studiok48RemoteSegment = TcKonnektSegment<StudioRemote>;
pub type Studiok48ConfigSegment = TcKonnektSegment<StudioConfig>;
pub type Studiok48MixerStateSegment = TcKonnektSegment<StudioMixerState>;
pub type Studiok48PhysOutSegment = TcKonnektSegment<StudioPhysOut>;
pub type Studiok48ReverbStateSegment = TcKonnektSegment<StudioReverbState>;
pub type Studiok48ChStripStatesSegment = TcKonnektSegment<StudioChStripStates>;
pub type Studiok48HwStateSegment = TcKonnektSegment<StudioHwState>;
pub type Studiok48MixerMeterSegment = TcKonnektSegment<StudioMixerMeter>;
pub type Studiok48ReverbMeterSegment = TcKonnektSegment<StudioReverbMeter>;
pub type Studiok48ChStripMetersSegment = TcKonnektSegment<StudioChStripMeters>;
macro_rules! segment_default {
($p:ty, $t:ty) => {
impl Default for TcKonnektSegment<$t> {
fn default() -> Self {
Self {
data: <$t>::default(),
raw: vec![0; <$p as TcKonnektSegmentSerdes<$t>>::SIZE],
}
}
}
};
}
segment_default!(Studiok48Protocol, StudioLineOutLevel);
segment_default!(Studiok48Protocol, StudioRemote);
segment_default!(Studiok48Protocol, StudioConfig);
segment_default!(Studiok48Protocol, StudioMixerState);
segment_default!(Studiok48Protocol, StudioPhysOut);
segment_default!(Studiok48Protocol, StudioReverbState);
segment_default!(Studiok48Protocol, StudioChStripStates);
segment_default!(Studiok48Protocol, StudioHwState);
segment_default!(Studiok48Protocol, StudioMixerMeter);
segment_default!(Studiok48Protocol, StudioReverbMeter);
segment_default!(Studiok48Protocol, StudioChStripMeters);
const STUDIO_LINE_OUT_LEVEL_NOTIFY_FLAG: u32 = 0x00010000;
const STUDIO_REMOTE_NOTIFY_FLAG: u32 = 0x00020000;
const STUDIO_CONFIG_NOTIFY_FLAG: u32 = 0x00040000;
const STUDIO_MIXER_STATE_NOTIFY_FLAG: u32 = 0x00080000;
const STUDIO_PHYS_OUT_NOTIFY_FLAG: u32 = 0x00100000;
const STUDIO_REVERB_NOTIFY_CHANGE: u32 = 0x00200000;
const STUDIO_CH_STRIP_NOTIFY_01_CHANGE: u32 = 0x00400000;
const STUDIO_CH_STRIP_NOTIFY_23_CHANGE: u32 = 0x00800000;
const STUDIO_HW_STATE_NOTIFY_FLAG: u32 = 0x04000000;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum NominalSignalLevel {
Professional,
Consumer,
}
impl Default for NominalSignalLevel {
fn default() -> Self {
NominalSignalLevel::Professional
}
}
const NOMINAL_LEVELS: &[NominalSignalLevel] = &[
NominalSignalLevel::Professional,
NominalSignalLevel::Consumer,
];
const NOMINAL_LEVEL_LABEL: &str = "nominal level";
fn serialize_nominal_level(level: &NominalSignalLevel, raw: &mut [u8]) -> Result<(), String> {
serialize_position(NOMINAL_LEVELS, level, raw, NOMINAL_LEVEL_LABEL)
}
fn deserialize_nominal_level(level: &mut NominalSignalLevel, raw: &[u8]) -> Result<(), String> {
deserialize_position(NOMINAL_LEVELS, level, raw, NOMINAL_LEVEL_LABEL)
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct StudioLineOutLevel {
pub line_45: NominalSignalLevel,
pub line_67: NominalSignalLevel,
pub line_89: NominalSignalLevel,
pub line_1011: NominalSignalLevel,
}
impl TcKonnektSegmentSerdes<StudioLineOutLevel> for Studiok48Protocol {
const NAME: &'static str = "line-output-level";
const OFFSET: usize = 0x0000;
const SIZE: usize = 20;
fn serialize(params: &StudioLineOutLevel, raw: &mut [u8]) -> Result<(), String> {
serialize_nominal_level(¶ms.line_45, &mut raw[4..8])?;
serialize_nominal_level(¶ms.line_67, &mut raw[8..12])?;
serialize_nominal_level(¶ms.line_89, &mut raw[12..16])?;
serialize_nominal_level(¶ms.line_1011, &mut raw[16..20])?;
Ok(())
}
fn deserialize(params: &mut StudioLineOutLevel, raw: &[u8]) -> Result<(), String> {
deserialize_nominal_level(&mut params.line_45, &raw[4..8])?;
deserialize_nominal_level(&mut params.line_67, &raw[8..12])?;
deserialize_nominal_level(&mut params.line_89, &raw[12..16])?;
deserialize_nominal_level(&mut params.line_1011, &raw[16..20])?;
Ok(())
}
}
impl TcKonnektMutableSegmentOperation<StudioLineOutLevel> for Studiok48Protocol {}
impl TcKonnektNotifiedSegmentOperation<StudioLineOutLevel> for Studiok48Protocol {
const NOTIFY_FLAG: u32 = STUDIO_LINE_OUT_LEVEL_NOTIFY_FLAG;
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum RemoteEffectButtonMode {
Reverb,
Midi,
}
impl Default for RemoteEffectButtonMode {
fn default() -> Self {
Self::Reverb
}
}
const REMOTE_EFFECT_BUTTON_MODES: &[RemoteEffectButtonMode] =
&[RemoteEffectButtonMode::Reverb, RemoteEffectButtonMode::Midi];
const REMOTE_EFFECT_BUTTON_MODE_LABEL: &str = "remote effect button mode";
fn serialize_remote_effect_button_mode(
mode: &RemoteEffectButtonMode,
raw: &mut [u8],
) -> Result<(), String> {
serialize_position(
REMOTE_EFFECT_BUTTON_MODES,
mode,
raw,
REMOTE_EFFECT_BUTTON_MODE_LABEL,
)
}
fn deserialize_remote_effect_button_mode(
mode: &mut RemoteEffectButtonMode,
raw: &[u8],
) -> Result<(), String> {
deserialize_position(
REMOTE_EFFECT_BUTTON_MODES,
mode,
raw,
REMOTE_EFFECT_BUTTON_MODE_LABEL,
)
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum KnobPushMode {
Pan,
GainToReverb,
GainToAux0,
GainToAux1,
}
impl Default for KnobPushMode {
fn default() -> Self {
Self::Pan
}
}
const KNOB_PUSH_MODES: &[KnobPushMode] = &[
KnobPushMode::Pan,
KnobPushMode::GainToReverb,
KnobPushMode::GainToAux0,
KnobPushMode::GainToAux1,
];
const KNOB_PUSH_MODE_LABEL: &str = "knob push mode";
fn serialize_knob_push_mode(mode: &KnobPushMode, raw: &mut [u8]) -> Result<(), String> {
serialize_position(KNOB_PUSH_MODES, mode, raw, KNOB_PUSH_MODE_LABEL)
}
fn deserialize_knob_push_mode(mode: &mut KnobPushMode, raw: &[u8]) -> Result<(), String> {
deserialize_position(KNOB_PUSH_MODES, mode, raw, KNOB_PUSH_MODE_LABEL)
}
pub const STUDIO_REMOTE_USER_ASSIGN_COUNT: usize = 6;
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct StudioRemote {
pub prog: TcKonnektLoadedProgram,
pub user_assigns: [SrcEntry; STUDIO_REMOTE_USER_ASSIGN_COUNT],
pub effect_button_mode: RemoteEffectButtonMode,
pub fallback_to_master_enable: bool,
pub fallback_to_master_duration: u32,
pub knob_push_mode: KnobPushMode,
}
impl TcKonnektSegmentSerdes<StudioRemote> for Studiok48Protocol {
const NAME: &'static str = "remote-controller";
const OFFSET: usize = 0x0014;
const SIZE: usize = 48;
fn serialize(params: &StudioRemote, raw: &mut [u8]) -> Result<(), String> {
serialize_loaded_program(¶ms.prog, &mut raw[..4])?;
params
.user_assigns
.iter()
.enumerate()
.try_for_each(|(i, assign)| {
let pos = 4 + i * 4;
serialize_src_entry(assign, &mut raw[pos..(pos + 4)])
})?;
serialize_remote_effect_button_mode(¶ms.effect_button_mode, &mut raw[28..32])?;
serialize_bool(¶ms.fallback_to_master_enable, &mut raw[32..36]);
serialize_u32(¶ms.fallback_to_master_duration, &mut raw[36..40]);
serialize_knob_push_mode(¶ms.knob_push_mode, &mut raw[40..44])?;
Ok(())
}
fn deserialize(params: &mut StudioRemote, raw: &[u8]) -> Result<(), String> {
deserialize_loaded_program(&mut params.prog, &raw[..4])?;
params
.user_assigns
.iter_mut()
.enumerate()
.try_for_each(|(i, assign)| {
let pos = 4 + i * 4;
deserialize_src_entry(assign, &raw[pos..(pos + 4)])
})?;
deserialize_remote_effect_button_mode(&mut params.effect_button_mode, &raw[28..32])?;
deserialize_bool(&mut params.fallback_to_master_enable, &raw[32..36]);
deserialize_u32(&mut params.fallback_to_master_duration, &raw[36..40]);
deserialize_knob_push_mode(&mut params.knob_push_mode, &raw[40..44])?;
Ok(())
}
}
impl TcKonnektMutableSegmentOperation<StudioRemote> for Studiok48Protocol {}
impl TcKonnektNotifiedSegmentOperation<StudioRemote> for Studiok48Protocol {
const NOTIFY_FLAG: u32 = STUDIO_REMOTE_NOTIFY_FLAG;
}
impl AsRef<TcKonnektLoadedProgram> for StudioRemote {
fn as_ref(&self) -> &TcKonnektLoadedProgram {
&self.prog
}
}
impl AsMut<TcKonnektLoadedProgram> for StudioRemote {
fn as_mut(&mut self) -> &mut TcKonnektLoadedProgram {
&mut self.prog
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum OptIfaceMode {
Adat,
Spdif,
}
impl Default for OptIfaceMode {
fn default() -> Self {
Self::Adat
}
}
const OPT_IFACE_MODES: &[OptIfaceMode] = &[OptIfaceMode::Adat, OptIfaceMode::Spdif];
const OPT_IFACE_MODE_LABEL: &str = "optical interface mode";
fn serialize_opt_iface_mode(mode: &OptIfaceMode, raw: &mut [u8]) -> Result<(), String> {
serialize_position(OPT_IFACE_MODES, mode, raw, OPT_IFACE_MODE_LABEL)
}
fn deserialize_opt_iface_mode(mode: &mut OptIfaceMode, raw: &[u8]) -> Result<(), String> {
deserialize_position(OPT_IFACE_MODES, mode, raw, OPT_IFACE_MODE_LABEL)
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum StudioStandaloneClkSrc {
Adat,
SpdifOnOpt01,
SpdifOnOpt23,
SpdifOnCoax,
WordClock,
Internal,
}
impl Default for StudioStandaloneClkSrc {
fn default() -> Self {
Self::Internal
}
}
const STANDALONE_CLOCK_SOURCES: &[StudioStandaloneClkSrc] = &[
StudioStandaloneClkSrc::Adat,
StudioStandaloneClkSrc::SpdifOnOpt01,
StudioStandaloneClkSrc::SpdifOnOpt23,
StudioStandaloneClkSrc::SpdifOnCoax,
StudioStandaloneClkSrc::WordClock,
StudioStandaloneClkSrc::Internal,
];
const STANDALONE_CLOCK_SOURCE_LABEL: &str = "standalone clock source";
fn serialize_standalone_clock_source(
src: &StudioStandaloneClkSrc,
raw: &mut [u8],
) -> Result<(), String> {
serialize_position(
STANDALONE_CLOCK_SOURCES,
src,
raw,
STANDALONE_CLOCK_SOURCE_LABEL,
)
}
fn deserialize_standalone_clock_source(
src: &mut StudioStandaloneClkSrc,
raw: &[u8],
) -> Result<(), String> {
deserialize_position(
STANDALONE_CLOCK_SOURCES,
src,
raw,
STANDALONE_CLOCK_SOURCE_LABEL,
)
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct StudioConfig {
pub opt_iface_mode: OptIfaceMode,
pub standalone_src: StudioStandaloneClkSrc,
pub standalone_rate: TcKonnektStandaloneClockRate,
pub clock_recovery: bool,
pub midi_send: TcKonnektMidiSender,
}
impl TcKonnektSegmentSerdes<StudioConfig> for Studiok48Protocol {
const NAME: &'static str = "configuration";
const OFFSET: usize = 0x0044;
const SIZE: usize = 100;
fn serialize(params: &StudioConfig, raw: &mut [u8]) -> Result<(), String> {
serialize_opt_iface_mode(¶ms.opt_iface_mode, &mut raw[..4])?;
serialize_standalone_clock_source(¶ms.standalone_src, &mut raw[4..8])?;
serialize_standalone_clock_rate(¶ms.standalone_rate, &mut raw[8..12])?;
serialize_bool(¶ms.clock_recovery, &mut raw[16..20]);
serialize_midi_sender(¶ms.midi_send, &mut raw[52..88])?;
Ok(())
}
fn deserialize(params: &mut StudioConfig, raw: &[u8]) -> Result<(), String> {
deserialize_opt_iface_mode(&mut params.opt_iface_mode, &raw[..4])?;
deserialize_standalone_clock_source(&mut params.standalone_src, &raw[4..8])?;
deserialize_standalone_clock_rate(&mut params.standalone_rate, &raw[8..12])?;
deserialize_bool(&mut params.clock_recovery, &raw[16..20]);
deserialize_midi_sender(&mut params.midi_send, &raw[52..88])?;
Ok(())
}
}
impl TcKonnektMutableSegmentOperation<StudioConfig> for Studiok48Protocol {}
impl TcKonnektNotifiedSegmentOperation<StudioConfig> for Studiok48Protocol {
const NOTIFY_FLAG: u32 = STUDIO_CONFIG_NOTIFY_FLAG;
}
impl AsRef<TcKonnektStandaloneClockRate> for StudioConfig {
fn as_ref(&self) -> &TcKonnektStandaloneClockRate {
&self.standalone_rate
}
}
impl AsMut<TcKonnektStandaloneClockRate> for StudioConfig {
fn as_mut(&mut self) -> &mut TcKonnektStandaloneClockRate {
&mut self.standalone_rate
}
}
impl AsRef<TcKonnektMidiSender> for StudioConfig {
fn as_ref(&self) -> &TcKonnektMidiSender {
&self.midi_send
}
}
impl AsMut<TcKonnektMidiSender> for StudioConfig {
fn as_mut(&mut self) -> &mut TcKonnektMidiSender {
&mut self.midi_send
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum SrcEntry {
Unused,
Analog(usize), Spdif(usize), Adat(usize), StreamA(usize), StreamB(usize), Mixer(usize), }
impl SrcEntry {
const UNUSED: usize = 0x00;
const ANALOG_OFFSET: usize = 0x01;
const SPDIF_OFFSET: usize = 0x0d;
const ADAT_OFFSET: usize = 0x0f;
const STREAM_A_OFFSET: usize = 0x37;
const STREAM_B_OFFSET: usize = 0x47;
const MIXER_OFFSET: usize = 0x55;
}
impl Default for SrcEntry {
fn default() -> Self {
SrcEntry::Unused
}
}
fn serialize_src_entry(entry: &SrcEntry, raw: &mut [u8]) -> Result<(), String> {
assert!(raw.len() >= 4);
let val = (match entry {
SrcEntry::Unused => SrcEntry::UNUSED,
SrcEntry::Analog(ch) => SrcEntry::ANALOG_OFFSET + ch,
SrcEntry::Spdif(ch) => SrcEntry::SPDIF_OFFSET + ch,
SrcEntry::Adat(ch) => SrcEntry::ADAT_OFFSET + ch,
SrcEntry::StreamA(ch) => SrcEntry::STREAM_A_OFFSET + ch,
SrcEntry::StreamB(ch) => SrcEntry::STREAM_B_OFFSET + ch,
SrcEntry::Mixer(ch) => SrcEntry::MIXER_OFFSET + ch,
}) as u32;
serialize_u32(&val, raw);
Ok(())
}
fn deserialize_src_entry(entry: &mut SrcEntry, raw: &[u8]) -> Result<(), String> {
assert!(raw.len() >= 4);
let mut val = 0u32;
deserialize_u32(&mut val, raw);
let v = val as usize;
*entry = if v >= SrcEntry::ANALOG_OFFSET && v < SrcEntry::SPDIF_OFFSET {
SrcEntry::Analog(v - SrcEntry::ANALOG_OFFSET)
} else if v >= SrcEntry::SPDIF_OFFSET && v < SrcEntry::ADAT_OFFSET {
SrcEntry::Spdif(v - SrcEntry::SPDIF_OFFSET)
} else if v >= SrcEntry::ADAT_OFFSET && v < 0x17 {
SrcEntry::Adat(v - SrcEntry::ADAT_OFFSET)
} else if v >= SrcEntry::STREAM_A_OFFSET && v < SrcEntry::STREAM_B_OFFSET {
SrcEntry::StreamA(v - SrcEntry::STREAM_A_OFFSET)
} else if v >= SrcEntry::STREAM_B_OFFSET && v < SrcEntry::MIXER_OFFSET {
SrcEntry::StreamB(v - SrcEntry::STREAM_B_OFFSET)
} else if v >= SrcEntry::MIXER_OFFSET && v < 0x5d {
SrcEntry::Mixer(v - SrcEntry::MIXER_OFFSET)
} else {
SrcEntry::Unused
};
Ok(())
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct OutPair {
pub dim_enabled: bool,
pub vol: i32,
pub dim_vol: i32,
}
impl OutPair {
const SIZE: usize = 12;
}
fn serialize_out_pair(pair: &OutPair, raw: &mut [u8]) -> Result<(), String> {
assert!(raw.len() >= OutPair::SIZE);
serialize_bool(&pair.dim_enabled, &mut raw[..4]);
serialize_i32(&pair.vol, &mut raw[4..8]);
serialize_i32(&pair.dim_vol, &mut raw[8..12]);
Ok(())
}
fn deserialize_out_pair(pair: &mut OutPair, raw: &[u8]) -> Result<(), String> {
assert!(raw.len() >= OutPair::SIZE);
deserialize_bool(&mut pair.dim_enabled, &raw[..4]);
deserialize_i32(&mut pair.vol, &raw[4..8]);
deserialize_i32(&mut pair.dim_vol, &raw[8..12]);
Ok(())
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum MonitorSrcPairMode {
Inactive,
Active,
Fixed,
}
impl Default for MonitorSrcPairMode {
fn default() -> Self {
Self::Inactive
}
}
const MONITOR_SRC_PAIR_MODES: &[MonitorSrcPairMode] = &[
MonitorSrcPairMode::Inactive,
MonitorSrcPairMode::Active,
MonitorSrcPairMode::Fixed,
];
const MONITOR_SRC_PAIR_MODE_LABEL: &str = "monitor source pair mode";
fn serialize_monitor_src_pair_mode(
mode: &MonitorSrcPairMode,
raw: &mut [u8],
) -> Result<(), String> {
serialize_position(
MONITOR_SRC_PAIR_MODES,
mode,
raw,
MONITOR_SRC_PAIR_MODE_LABEL,
)
}
fn deserialize_monitor_src_pair_mode(
mode: &mut MonitorSrcPairMode,
raw: &[u8],
) -> Result<(), String> {
deserialize_position(
MONITOR_SRC_PAIR_MODES,
mode,
raw,
MONITOR_SRC_PAIR_MODE_LABEL,
)
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct MonitorSrcParam {
pub src: SrcEntry,
pub gain_to_main: i32,
pub pan_to_main: i32,
pub gain_to_reverb: i32,
pub gain_to_aux0: i32,
pub gain_to_aux1: i32,
}
impl MonitorSrcParam {
const SIZE: usize = 24;
}
fn serialize_monitor_src_params(params: &MonitorSrcParam, raw: &mut [u8]) -> Result<(), String> {
assert!(raw.len() >= MonitorSrcParam::SIZE);
serialize_src_entry(¶ms.src, &mut raw[..4])?;
serialize_i32(¶ms.gain_to_main, &mut raw[4..8]);
serialize_i32(¶ms.pan_to_main, &mut raw[8..12]);
serialize_i32(¶ms.gain_to_reverb, &mut raw[12..16]);
serialize_i32(¶ms.gain_to_aux0, &mut raw[16..20]);
serialize_i32(¶ms.gain_to_aux1, &mut raw[20..24]);
Ok(())
}
fn deserialize_monitor_src_params(params: &mut MonitorSrcParam, raw: &[u8]) -> Result<(), String> {
assert!(raw.len() >= MonitorSrcParam::SIZE);
deserialize_src_entry(&mut params.src, &raw[..4])?;
deserialize_i32(&mut params.gain_to_main, &raw[4..8]);
deserialize_i32(&mut params.pan_to_main, &raw[8..12]);
deserialize_i32(&mut params.gain_to_reverb, &raw[12..16]);
deserialize_i32(&mut params.gain_to_aux0, &raw[16..20]);
deserialize_i32(&mut params.gain_to_aux1, &raw[20..24]);
Ok(())
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct MonitorSrcPair {
pub mode: MonitorSrcPairMode,
pub stereo_link: bool,
pub params: [MonitorSrcParam; 2],
}
impl MonitorSrcPair {
const SIZE: usize = 56;
}
fn serialize_monitor_src_pair(pair: &MonitorSrcPair, raw: &mut [u8]) -> Result<(), String> {
assert!(raw.len() >= MonitorSrcPair::SIZE);
serialize_monitor_src_pair_mode(&pair.mode, &mut raw[..4])?;
serialize_bool(&pair.stereo_link, &mut raw[4..8]);
serialize_monitor_src_params(&pair.params[0], &mut raw[8..32])?;
serialize_monitor_src_params(&pair.params[1], &mut raw[32..56])?;
Ok(())
}
fn deserialize_monitor_src_pair(pair: &mut MonitorSrcPair, raw: &[u8]) -> Result<(), String> {
assert!(raw.len() >= MonitorSrcPair::SIZE);
deserialize_monitor_src_pair_mode(&mut pair.mode, &raw[..4])?;
deserialize_bool(&mut pair.stereo_link, &raw[4..8]);
deserialize_monitor_src_params(&mut pair.params[0], &raw[8..32])?;
deserialize_monitor_src_params(&mut pair.params[1], &raw[32..56])?;
Ok(())
}
pub const STUDIO_MIXER_SRC_PAIR_COUNT: usize = 12;
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct StudioMixerState {
pub src_pairs: [MonitorSrcPair; STUDIO_MIXER_SRC_PAIR_COUNT],
pub mutes: [bool; STUDIO_MIXER_SRC_PAIR_COUNT],
pub reverb_return_mute: [bool; 3],
pub reverb_return_gain: [i32; 3],
pub ch_strip_as_plugin: [bool; 2],
pub ch_strip_src: [SrcEntry; 4],
pub ch_strip_23_at_mid_rate: bool,
pub mixer_out: [OutPair; 3],
pub post_fader: [bool; 3],
pub enabled: bool,
}
impl TcKonnektSegmentSerdes<StudioMixerState> for Studiok48Protocol {
const NAME: &'static str = "mixer-state";
const OFFSET: usize = 0x00a8;
const SIZE: usize = 820;
fn serialize(params: &StudioMixerState, raw: &mut [u8]) -> Result<(), String> {
params.src_pairs.iter().enumerate().try_for_each(|(i, p)| {
let pos = i * MonitorSrcPair::SIZE;
serialize_monitor_src_pair(p, &mut raw[pos..(pos + MonitorSrcPair::SIZE)])
})?;
let mut val = 0u32;
params
.mutes
.iter()
.enumerate()
.filter(|(_, &m)| m)
.for_each(|(i, _)| {
val |= 1 << i;
});
serialize_u32(&val, &mut raw[672..676]);
serialize_bool(¶ms.reverb_return_mute[0], &mut raw[712..716]);
serialize_i32(¶ms.reverb_return_gain[0], &mut raw[716..720]);
serialize_bool(¶ms.reverb_return_mute[1], &mut raw[720..724]);
serialize_i32(¶ms.reverb_return_gain[1], &mut raw[724..728]);
serialize_bool(¶ms.reverb_return_mute[2], &mut raw[728..732]);
serialize_i32(¶ms.reverb_return_gain[2], &mut raw[732..736]);
serialize_bool(¶ms.ch_strip_as_plugin[0], &mut raw[736..740]);
serialize_bool(¶ms.ch_strip_as_plugin[1], &mut raw[740..744]);
params
.ch_strip_src
.iter()
.enumerate()
.try_for_each(|(i, entry)| {
let pos = 744 + i * 4;
serialize_src_entry(entry, &mut raw[pos..(pos + 4)])
})?;
serialize_bool(¶ms.ch_strip_23_at_mid_rate, &mut raw[760..764]);
serialize_out_pair(¶ms.mixer_out[0], &mut raw[764..776])?;
serialize_out_pair(¶ms.mixer_out[1], &mut raw[776..788])?;
serialize_out_pair(¶ms.mixer_out[2], &mut raw[788..800])?;
serialize_bool(¶ms.post_fader[0], &mut raw[800..804]);
serialize_bool(¶ms.post_fader[1], &mut raw[804..808]);
serialize_bool(¶ms.post_fader[2], &mut raw[808..812]);
serialize_bool(¶ms.enabled, &mut raw[812..816]);
Ok(())
}
fn deserialize(params: &mut StudioMixerState, raw: &[u8]) -> Result<(), String> {
params
.src_pairs
.iter_mut()
.enumerate()
.try_for_each(|(i, p)| {
let pos = i * MonitorSrcPair::SIZE;
deserialize_monitor_src_pair(p, &raw[pos..(pos + MonitorSrcPair::SIZE)])
})?;
let mut val = 0u32;
deserialize_u32(&mut val, &raw[672..676]);
params.mutes.iter_mut().enumerate().for_each(|(i, m)| {
*m = (val & 1 << i) > 0;
});
deserialize_bool(&mut params.reverb_return_mute[0], &raw[712..716]);
deserialize_i32(&mut params.reverb_return_gain[0], &raw[716..720]);
deserialize_bool(&mut params.reverb_return_mute[1], &raw[720..724]);
deserialize_i32(&mut params.reverb_return_gain[1], &raw[724..728]);
deserialize_bool(&mut params.reverb_return_mute[2], &raw[728..732]);
deserialize_i32(&mut params.reverb_return_gain[2], &raw[732..736]);
deserialize_bool(&mut params.ch_strip_as_plugin[0], &raw[736..740]);
deserialize_bool(&mut params.ch_strip_as_plugin[1], &raw[740..744]);
params
.ch_strip_src
.iter_mut()
.enumerate()
.try_for_each(|(i, entry)| {
let pos = 744 + i * 4;
deserialize_src_entry(entry, &raw[pos..(pos + 4)])
})?;
deserialize_bool(&mut params.ch_strip_23_at_mid_rate, &raw[760..764]);
deserialize_out_pair(&mut params.mixer_out[0], &raw[764..776])?;
deserialize_out_pair(&mut params.mixer_out[1], &raw[776..788])?;
deserialize_out_pair(&mut params.mixer_out[2], &raw[788..800])?;
deserialize_bool(&mut params.post_fader[0], &raw[800..804]);
deserialize_bool(&mut params.post_fader[1], &raw[804..808]);
deserialize_bool(&mut params.post_fader[2], &raw[800..812]);
deserialize_bool(&mut params.enabled, &raw[812..816]);
Ok(())
}
}
impl TcKonnektMutableSegmentOperation<StudioMixerState> for Studiok48Protocol {}
impl TcKonnektNotifiedSegmentOperation<StudioMixerState> for Studiok48Protocol {
const NOTIFY_FLAG: u32 = STUDIO_MIXER_STATE_NOTIFY_FLAG;
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct PhysOutSrcParam {
pub src: SrcEntry,
pub vol: i32,
pub delay: i32,
}
impl PhysOutSrcParam {
const SIZE: usize = 12;
}
fn serialize_phys_out_src_params(params: &PhysOutSrcParam, raw: &mut [u8]) -> Result<(), String> {
assert!(raw.len() >= PhysOutSrcParam::SIZE);
serialize_src_entry(¶ms.src, &mut raw[..4])?;
serialize_i32(¶ms.vol, &mut raw[4..8]);
serialize_i32(¶ms.delay, &mut raw[8..12]);
Ok(())
}
fn deserialize_phys_out_src_params(params: &mut PhysOutSrcParam, raw: &[u8]) -> Result<(), String> {
assert!(raw.len() >= PhysOutSrcParam::SIZE);
deserialize_src_entry(&mut params.src, &raw[..4])?;
deserialize_i32(&mut params.vol, &raw[4..8]);
deserialize_i32(&mut params.delay, &raw[8..12]);
Ok(())
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct PhysOutPairSrc {
pub stereo_link: bool,
pub params: [PhysOutSrcParam; 2],
}
impl PhysOutPairSrc {
const SIZE: usize = 28;
}
fn serialize_phys_out_pair_src(src: &PhysOutPairSrc, raw: &mut [u8]) -> Result<(), String> {
assert!(raw.len() >= PhysOutPairSrc::SIZE);
serialize_bool(&src.stereo_link, &mut raw[..4]);
serialize_phys_out_src_params(&src.params[0], &mut raw[4..16])?;
serialize_phys_out_src_params(&src.params[1], &mut raw[16..28])?;
Ok(())
}
fn deserialize_phys_out_pair_src(src: &mut PhysOutPairSrc, raw: &[u8]) -> Result<(), String> {
assert!(raw.len() >= PhysOutPairSrc::SIZE);
deserialize_bool(&mut src.stereo_link, &raw[..4]);
deserialize_phys_out_src_params(&mut src.params[0], &raw[4..16])?;
deserialize_phys_out_src_params(&mut src.params[1], &raw[16..28])?;
Ok(())
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum CrossOverFreq {
F50,
F80,
F95,
F110,
F115,
F120,
}
impl Default for CrossOverFreq {
fn default() -> Self {
Self::F50
}
}
const CROSS_OVER_FREQS: &[CrossOverFreq] = &[
CrossOverFreq::F50,
CrossOverFreq::F80,
CrossOverFreq::F95,
CrossOverFreq::F110,
CrossOverFreq::F115,
CrossOverFreq::F120,
];
const CROSS_OVER_FREQ_LABEL: &str = "cross over frequency";
fn serialize_cross_over_freq(freq: &CrossOverFreq, raw: &mut [u8]) -> Result<(), String> {
serialize_position(CROSS_OVER_FREQS, freq, raw, CROSS_OVER_FREQ_LABEL)
}
fn deserialize_cross_over_freq(freq: &mut CrossOverFreq, raw: &[u8]) -> Result<(), String> {
deserialize_position(CROSS_OVER_FREQS, freq, raw, CROSS_OVER_FREQ_LABEL)
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum HighPassFreq {
Off,
Above12,
Above24,
}
impl Default for HighPassFreq {
fn default() -> Self {
HighPassFreq::Off
}
}
const HIGH_PASS_FREQS: &[HighPassFreq] = &[
HighPassFreq::Off,
HighPassFreq::Above12,
HighPassFreq::Above24,
];
const HIGH_PASS_FREQ_LABEL: &str = "high pass frequency";
fn serialize_high_pass_freq(freq: &HighPassFreq, raw: &mut [u8]) -> Result<(), String> {
serialize_position(HIGH_PASS_FREQS, freq, raw, HIGH_PASS_FREQ_LABEL)
}
fn deserialize_high_pass_freq(freq: &mut HighPassFreq, raw: &[u8]) -> Result<(), String> {
deserialize_position(HIGH_PASS_FREQS, freq, raw, HIGH_PASS_FREQ_LABEL)
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum LowPassFreq {
Below12,
Below24,
}
impl Default for LowPassFreq {
fn default() -> Self {
LowPassFreq::Below12
}
}
fn serialize_low_pass_freq(freq: &LowPassFreq, raw: &mut [u8]) -> Result<(), String> {
assert!(raw.len() >= 4);
let val = match freq {
LowPassFreq::Below12 => 1u32,
LowPassFreq::Below24 => 2,
};
serialize_u32(&val, raw);
Ok(())
}
fn deserialize_low_pass_freq(freq: &mut LowPassFreq, raw: &[u8]) -> Result<(), String> {
assert!(raw.len() >= 4);
let mut val = 0u32;
deserialize_u32(&mut val, raw);
*freq = match val {
1 => LowPassFreq::Below12,
2 => LowPassFreq::Below24,
_ => Err(format!("low pass frequency not found for value {}", val))?,
};
Ok(())
}
pub const STUDIO_MAX_SURROUND_CHANNELS: usize = 8;
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct OutGroup {
pub assigned_phys_outs: [bool; STUDIO_PHYS_OUT_PAIR_COUNT * 2],
pub bass_management: bool,
pub sub_channel: Option<usize>,
pub main_cross_over_freq: CrossOverFreq,
pub main_level_to_sub: i32,
pub sub_level_to_sub: i32,
pub main_filter_for_main: HighPassFreq,
pub main_filter_for_sub: LowPassFreq,
}
impl OutGroup {
const SIZE: usize = 36;
}
fn serialize_out_group(group: &OutGroup, raw: &mut [u8]) -> Result<(), String> {
assert!(raw.len() >= OutGroup::SIZE);
let mut val = 0u32;
group
.assigned_phys_outs
.iter()
.enumerate()
.filter(|(_, &a)| a)
.take(STUDIO_MAX_SURROUND_CHANNELS)
.for_each(|(i, _)| {
val |= 1 << i;
});
serialize_u32(&val, &mut raw[..4]);
serialize_bool(&group.bass_management, &mut raw[4..8]);
val = match group.sub_channel {
Some(pos) => 1 << pos,
None => 0,
};
serialize_u32(&val, &mut raw[12..16]);
serialize_cross_over_freq(&group.main_cross_over_freq, &mut raw[16..20])?;
serialize_i32(&group.main_level_to_sub, &mut raw[20..24]);
serialize_i32(&group.sub_level_to_sub, &mut raw[24..28]);
serialize_high_pass_freq(&group.main_filter_for_main, &mut raw[28..32])?;
serialize_low_pass_freq(&group.main_filter_for_sub, &mut raw[32..])?;
Ok(())
}
fn deserialize_out_group(group: &mut OutGroup, raw: &[u8]) -> Result<(), String> {
assert!(raw.len() >= OutGroup::SIZE);
let mut val = 0u32;
deserialize_u32(&mut val, &raw[..4]);
group
.assigned_phys_outs
.iter_mut()
.enumerate()
.for_each(|(i, a)| *a = val & (1 << i) > 0);
deserialize_bool(&mut group.bass_management, &raw[4..8]);
deserialize_u32(&mut val, &raw[12..16]);
group.sub_channel = (0..group.assigned_phys_outs.len())
.position(|i| val & (1 << i) > 0)
.map(|pos| pos as usize);
deserialize_cross_over_freq(&mut group.main_cross_over_freq, &raw[16..20])?;
deserialize_i32(&mut group.main_level_to_sub, &raw[20..24]);
deserialize_i32(&mut group.sub_level_to_sub, &raw[24..28]);
deserialize_high_pass_freq(&mut group.main_filter_for_main, &raw[28..32])?;
deserialize_low_pass_freq(&mut group.main_filter_for_sub, &raw[32..])?;
Ok(())
}
pub const STUDIO_PHYS_OUT_PAIR_COUNT: usize = 11;
pub const STUDIO_OUTPUT_GROUP_COUNT: usize = 3;
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct StudioPhysOut {
pub master_out: OutPair,
pub selected_out_grp: usize,
pub out_pair_srcs: [PhysOutPairSrc; STUDIO_PHYS_OUT_PAIR_COUNT],
pub out_assign_to_grp: [bool; STUDIO_PHYS_OUT_PAIR_COUNT * 2],
pub out_mutes: [bool; STUDIO_PHYS_OUT_PAIR_COUNT * 2],
pub out_grps: [OutGroup; STUDIO_OUTPUT_GROUP_COUNT],
}
impl TcKonnektSegmentSerdes<StudioPhysOut> for Studiok48Protocol {
const NAME: &'static str = "physical-output";
const OFFSET: usize = 0x03dc;
const SIZE: usize = 440;
fn serialize(params: &StudioPhysOut, raw: &mut [u8]) -> Result<(), String> {
serialize_out_pair(¶ms.master_out, &mut raw[..12])?;
params
.out_pair_srcs
.iter()
.enumerate()
.try_for_each(|(i, p)| {
let pos = 16 + i * PhysOutPairSrc::SIZE;
serialize_phys_out_pair_src(p, &mut raw[pos..(pos + PhysOutPairSrc::SIZE)])
})?;
serialize_usize(¶ms.selected_out_grp, &mut raw[12..16]);
let mut val = 0u32;
params
.out_assign_to_grp
.iter()
.enumerate()
.filter(|(_, &m)| m)
.for_each(|(i, _)| {
val |= 1 << i;
});
serialize_u32(&val, &mut raw[324..328]);
let mut val = 0u32;
params
.out_mutes
.iter()
.enumerate()
.filter(|(_, &d)| d)
.for_each(|(i, _)| {
val |= 1 << i;
});
serialize_u32(&val, &mut raw[328..332]);
params.out_grps.iter().enumerate().try_for_each(|(i, s)| {
let pos = 332 + OutGroup::SIZE * i;
serialize_out_group(s, &mut raw[pos..(pos + OutGroup::SIZE)])
})?;
Ok(())
}
fn deserialize(params: &mut StudioPhysOut, raw: &[u8]) -> Result<(), String> {
deserialize_out_pair(&mut params.master_out, &raw[..12])?;
params
.out_pair_srcs
.iter_mut()
.enumerate()
.try_for_each(|(i, p)| {
let pos = 16 + i * PhysOutPairSrc::SIZE;
deserialize_phys_out_pair_src(p, &raw[pos..(pos + PhysOutPairSrc::SIZE)])
})?;
let mut val = 0u32;
deserialize_u32(&mut val, &raw[12..16]);
deserialize_usize(&mut params.selected_out_grp, &raw[324..328]);
params
.out_assign_to_grp
.iter_mut()
.enumerate()
.for_each(|(i, m)| {
*m = val & (1 << i) > 0;
});
let mut val = 0u32;
deserialize_u32(&mut val, &raw[328..332]);
params.out_mutes.iter_mut().enumerate().for_each(|(i, d)| {
*d = val & (1 << i) > 0;
});
params
.out_grps
.iter_mut()
.enumerate()
.try_for_each(|(i, s)| {
let pos = 332 + OutGroup::SIZE * i;
deserialize_out_group(s, &raw[pos..(pos + OutGroup::SIZE)])
})?;
Ok(())
}
}
impl TcKonnektMutableSegmentOperation<StudioPhysOut> for Studiok48Protocol {}
impl TcKonnektNotifiedSegmentOperation<StudioPhysOut> for Studiok48Protocol {
const NOTIFY_FLAG: u32 = STUDIO_PHYS_OUT_NOTIFY_FLAG;
}
const STUDIO_CH_STRIP_COUNT: usize = 4;
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct StudioReverbState(pub ReverbState);
impl TcKonnektSegmentSerdes<StudioReverbState> for Studiok48Protocol {
const NAME: &'static str = "reverb-state";
const OFFSET: usize = 0x0594;
const SIZE: usize = ReverbState::SIZE;
fn serialize(params: &StudioReverbState, raw: &mut [u8]) -> Result<(), String> {
serialize_reverb_state(¶ms.0, raw)
}
fn deserialize(params: &mut StudioReverbState, raw: &[u8]) -> Result<(), String> {
deserialize_reverb_state(&mut params.0, raw)
}
}
impl TcKonnektMutableSegmentOperation<StudioReverbState> for Studiok48Protocol {}
impl TcKonnektNotifiedSegmentOperation<StudioReverbState> for Studiok48Protocol {
const NOTIFY_FLAG: u32 = STUDIO_REVERB_NOTIFY_CHANGE;
}
impl AsRef<ReverbState> for StudioReverbState {
fn as_ref(&self) -> &ReverbState {
&self.0
}
}
impl AsMut<ReverbState> for StudioReverbState {
fn as_mut(&mut self) -> &mut ReverbState {
&mut self.0
}
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct StudioChStripStates(pub [ChStripState; STUDIO_CH_STRIP_COUNT]);
impl TcKonnektSegmentSerdes<StudioChStripStates> for Studiok48Protocol {
const NAME: &'static str = "channel-strip-state";
const OFFSET: usize = 0x05dc;
const SIZE: usize = ChStripState::SIZE * STUDIO_CH_STRIP_COUNT + 8;
fn serialize(params: &StudioChStripStates, raw: &mut [u8]) -> Result<(), String> {
serialize_ch_strip_states(¶ms.0, raw)
}
fn deserialize(params: &mut StudioChStripStates, raw: &[u8]) -> Result<(), String> {
deserialize_ch_strip_states(&mut params.0, raw)
}
}
impl TcKonnektMutableSegmentOperation<StudioChStripStates> for Studiok48Protocol {}
impl TcKonnektNotifiedSegmentOperation<StudioChStripStates> for Studiok48Protocol {
const NOTIFY_FLAG: u32 = STUDIO_CH_STRIP_NOTIFY_01_CHANGE | STUDIO_CH_STRIP_NOTIFY_23_CHANGE;
}
impl AsRef<[ChStripState]> for StudioChStripStates {
fn as_ref(&self) -> &[ChStripState] {
&self.0
}
}
impl AsMut<[ChStripState]> for StudioChStripStates {
fn as_mut(&mut self) -> &mut [ChStripState] {
&mut self.0
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum StudioAnalogJackState {
FrontSelected,
FrontInserted,
RearSelected,
RearInserted,
}
impl Default for StudioAnalogJackState {
fn default() -> Self {
Self::FrontSelected
}
}
fn serialize_analog_jack_state(
state: &StudioAnalogJackState,
raw: &mut [u8],
) -> Result<(), String> {
assert!(raw.len() >= 4);
let val = match state {
StudioAnalogJackState::FrontSelected => 5,
StudioAnalogJackState::FrontInserted => 6,
StudioAnalogJackState::RearSelected => 7,
StudioAnalogJackState::RearInserted => 8,
};
serialize_u32(&val, raw);
Ok(())
}
fn deserialize_analog_jack_state(
state: &mut StudioAnalogJackState,
raw: &[u8],
) -> Result<(), String> {
assert!(raw.len() >= 4);
let mut val = 0u32;
deserialize_u32(&mut val, raw);
*state = match val {
8 => StudioAnalogJackState::RearInserted,
7 => StudioAnalogJackState::RearSelected,
6 => StudioAnalogJackState::FrontInserted,
_ => StudioAnalogJackState::FrontSelected,
};
Ok(())
}
pub const STUDIO_ANALOG_JACK_STATE_COUNT: usize = 12;
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct StudioHwState {
pub analog_jack_states: [StudioAnalogJackState; STUDIO_ANALOG_JACK_STATE_COUNT],
pub hp_state: [bool; 2],
pub firewire_led: FireWireLedState,
pub valid_master_level: bool,
}
impl TcKonnektSegmentSerdes<StudioHwState> for Studiok48Protocol {
const NAME: &'static str = "hardware-state";
const OFFSET: usize = 0x2008;
const SIZE: usize = 68;
fn serialize(params: &StudioHwState, raw: &mut [u8]) -> Result<(), String> {
params
.analog_jack_states
.iter()
.enumerate()
.try_for_each(|(i, state)| {
let pos = 4 * i;
serialize_analog_jack_state(state, &mut raw[pos..(pos + 4)])
})?;
serialize_bool(¶ms.hp_state[0], &mut raw[48..56]);
serialize_bool(¶ms.hp_state[1], &mut raw[48..56]);
serialize_fw_led_state(¶ms.firewire_led, &mut raw[56..60])?;
serialize_bool(¶ms.valid_master_level, &mut raw[60..64]);
Ok(())
}
fn deserialize(params: &mut StudioHwState, raw: &[u8]) -> Result<(), String> {
params
.analog_jack_states
.iter_mut()
.enumerate()
.try_for_each(|(i, state)| {
let pos = 4 * i;
deserialize_analog_jack_state(state, &raw[pos..(pos + 4)])
})?;
deserialize_bool(&mut params.hp_state[0], &raw[48..52]);
deserialize_bool(&mut params.hp_state[1], &raw[52..56]);
deserialize_fw_led_state(&mut params.firewire_led, &raw[56..60])?;
deserialize_bool(&mut params.valid_master_level, &raw[60..64]);
Ok(())
}
}
impl TcKonnektMutableSegmentOperation<StudioHwState> for Studiok48Protocol {}
impl TcKonnektNotifiedSegmentOperation<StudioHwState> for Studiok48Protocol {
const NOTIFY_FLAG: u32 = STUDIO_HW_STATE_NOTIFY_FLAG;
}
impl AsRef<FireWireLedState> for StudioHwState {
fn as_ref(&self) -> &FireWireLedState {
&self.firewire_led
}
}
impl AsMut<FireWireLedState> for StudioHwState {
fn as_mut(&mut self) -> &mut FireWireLedState {
&mut self.firewire_led
}
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct StudioMixerMeter {
pub src_inputs: [i32; 24],
pub mixer_outputs: [i32; 2],
pub aux_outputs: [i32; 4],
}
impl TcKonnektSegmentSerdes<StudioMixerMeter> for Studiok48Protocol {
const NAME: &'static str = "mixer-meter";
const OFFSET: usize = 0x20b8;
const SIZE: usize = 128;
fn serialize(params: &StudioMixerMeter, raw: &mut [u8]) -> Result<(), String> {
params
.src_inputs
.iter()
.chain(¶ms.mixer_outputs)
.chain(¶ms.aux_outputs)
.enumerate()
.for_each(|(i, level)| {
let pos = i * 4;
serialize_i32(level, &mut raw[pos..(pos + 4)])
});
Ok(())
}
fn deserialize(params: &mut StudioMixerMeter, raw: &[u8]) -> Result<(), String> {
params
.src_inputs
.iter_mut()
.chain(&mut params.mixer_outputs)
.chain(&mut params.aux_outputs)
.enumerate()
.for_each(|(i, level)| {
let pos = i * 4;
deserialize_i32(level, &raw[pos..(pos + 4)])
});
Ok(())
}
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct StudioReverbMeter(pub ReverbMeter);
impl TcKonnektSegmentSerdes<StudioReverbMeter> for Studiok48Protocol {
const NAME: &'static str = "reverb-meter";
const OFFSET: usize = 0x2164;
const SIZE: usize = ReverbMeter::SIZE;
fn serialize(params: &StudioReverbMeter, raw: &mut [u8]) -> Result<(), String> {
serialize_reverb_meter(¶ms.0, raw)
}
fn deserialize(params: &mut StudioReverbMeter, raw: &[u8]) -> Result<(), String> {
deserialize_reverb_meter(&mut params.0, raw)
}
}
impl AsRef<ReverbMeter> for StudioReverbMeter {
fn as_ref(&self) -> &ReverbMeter {
&self.0
}
}
impl AsMut<ReverbMeter> for StudioReverbMeter {
fn as_mut(&mut self) -> &mut ReverbMeter {
&mut self.0
}
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct StudioChStripMeters(pub [ChStripMeter; STUDIO_CH_STRIP_COUNT]);
impl TcKonnektSegmentSerdes<StudioChStripMeters> for Studiok48Protocol {
const NAME: &'static str = "channel-strip-meter";
const OFFSET: usize = 0x217c;
const SIZE: usize = ChStripMeter::SIZE * STUDIO_CH_STRIP_COUNT + 8;
fn serialize(params: &StudioChStripMeters, raw: &mut [u8]) -> Result<(), String> {
serialize_ch_strip_meters(¶ms.0, raw)
}
fn deserialize(params: &mut StudioChStripMeters, raw: &[u8]) -> Result<(), String> {
deserialize_ch_strip_meters(&mut params.0, raw)
}
}
impl AsRef<[ChStripMeter]> for StudioChStripMeters {
fn as_ref(&self) -> &[ChStripMeter] {
&self.0
}
}
impl AsMut<[ChStripMeter]> for StudioChStripMeters {
fn as_mut(&mut self) -> &mut [ChStripMeter] {
&mut self.0
}
}