use std::{ffi::OsString, io::Result};
use super::{
util::{FunctionDir, Status},
Function, Handle,
};
#[derive(Debug, Clone, Default)]
pub struct Channel {
pub channel_mask: Option<u32>,
pub sample_rate: Option<u32>,
pub sample_size: Option<u32>,
}
impl Channel {
pub fn new(channel_mask: u32, sample_rate: u32, sample_size: u32) -> Self {
Self { channel_mask: Some(channel_mask), sample_rate: Some(sample_rate), sample_size: Some(sample_size) }
}
}
#[derive(Debug, Clone, Default)]
#[non_exhaustive]
pub struct Uac2Config {
pub channel: Channel,
pub sync_type: Option<u32>,
pub hs_interval: Option<u8>,
pub mute_present: Option<bool>,
pub terminal_type: Option<u8>,
pub volume_present: Option<bool>,
pub volume_min: Option<i16>,
pub volume_max: Option<i16>,
pub volume_resolution: Option<i16>,
pub volume_name: Option<String>,
pub input_terminal_name: Option<String>,
pub input_terminal_channel_name: Option<String>,
pub output_terminal_name: Option<String>,
}
#[derive(Debug, Clone, Default)]
#[non_exhaustive]
pub struct Uac2Builder {
pub capture: Uac2Config,
pub playback: Uac2Config,
pub fb_max: Option<u32>,
pub request_number: Option<u32>,
pub function_name: Option<String>,
pub control_name: Option<String>,
pub clock_source_in_name: Option<String>,
pub clock_source_out_name: Option<String>,
}
impl Uac2Builder {
pub fn build(self) -> (Uac2, Handle) {
let dir = FunctionDir::new();
(Uac2 { dir: dir.clone() }, Handle::new(Uac2Function { builder: self, dir }))
}
#[must_use]
pub fn with_capture_config(mut self, capture: Uac2Config) -> Self {
self.capture = capture;
self
}
#[must_use]
pub fn with_playback_config(mut self, playback: Uac2Config) -> Self {
self.playback = playback;
self
}
}
#[derive(Debug)]
struct Uac2Function {
builder: Uac2Builder,
dir: FunctionDir,
}
impl Function for Uac2Function {
fn driver(&self) -> OsString {
"uac2".into()
}
fn dir(&self) -> FunctionDir {
self.dir.clone()
}
fn register(&self) -> Result<()> {
if let Some(channel_mask) = self.builder.capture.channel.channel_mask {
self.dir.write("c_chmask", channel_mask.to_string())?;
}
if let Some(sample_rate) = self.builder.capture.channel.sample_rate {
self.dir.write("c_srate", sample_rate.to_string())?;
}
if let Some(sample_size) = self.builder.capture.channel.sample_size {
self.dir.write("c_ssize", sample_size.to_string())?;
}
if let Some(sync_type) = self.builder.capture.sync_type {
self.dir.write("c_sync", sync_type.to_string())?;
}
if let Some(hs_interval) = self.builder.capture.hs_interval {
self.dir.write("c_hs_bint", hs_interval.to_string())?;
}
if let Some(mute_present) = self.builder.capture.mute_present {
self.dir.write("c_mute_present", (mute_present as u8).to_string())?;
}
if let Some(volume_present) = self.builder.capture.volume_present {
self.dir.write("c_volume_present", (volume_present as u8).to_string())?;
}
if let Some(volume_min) = self.builder.capture.volume_min {
self.dir.write("c_volume_min", volume_min.to_string())?;
}
if let Some(volume_max) = self.builder.capture.volume_max {
self.dir.write("c_volume_max", volume_max.to_string())?;
}
if let Some(volume_resolution) = self.builder.capture.volume_resolution {
self.dir.write("c_volume_res", volume_resolution.to_string())?;
}
if let Some(volume_name) = &self.builder.capture.volume_name {
self.dir.write("c_fu_vol_name", volume_name)?;
}
if let Some(terminal_type) = self.builder.capture.terminal_type {
self.dir.write("c_terminal_type", terminal_type.to_string())?;
}
if let Some(input_terminal_name) = &self.builder.capture.input_terminal_name {
self.dir.write("c_it_name", input_terminal_name)?;
}
if let Some(input_terminal_channel_name) = &self.builder.capture.input_terminal_channel_name {
self.dir.write("c_it_ch_name", input_terminal_channel_name)?;
}
if let Some(output_terminal_name) = &self.builder.capture.output_terminal_name {
self.dir.write("c_ot_name", output_terminal_name)?;
}
if let Some(channel_mask) = self.builder.playback.channel.channel_mask {
self.dir.write("p_chmask", channel_mask.to_string())?;
}
if let Some(sample_rate) = self.builder.playback.channel.sample_rate {
self.dir.write("p_srate", sample_rate.to_string())?;
}
if let Some(sample_size) = self.builder.playback.channel.sample_size {
self.dir.write("p_ssize", sample_size.to_string())?;
}
if let Some(hs_interval) = self.builder.playback.hs_interval {
self.dir.write("p_hs_bint", hs_interval.to_string())?;
}
if let Some(mute_present) = self.builder.playback.mute_present {
self.dir.write("p_mute_present", (mute_present as u8).to_string())?;
}
if let Some(volume_present) = self.builder.playback.volume_present {
self.dir.write("p_volume_present", (volume_present as u8).to_string())?;
}
if let Some(volume_min) = self.builder.playback.volume_min {
self.dir.write("p_volume_min", volume_min.to_string())?;
}
if let Some(volume_max) = self.builder.playback.volume_max {
self.dir.write("p_volume_max", volume_max.to_string())?;
}
if let Some(volume_resolution) = self.builder.playback.volume_resolution {
self.dir.write("p_volume_res", volume_resolution.to_string())?;
}
if let Some(volume_name) = &self.builder.playback.volume_name {
self.dir.write("p_fu_vol_name", volume_name)?;
}
if let Some(terminal_type) = self.builder.playback.terminal_type {
self.dir.write("p_terminal_type", terminal_type.to_string())?;
}
if let Some(input_terminal_name) = &self.builder.playback.input_terminal_name {
self.dir.write("p_it_name", input_terminal_name)?;
}
if let Some(input_terminal_channel_name) = &self.builder.playback.input_terminal_channel_name {
self.dir.write("p_it_ch_name", input_terminal_channel_name)?;
}
if let Some(output_terminal_name) = &self.builder.playback.output_terminal_name {
self.dir.write("p_ot_name", output_terminal_name)?;
}
if let Some(fb_max) = self.builder.fb_max {
self.dir.write("fb_max", fb_max.to_string())?;
}
if let Some(request_number) = self.builder.request_number {
self.dir.write("req_number", request_number.to_string())?;
}
if let Some(function_name) = &self.builder.function_name {
self.dir.write("function_name", function_name)?;
}
if let Some(control_name) = &self.builder.control_name {
self.dir.write("if_ctrl_name", control_name)?;
}
if let Some(clock_source_in_name) = &self.builder.clock_source_in_name {
self.dir.write("clksrc_in_name", clock_source_in_name)?;
}
if let Some(clock_source_out_name) = &self.builder.clock_source_out_name {
self.dir.write("clksrc_out_name", clock_source_out_name)?;
}
Ok(())
}
}
#[derive(Debug)]
pub struct Uac2 {
dir: FunctionDir,
}
impl Uac2 {
pub fn builder() -> Uac2Builder {
Uac2Builder::default()
}
pub fn new(capture: Channel, playback: Channel) -> (Uac2, Handle) {
let mut builder = Uac2Builder::default();
builder.capture.channel = capture;
builder.playback.channel = playback;
builder.build()
}
pub fn status(&self) -> Status {
self.dir.status()
}
}