use super::*;
#[derive(Default, Debug)]
pub struct SaffirePro26ioClkProtocol;
impl SaffireProioMediaClockSpecification for SaffirePro26ioClkProtocol {
const FREQ_LIST: &'static [u32] = &[44100, 48000, 88200, 96000, 176400, 192000];
}
impl SaffireProioSamplingClockSpecification for SaffirePro26ioClkProtocol {
const SRC_LIST: &'static [SaffireProioSamplingClockSource] = &[
SaffireProioSamplingClockSource::Internal,
SaffireProioSamplingClockSource::Spdif,
SaffireProioSamplingClockSource::Adat0,
SaffireProioSamplingClockSource::Adat1,
SaffireProioSamplingClockSource::WordClock,
];
}
#[derive(Default, Debug)]
pub struct SaffirePro26ioMeterProtocol;
impl SaffireProioMeterOperation for SaffirePro26ioMeterProtocol {
const SRC_LIST: &'static [SaffireProioSamplingClockSource] = &[
SaffireProioSamplingClockSource::Internal,
SaffireProioSamplingClockSource::Spdif,
SaffireProioSamplingClockSource::Adat0,
SaffireProioSamplingClockSource::Adat1,
SaffireProioSamplingClockSource::WordClock,
];
}
#[derive(Default, Debug)]
pub struct SaffirePro26ioMonitorProtocol;
impl SaffireProioMonitorSpecification for SaffirePro26ioMonitorProtocol {
const HAS_ADAT: bool = true;
}
#[derive(Default, Debug)]
pub struct SaffirePro26ioSpecificProtocol;
impl SaffireProioSpecificSpecification for SaffirePro26ioSpecificProtocol {
const PHANTOM_POWERING_COUNT: usize = 2;
const INSERT_SWAP_COUNT: usize = 2;
}
#[derive(Default, Debug)]
pub struct SaffirePro10ioClkProtocol;
impl SaffireProioMediaClockSpecification for SaffirePro10ioClkProtocol {
const FREQ_LIST: &'static [u32] = &[44100, 48000, 88200, 96000];
}
#[derive(Default, Debug)]
pub struct SaffirePro10ioMonitorProtocol;
impl SaffireProioMonitorSpecification for SaffirePro10ioMonitorProtocol {
const HAS_ADAT: bool = false;
}
#[derive(Default, Debug)]
pub struct SaffirePro10ioSpecificProtocol;
impl SaffireProioSpecificSpecification for SaffirePro10ioSpecificProtocol {
const PHANTOM_POWERING_COUNT: usize = 0;
const INSERT_SWAP_COUNT: usize = 0;
}
#[derive(Default, Debug)]
pub struct SaffireProioOutputProtocol;
impl SaffireOutputSpecification for SaffireProioOutputProtocol {
const OUTPUT_OFFSETS: &'static [usize] = &[0x140, 0x144, 0x148, 0x14c];
const MUTE_COUNT: usize = 4;
const VOL_COUNT: usize = 4;
const HWCTL_COUNT: usize = 4;
const DIM_COUNT: usize = 4;
const PAD_COUNT: usize = 4;
}
impl SaffireProioSamplingClockSpecification for SaffirePro10ioClkProtocol {
const SRC_LIST: &'static [SaffireProioSamplingClockSource] = &[
SaffireProioSamplingClockSource::Internal,
SaffireProioSamplingClockSource::Spdif,
];
}
#[derive(Default, Debug)]
pub struct SaffirePro10ioMeterProtocol;
impl SaffireProioMeterOperation for SaffirePro10ioMeterProtocol {
const SRC_LIST: &'static [SaffireProioSamplingClockSource] = &[
SaffireProioSamplingClockSource::Internal,
SaffireProioSamplingClockSource::Spdif,
];
}
#[derive(Default, Debug)]
pub struct SaffireProioMixerProtocol;
pub trait SaffireProioMediaClockSpecification {
const FREQ_LIST: &'static [u32];
}
impl<O: SaffireProioMediaClockSpecification> SaffireParametersSerdes<MediaClockParameters> for O {
const OFFSETS: &'static [usize] = &[0x0150];
fn serialize(params: &MediaClockParameters, raw: &mut [u8]) {
raw.copy_from_slice(&(params.freq_idx as u32).to_be_bytes());
}
fn deserialize(params: &mut MediaClockParameters, raw: &[u8]) {
let mut quadlet = [9u8; 4];
quadlet.copy_from_slice(&raw[..4]);
let idx = u32::from_be_bytes(quadlet) as usize;
if idx < Self::FREQ_LIST.len() {
params.freq_idx = idx;
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum SaffireProioSamplingClockSource {
Internal,
Spdif,
Adat0,
Adat1,
WordClock,
}
impl Default for SaffireProioSamplingClockSource {
fn default() -> Self {
Self::Internal
}
}
pub trait SaffireProioSamplingClockSpecification {
const SRC_LIST: &'static [SaffireProioSamplingClockSource];
}
impl<O: SaffireProioSamplingClockSpecification> SaffireParametersSerdes<SamplingClockParameters>
for O
{
const OFFSETS: &'static [usize] = &[0x0174];
fn serialize(params: &SamplingClockParameters, raw: &mut [u8]) {
if let Some(val) = Self::SRC_LIST
.iter()
.nth(params.src_idx)
.and_then(|&src| match src {
SaffireProioSamplingClockSource::Internal => Some(CLK_SRC_INTERNAL),
SaffireProioSamplingClockSource::Spdif => Some(CLK_SRC_SPDIF),
SaffireProioSamplingClockSource::Adat0 => Some(CLK_SRC_ADAT0),
SaffireProioSamplingClockSource::Adat1 => Some(CLK_SRC_ADAT1),
SaffireProioSamplingClockSource::WordClock => Some(CLK_SRC_WORD_CLOCK),
})
{
raw.copy_from_slice(&val.to_be_bytes());
}
}
fn deserialize(params: &mut SamplingClockParameters, raw: &[u8]) {
let mut quadlet = [0u8; 4];
quadlet.copy_from_slice(&raw[..4]);
let val = u32::from_be_bytes(quadlet) & CLK_SRC_CONF_MASK;
if let Some(src_idx) = match val {
CLK_SRC_INTERNAL => Some(SaffireProioSamplingClockSource::Internal),
CLK_SRC_SPDIF => Some(SaffireProioSamplingClockSource::Spdif),
CLK_SRC_ADAT0 => Some(SaffireProioSamplingClockSource::Adat0),
CLK_SRC_ADAT1 => Some(SaffireProioSamplingClockSource::Adat1),
CLK_SRC_WORD_CLOCK => Some(SaffireProioSamplingClockSource::WordClock),
_ => None,
}
.and_then(|src| Self::SRC_LIST.iter().position(|s| s.eq(&src)))
{
params.src_idx = src_idx;
}
}
}
const CLK_SRC_EFFECTIVE_MASK: u32 = 0x0000ff00;
const CLK_SRC_CONF_MASK: u32 = 0x000000ff;
const CLK_SRC_INTERNAL: u32 = 0x00;
const CLK_SRC_SPDIF: u32 = 0x02;
const CLK_SRC_ADAT0: u32 = 0x03;
const CLK_SRC_ADAT1: u32 = 0x04;
const CLK_SRC_WORD_CLOCK: u32 = 0x05;
#[derive(Default, Debug)]
pub struct SaffireProioThroughProtocol;
impl SaffireThroughSpecification for SaffireProioThroughProtocol {
const THROUGH_OFFSETS: &'static [usize] = &[0x019c, 0x01a0];
}
#[derive(Default, Debug)]
pub struct SaffireProioMeterState {
pub monitor_knob: u8,
pub mute_led: bool,
pub dim_led: bool,
pub effective_clk_srcs: SaffireProioSamplingClockSource,
}
pub trait SaffireProioMeterOperation {
const SRC_LIST: &'static [SaffireProioSamplingClockSource];
const OFFSETS: &'static [usize] = &[
0x0158, 0x015c, 0x0160, 0x0174, ];
fn cache(
req: &FwReq,
node: &FwNode,
state: &mut SaffireProioMeterState,
timeout_ms: u32,
) -> Result<(), Error> {
let mut buf = vec![0; Self::OFFSETS.len() * 4];
saffire_read_quadlets(req, node, &Self::OFFSETS, &mut buf, timeout_ms).and_then(|_| {
let mut quadlet = [0; 4];
let vals = (0..Self::OFFSETS.len()).fold(Vec::new(), |mut vals, i| {
let pos = i * 4;
quadlet.copy_from_slice(&buf[pos..(pos + 4)]);
vals.push(u32::from_be_bytes(quadlet));
vals
});
state.monitor_knob = (vals[0] & 0xff) as u8;
state.mute_led = vals[1] > 0;
state.dim_led = vals[2] > 0;
state.effective_clk_srcs = match (vals[3] & CLK_SRC_EFFECTIVE_MASK) >> 8 {
CLK_SRC_INTERNAL => Ok(SaffireProioSamplingClockSource::Internal),
CLK_SRC_SPDIF => Ok(SaffireProioSamplingClockSource::Spdif),
CLK_SRC_ADAT0 => Ok(SaffireProioSamplingClockSource::Adat0),
CLK_SRC_ADAT1 => Ok(SaffireProioSamplingClockSource::Adat1),
CLK_SRC_WORD_CLOCK => Ok(SaffireProioSamplingClockSource::WordClock),
_ => {
let msg = format!("Unexpected value for source of sampling clock: {}", vals[0]);
Err(Error::new(FileError::Io, &msg))
}
}?;
Ok(())
})
}
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct SaffireProioMonitorParameters {
pub analog_inputs: [[i16; 8]; 2],
pub spdif_inputs: [[i16; 2]; 2],
pub adat_inputs: Option<[[i16; 16]; 2]>,
}
pub trait SaffireProioMonitorSpecification {
const HAS_ADAT: bool;
const MONITOR_OFFSETS: &'static [usize] = &[
0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c, 0x20, 0x24, 0x28, 0x2c, 0x30, 0x34, 0x38, 0x3c, 0x40, 0x44, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c, 0x60, 0x64, 0x68, 0x6c, 0x70, 0x74, 0x78, 0x7c, 0x80, 0x84, 0x88, 0x8c, 0x90, 0x94, 0x98, 0x9c, 0xa0, 0xa4, 0xa8, 0xac, 0xb0, 0xb4, 0xb8, 0xbc, 0xc0, 0xc4, 0xc8, 0xcc, ];
}
impl<O: SaffireProioMonitorSpecification> SaffireParametersSerdes<SaffireProioMonitorParameters>
for O
{
const OFFSETS: &'static [usize] = Self::MONITOR_OFFSETS;
fn serialize(params: &SaffireProioMonitorParameters, raw: &mut [u8]) {
params
.analog_inputs
.iter()
.enumerate()
.for_each(|(i, gains)| {
gains.iter().enumerate().for_each(|(j, &gain)| {
let pos = (i + j * 2) * 4;
let gain = gain as i32;
raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
});
});
params
.spdif_inputs
.iter()
.enumerate()
.for_each(|(i, gains)| {
gains.iter().enumerate().for_each(|(j, &gain)| {
let pos = (16 + i + j * 2) * 4;
let gain = gain as i32;
raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
});
});
if let Some(adat_inputs) = ¶ms.adat_inputs {
adat_inputs.iter().enumerate().for_each(|(i, gains)| {
gains.iter().enumerate().for_each(|(j, &gain)| {
let pos = (20 + i + j * 2) * 4;
let gain = gain as i32;
raw[pos..(pos + 4)].copy_from_slice(&gain.to_be_bytes());
});
});
}
}
fn deserialize(params: &mut SaffireProioMonitorParameters, raw: &[u8]) {
let mut quadlet = [0; 4];
let quads: Vec<i16> = (0..raw.len())
.step_by(4)
.map(|pos| {
quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
i32::from_be_bytes(quadlet) as i16
})
.collect();
params
.analog_inputs
.iter_mut()
.enumerate()
.for_each(|(i, gains)| {
gains.iter_mut().enumerate().for_each(|(j, gain)| {
let pos = i + j * 2;
*gain = quads[pos];
});
});
params
.spdif_inputs
.iter_mut()
.enumerate()
.for_each(|(i, gains)| {
gains.iter_mut().enumerate().for_each(|(j, gain)| {
let pos = 16 + i + j * 2;
*gain = quads[pos];
});
});
if let Some(adat_inputs) = &mut params.adat_inputs {
adat_inputs.iter_mut().enumerate().for_each(|(i, gains)| {
gains.iter_mut().enumerate().for_each(|(j, gain)| {
let pos = 20 + i + j * 2;
*gain = quads[pos];
});
});
}
}
}
pub trait SaffireProioMonitorProtocol: SaffireProioMonitorSpecification {
const LEVEL_MIN: i16 = 0;
const LEVEL_MAX: i16 = 0x7fff;
const LEVEL_STEP: i16 = 0x100;
fn create_params() -> SaffireProioMonitorParameters {
SaffireProioMonitorParameters {
analog_inputs: Default::default(),
spdif_inputs: Default::default(),
adat_inputs: if Self::HAS_ADAT {
Some(Default::default())
} else {
None
},
}
}
}
impl<O: SaffireProioMonitorSpecification> SaffireProioMonitorProtocol for O {}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq)]
pub struct SaffireProioMixerParameters {
pub monitor_sources: [i16; 10],
pub stream_source_pair0: [i16; 10],
pub stream_sources: [i16; 10],
}
impl SaffireParametersSerdes<SaffireProioMixerParameters> for SaffireProioMixerProtocol {
const OFFSETS: &'static [usize] = &[
0x0d0, 0x0d4, 0x0d8, 0x0dc, 0x0e0, 0x0e4, 0x0e8, 0x0ec, 0x0f0, 0x0f4, 0x0f8, 0x0fc, 0x100, 0x104, 0x108, 0x10c, 0x110, 0x114, 0x118, 0x11c, 0x120, 0x124, 0x128, 0x12c, 0x130, 0x134, 0x138, 0x13c, ];
fn serialize(params: &SaffireProioMixerParameters, raw: &mut [u8]) {
params
.monitor_sources
.iter()
.enumerate()
.for_each(|(i, &level)| {
let pos = calc_monitor_source_pos(i) * 4;
let level = level as i32;
raw[pos..(pos + 4)].copy_from_slice(&level.to_be_bytes());
});
params
.stream_source_pair0
.iter()
.enumerate()
.for_each(|(i, &level)| {
let pos = calc_stream_source_pair0_pos(i) * 4;
let level = level as i32;
raw[pos..(pos + 4)].copy_from_slice(&level.to_be_bytes());
});
params
.stream_sources
.iter()
.enumerate()
.for_each(|(i, &level)| {
let pos = calc_stream_source_pos(i) * 4;
let level = level as i32;
raw[pos..(pos + 4)].copy_from_slice(&level.to_be_bytes());
});
}
fn deserialize(params: &mut SaffireProioMixerParameters, raw: &[u8]) {
let mut quadlet = [0; 4];
let quads: Vec<i16> = (0..raw.len())
.step_by(4)
.map(|pos| {
quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
i32::from_be_bytes(quadlet) as i16
})
.collect();
params
.monitor_sources
.iter_mut()
.enumerate()
.for_each(|(i, level)| {
let pos = calc_monitor_source_pos(i);
*level = quads[pos];
});
params
.stream_source_pair0
.iter_mut()
.enumerate()
.for_each(|(i, level)| {
let pos = calc_stream_source_pair0_pos(i);
*level = quads[pos];
});
params
.stream_sources
.iter_mut()
.enumerate()
.for_each(|(i, level)| {
let pos = calc_stream_source_pos(i);
*level = quads[pos];
});
}
}
impl SaffireProioMixerProtocol {
pub const LEVEL_MIN: i16 = 0;
pub const LEVEL_MAX: i16 = 0x7fff;
pub const LEVEL_STEP: i16 = 0x100;
}
fn calc_monitor_source_pos(i: usize) -> usize {
if i < 2 {
1 + i * 2
} else {
6 + (i - 2) * 3
}
}
fn calc_stream_source_pair0_pos(i: usize) -> usize {
if i < 2 {
i * 2
} else {
4 + (i - 2) * 3
}
}
fn calc_stream_source_pos(i: usize) -> usize {
if i < 2 {
i * 2
} else {
5 + (i - 2) * 3
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum SaffireProioStandaloneMode {
Mix,
Track,
}
impl Default for SaffireProioStandaloneMode {
fn default() -> Self {
Self::Mix
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SaffireProioSpecificParameters {
pub head_room: bool,
pub phantom_powerings: Vec<bool>,
pub insert_swaps: Vec<bool>,
pub standalone_mode: SaffireProioStandaloneMode,
pub adat_enabled: bool,
pub direct_monitoring: bool,
}
pub trait SaffireProioSpecificSpecification {
const SPECIFIC_OFFSETS: &'static [usize] = &[
0x016c, 0x0188, 0x018c, 0x0190, 0x0194, 0x01bc, 0x01c0, 0x01c8, ];
const PHANTOM_POWERING_COUNT: usize;
const INSERT_SWAP_COUNT: usize;
}
impl<O: SaffireProioSpecificSpecification> SaffireParametersSerdes<SaffireProioSpecificParameters>
for O
{
const OFFSETS: &'static [usize] = Self::SPECIFIC_OFFSETS;
fn serialize(params: &SaffireProioSpecificParameters, raw: &mut [u8]) {
raw[..4].copy_from_slice(&(params.head_room as u32).to_be_bytes());
params
.phantom_powerings
.iter()
.rev()
.enumerate()
.for_each(|(i, &enabled)| {
let pos = 4 + i * 4;
raw[pos..(pos + 4)].copy_from_slice(&(enabled as u32).to_be_bytes());
});
params
.insert_swaps
.iter()
.enumerate()
.for_each(|(i, &enabled)| {
let pos = 12 + i * 4;
raw[pos..(pos + 4)].copy_from_slice(&(enabled as u32).to_be_bytes());
});
let val = (params.standalone_mode == SaffireProioStandaloneMode::Track) as u32;
raw[20..24].copy_from_slice(&val.to_be_bytes());
raw[24..28].copy_from_slice(&(!params.adat_enabled as u32).to_be_bytes());
raw[28..32].copy_from_slice(&(params.direct_monitoring as u32).to_be_bytes());
}
fn deserialize(params: &mut SaffireProioSpecificParameters, raw: &[u8]) {
let mut quadlet = [0; 4];
let quads: Vec<i16> = (0..raw.len())
.step_by(4)
.map(|pos| {
quadlet.copy_from_slice(&raw[pos..(pos + 4)]);
i32::from_be_bytes(quadlet) as i16
})
.collect();
params.head_room = quads[0] > 0;
params
.phantom_powerings
.iter_mut()
.rev()
.enumerate()
.for_each(|(i, enabled)| *enabled = quads[1 + i] > 0);
params
.insert_swaps
.iter_mut()
.enumerate()
.for_each(|(i, enabled)| *enabled = quads[3 + i] > 0);
params.standalone_mode = if quads[5] > 0 {
SaffireProioStandaloneMode::Track
} else {
SaffireProioStandaloneMode::Mix
};
params.adat_enabled = quads[6] == 0;
params.direct_monitoring = quads[7] > 0;
}
}
pub trait SaffireProioSpecificOperation: SaffireProioSpecificSpecification {
fn create_params() -> SaffireProioSpecificParameters {
SaffireProioSpecificParameters {
head_room: Default::default(),
phantom_powerings: vec![Default::default(); Self::PHANTOM_POWERING_COUNT],
insert_swaps: vec![Default::default(); Self::INSERT_SWAP_COUNT],
standalone_mode: Default::default(),
adat_enabled: Default::default(),
direct_monitoring: Default::default(),
}
}
}
impl<O: SaffireProioSpecificSpecification> SaffireProioSpecificOperation for O {}
#[derive(Default, Debug)]
pub struct SaffireProioStoreConfigProtocol;
impl SaffireStoreConfigSpecification for SaffireProioStoreConfigProtocol {
const STORE_CONFIG_OFFSETS: &'static [usize] = &[0x1b0];
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn saffireproio_output_protocol_serdes() {
let mut params = SaffireProioOutputProtocol::create_output_parameters();
params
.mutes
.iter_mut()
.step_by(2)
.for_each(|mute| *mute = true);
params
.vols
.iter_mut()
.enumerate()
.for_each(|(i, vol)| *vol = i as u8);
params
.hwctls
.iter_mut()
.step_by(2)
.for_each(|hwctl| *hwctl = true);
params
.dims
.iter_mut()
.step_by(2)
.for_each(|dim| *dim = true);
params
.pads
.iter_mut()
.step_by(2)
.for_each(|pad| *pad = true);
let mut raw = vec![0u8; SaffireProioOutputProtocol::OFFSETS.len() * 4];
SaffireProioOutputProtocol::serialize(¶ms, &mut raw);
let mut p = SaffireProioOutputProtocol::create_output_parameters();
SaffireProioOutputProtocol::deserialize(&mut p, &raw);
assert_eq!(params, p);
}
#[test]
fn saffirepro10io_monitor_protocol_serdes() {
let params = SaffireProioMonitorParameters {
analog_inputs: [
[45, 89, -17, -90, -28, 95, 32, -51],
[-2, -43, -34, 69, 27, 14, 37, 10],
],
spdif_inputs: [[84, 46], [42, -20]],
adat_inputs: None,
};
let mut raw = vec![0u8; SaffirePro10ioMonitorProtocol::OFFSETS.len() * 4];
SaffirePro10ioMonitorProtocol::serialize(¶ms, &mut raw);
let mut p = SaffirePro10ioMonitorProtocol::create_params();
SaffirePro10ioMonitorProtocol::deserialize(&mut p, &raw);
assert_eq!(params, p);
}
#[test]
fn saffirepro26io_monitor_protocol_serdes() {
let params = SaffireProioMonitorParameters {
analog_inputs: [
[45, 89, -17, -90, -28, 95, 32, -51],
[-2, -43, -34, 69, 27, 14, 37, 10],
],
spdif_inputs: [[84, 46], [42, -20]],
adat_inputs: Some([
[
38, 9, 20, 4, -9, 82, -41, -14, 88, -18, 58, 1, -98, -26, 54, 21,
],
[
58, 66, 42, -36, -50, 36, 50, -77, -99, -49, 52, -78, -51, -80, -40, 94,
],
]),
};
let mut raw = vec![0u8; SaffirePro26ioMonitorProtocol::OFFSETS.len() * 4];
SaffirePro26ioMonitorProtocol::serialize(¶ms, &mut raw);
let mut p = SaffirePro26ioMonitorProtocol::create_params();
SaffirePro26ioMonitorProtocol::deserialize(&mut p, &raw);
assert_eq!(params, p);
}
#[test]
fn saffirepro10io_specific_protocol_serdes() {
let mut params = SaffirePro10ioSpecificProtocol::create_params();
params.standalone_mode = SaffireProioStandaloneMode::Track;
params.adat_enabled = true;
params.direct_monitoring = true;
let mut raw = vec![0u8; SaffirePro10ioSpecificProtocol::OFFSETS.len() * 4];
SaffirePro10ioSpecificProtocol::serialize(¶ms, &mut raw);
let mut p = SaffirePro10ioSpecificProtocol::create_params();
SaffirePro10ioSpecificProtocol::deserialize(&mut p, &raw);
assert_eq!(params, p);
}
#[test]
fn saffirepro26io_specific_protocol_serdes() {
let mut params = SaffirePro26ioSpecificProtocol::create_params();
params.phantom_powerings[0] = true;
params.phantom_powerings[1] = false;
params.insert_swaps[0] = false;
params.insert_swaps[1] = true;
params.standalone_mode = SaffireProioStandaloneMode::Track;
params.adat_enabled = true;
params.direct_monitoring = true;
let mut raw = vec![0u8; SaffirePro26ioSpecificProtocol::OFFSETS.len() * 4];
SaffirePro26ioSpecificProtocol::serialize(¶ms, &mut raw);
let mut p = SaffirePro26ioSpecificProtocol::create_params();
SaffirePro26ioSpecificProtocol::deserialize(&mut p, &raw);
assert_eq!(params, p);
}
#[test]
#[should_panic(expected = "expected to fail")]
fn saffireproio_mixer_protocol_serdes() {
let params = SaffireProioMixerParameters {
monitor_sources: [-6, 25, 32, 76, 91, 57, -21, 88, 9, -87],
stream_source_pair0: [84, -65, 59, 2, -21, 96, 40, 67, 72, 30],
stream_sources: [-78, -75, -58, 86, 16, 59, 41, 88, 57, 24],
};
let mut raw = vec![0u8; SaffireProioMixerProtocol::OFFSETS.len() * 4];
SaffireProioMixerProtocol::serialize(¶ms, &mut raw);
let mut p = SaffireProioMixerParameters::default();
SaffireProioMixerProtocol::deserialize(&mut p, &raw);
assert_eq!(params, p, "expected to fail");
}
#[test]
fn saffireproio_through_protocol_serdes() {
let params = SaffireThroughParameters {
midi: true,
ac3: true,
};
let mut raw = vec![0u8; SaffireProioThroughProtocol::OFFSETS.len() * 4];
SaffireProioThroughProtocol::serialize(¶ms, &mut raw);
let mut p = SaffireThroughParameters::default();
SaffireProioThroughProtocol::deserialize(&mut p, &raw);
assert_eq!(params, p);
}
#[test]
fn saffirepro10io_media_clock_serdes() {
let mut raw = [0u8; 4];
(0..SaffirePro10ioClkProtocol::FREQ_LIST.len()).for_each(|freq_idx| {
let params = MediaClockParameters { freq_idx };
SaffirePro10ioClkProtocol::serialize(¶ms, &mut raw);
let mut p = MediaClockParameters::default();
SaffirePro10ioClkProtocol::deserialize(&mut p, &raw);
assert_eq!(params, p);
});
}
#[test]
fn saffirepro26io_media_clock_serdes() {
let mut raw = [0u8; 4];
(0..SaffirePro26ioClkProtocol::FREQ_LIST.len()).for_each(|freq_idx| {
let params = MediaClockParameters { freq_idx };
SaffirePro26ioClkProtocol::serialize(¶ms, &mut raw);
let mut p = MediaClockParameters::default();
SaffirePro26ioClkProtocol::deserialize(&mut p, &raw);
assert_eq!(params, p);
});
}
#[test]
fn saffirepro10io_sampling_clock_serdes() {
let mut raw = [0u8; 4];
(0..SaffirePro10ioClkProtocol::SRC_LIST.len()).for_each(|src_idx| {
let params = SamplingClockParameters { src_idx };
SaffirePro10ioClkProtocol::serialize(¶ms, &mut raw);
let mut p = SamplingClockParameters::default();
SaffirePro10ioClkProtocol::deserialize(&mut p, &raw);
assert_eq!(params, p);
});
}
#[test]
fn saffirepro26io_sampling_clock_serdes() {
let mut raw = [0u8; 4];
(0..SaffirePro26ioClkProtocol::SRC_LIST.len()).for_each(|src_idx| {
let params = SamplingClockParameters { src_idx };
SaffirePro26ioClkProtocol::serialize(¶ms, &mut raw);
let mut p = SamplingClockParameters::default();
SaffirePro26ioClkProtocol::deserialize(&mut p, &raw);
assert_eq!(params, p);
});
}
#[test]
fn test_mixer_offset_helpers() {
assert_eq!(calc_monitor_source_pos(0), 1);
assert_eq!(calc_monitor_source_pos(1), 3);
assert_eq!(calc_monitor_source_pos(2), 6);
assert_eq!(calc_monitor_source_pos(3), 9);
assert_eq!(calc_monitor_source_pos(4), 12);
assert_eq!(calc_monitor_source_pos(5), 15);
assert_eq!(calc_monitor_source_pos(6), 18);
assert_eq!(calc_monitor_source_pos(7), 21);
assert_eq!(calc_monitor_source_pos(8), 24);
assert_eq!(calc_monitor_source_pos(9), 27);
assert_eq!(calc_stream_source_pair0_pos(0), 0);
assert_eq!(calc_stream_source_pair0_pos(1), 2);
assert_eq!(calc_stream_source_pair0_pos(2), 4);
assert_eq!(calc_stream_source_pair0_pos(3), 7);
assert_eq!(calc_stream_source_pair0_pos(4), 10);
assert_eq!(calc_stream_source_pair0_pos(5), 13);
assert_eq!(calc_stream_source_pair0_pos(6), 16);
assert_eq!(calc_stream_source_pair0_pos(7), 19);
assert_eq!(calc_stream_source_pair0_pos(8), 22);
assert_eq!(calc_stream_source_pair0_pos(9), 25);
assert_eq!(calc_stream_source_pos(0), 0);
assert_eq!(calc_stream_source_pos(1), 2);
assert_eq!(calc_stream_source_pos(2), 5);
assert_eq!(calc_stream_source_pos(3), 8);
assert_eq!(calc_stream_source_pos(4), 11);
assert_eq!(calc_stream_source_pos(5), 14);
assert_eq!(calc_stream_source_pos(6), 17);
assert_eq!(calc_stream_source_pos(7), 20);
assert_eq!(calc_stream_source_pos(8), 23);
assert_eq!(calc_stream_source_pos(9), 26);
}
}