use crate::config::VolumeCtrl; pub mod mappings; use self::mappings::MappedCtrl; pub trait Mixer: Send { fn open(config: MixerConfig) -> Self where Self: Sized; fn set_volume(&self, volume: u16); fn volume(&self) -> u16; fn get_audio_filter(&self) -> Option> { None } } pub trait AudioFilter { fn modify_stream(&self, data: &mut [f64]); } pub mod softmixer; use self::softmixer::SoftMixer; #[cfg(feature = "alsa-backend")] pub mod alsamixer; #[cfg(feature = "alsa-backend")] use self::alsamixer::AlsaMixer; #[derive(Debug, Clone)] pub struct MixerConfig { pub device: String, pub control: String, pub index: u32, pub volume_ctrl: VolumeCtrl, } impl Default for MixerConfig { fn default() -> MixerConfig { MixerConfig { device: String::from("default"), control: String::from("PCM"), index: 0, volume_ctrl: VolumeCtrl::default(), } } } pub type MixerFn = fn(MixerConfig) -> Box; fn mk_sink(config: MixerConfig) -> Box { Box::new(M::open(config)) } pub const MIXERS: &[(&str, MixerFn)] = &[ (SoftMixer::NAME, mk_sink::), // default goes first #[cfg(feature = "alsa-backend")] (AlsaMixer::NAME, mk_sink::), ]; pub fn find(name: Option<&str>) -> Option { if let Some(name) = name { MIXERS .iter() .find(|mixer| name == mixer.0) .map(|mixer| mixer.1) } else { MIXERS.first().map(|mixer| mixer.1) } }