use crate::event::Event;
use crate::state::State;
use crate::types::{AmpDolbySettings, AmpZoneSettings, AMP_EQ_BANDS};
use crate::wire::{BayUid, DeviceUid};
use super::handlers::{byte, u32_at};
use super::Rx;
const AMP_ZONE_SETTINGS_SIZE: usize = 56;
const AMP_DOLBY_SETTINGS_SIZE: usize = 24;
fn amp_target(rx: &Rx<'_>) -> DeviceUid {
let uid = rx.uid_or_zero(0);
if uid.is_zero() {
rx.sender()
} else {
uid
}
}
pub(super) fn zone_settings(state: &mut State, rx: &Rx<'_>, ev: &mut Vec<Event>) {
let target = amp_target(rx);
let p = rx.frame.payload();
if p.len() < AMP_ZONE_SETTINGS_SIZE {
return;
}
let Some(zone) = rx.frame.u16(16) else {
return;
};
let mut settings = AmpZoneSettings {
gain_left: byte(p, 18),
gain_right: byte(p, 19),
volume_min: byte(p, 20),
volume_max: byte(p, 21),
delay_left: u32_at(p, 24),
delay_right: u32_at(p, 28),
bass: byte(p, 32),
treble: byte(p, 33),
bridged: byte(p, 34),
power_mode: byte(p, 35),
power_level: byte(p, 36),
power_timeout: u32_at(p, 40),
eq_left: [0; AMP_EQ_BANDS],
eq_right: [0; AMP_EQ_BANDS],
};
for band in 0..AMP_EQ_BANDS {
settings.eq_left[band] = byte(p, 44 + band);
settings.eq_right[band] = byte(p, 49 + band);
}
if let Some(bay) = state.bay_mut(BayUid::new(target, zone)) {
bay.set_amp_settings(settings, ev);
}
}
pub(super) fn dolby_settings(state: &mut State, rx: &Rx<'_>, ev: &mut Vec<Event>) {
let target = amp_target(rx);
if rx.frame.payload().len() < AMP_DOLBY_SETTINGS_SIZE {
return;
}
let Some(mode) = rx.frame.u8(16) else {
return;
};
let flags = rx.frame.u8(17).unwrap_or(0);
let settings = AmpDolbySettings {
mode,
pcm_upmix: flags & 0x1 != 0,
dolby_detected: flags & 0x2 != 0,
pcm_upmix_active: flags & 0x4 != 0,
};
if let Some(device) = state.device_mut(target) {
device.set_dolby_settings(settings, ev);
}
}