use super::*;
#[derive(Default, Debug)]
pub struct PflClkProtocol;
impl MediaClockFrequencyOperation for PflClkProtocol {
const FREQ_LIST: &'static [u32] = &[44100, 48000, 88200, 96000];
}
impl SamplingClockSourceOperation for PflClkProtocol {
const DST: SignalAddr = SignalAddr::Subunit(SignalSubunitAddr {
subunit: MUSIC_SUBUNIT_0,
plug_id: 0x07,
});
const SRC_LIST: &'static [SignalAddr] = &[
SignalAddr::Subunit(SignalSubunitAddr {
subunit: MUSIC_SUBUNIT_0,
plug_id: 0x08,
}),
SignalAddr::Unit(SignalUnitAddr::Ext(0x01)),
SignalAddr::Unit(SignalUnitAddr::Ext(0x02)),
SignalAddr::Unit(SignalUnitAddr::Ext(0x03)),
SignalAddr::Unit(SignalUnitAddr::Ext(0x04)),
SignalAddr::Unit(SignalUnitAddr::Ext(0x05)),
SignalAddr::Unit(SignalUnitAddr::Ext(0x06)),
];
}
#[derive(Default, Debug)]
pub struct PflMeterProtocol;
const METER_SIZE: usize = 56;
#[derive(Default, Debug)]
pub struct PflInputParametersProtocol;
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum PflDetectedInputFreq {
Unavailable,
R44100,
R48000,
R88200,
R96000,
}
impl Default for PflDetectedInputFreq {
fn default() -> Self {
Self::Unavailable
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct PflMeterState {
pub detected_input_freq: PflDetectedInputFreq,
pub phys_outputs: [i32; 2],
pub sync_status: bool,
cache: [u8; METER_SIZE],
}
impl Default for PflMeterState {
fn default() -> Self {
Self {
detected_input_freq: Default::default(),
phys_outputs: Default::default(),
sync_status: Default::default(),
cache: [0; METER_SIZE],
}
}
}
impl PflMeterProtocol {
pub const METER_MIN: i32 = 0;
pub const METER_MAX: i32 = 0x007fffff;
pub const METER_STEP: i32 = 0x100;
pub fn cache(
req: &FwReq,
node: &FwNode,
meter: &mut PflMeterState,
timeout_ms: u32,
) -> Result<(), Error> {
let frame = &mut meter.cache;
req.transaction_sync(
node,
FwTcode::ReadBlockRequest,
DM_APPL_METER_OFFSET,
frame.len(),
frame,
timeout_ms,
)?;
let mut quadlet = [0; 4];
quadlet.copy_from_slice(&frame[..4]);
let val = u32::from_be_bytes(quadlet);
meter.detected_input_freq = match val {
4 => PflDetectedInputFreq::R96000,
3 => PflDetectedInputFreq::R88200,
2 => PflDetectedInputFreq::R48000,
1 => PflDetectedInputFreq::R44100,
_ => PflDetectedInputFreq::Unavailable,
};
meter
.phys_outputs
.iter_mut()
.enumerate()
.for_each(|(i, m)| {
let pos = 4 + i * 4;
quadlet.copy_from_slice(&frame[pos..(pos + 4)]);
*m = i32::from_be_bytes(quadlet);
});
quadlet.copy_from_slice(&frame[20..24]);
let val = u32::from_be_bytes(quadlet);
meter.sync_status = val != 2;
Ok(())
}
}
const CACHE_SIZE: usize = 24;
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct PflInputParameters {
pub adat_mute: [bool; 4],
pub spdif_mute: bool,
pub force_smux: bool,
cache: [u8; CACHE_SIZE],
}
impl PflInputParametersProtocol {
pub fn update(
req: &FwReq,
node: &FwNode,
params: &mut PflInputParameters,
timeout_ms: u32,
) -> Result<(), Error> {
let cache = &mut params.cache;
params.adat_mute.iter().enumerate().for_each(|(i, m)| {
let pos = i * 4;
let val = *m as u32;
cache[pos..(pos + 4)].copy_from_slice(&val.to_be_bytes());
});
let val = params.spdif_mute as u32;
cache[16..20].copy_from_slice(&val.to_be_bytes());
let val = params.force_smux as u32;
cache[20..24].copy_from_slice(&val.to_be_bytes());
req.transaction_sync(
node,
hinawa::FwTcode::WriteBlockRequest,
DM_APPL_PARAM_OFFSET,
cache.len(),
cache,
timeout_ms,
)
}
}