diff --git a/src/mixer/mod.rs b/src/mixer/mod.rs index 285bde0c..cb67a6d7 100644 --- a/src/mixer/mod.rs +++ b/src/mixer/mod.rs @@ -3,12 +3,17 @@ use std::borrow::Cow; pub mod softmixer; pub trait Mixer { - fn init(&mut self); - fn inuse(&mut self); - fn release(&mut self); - fn set_volume(&mut self, volume: u16); + fn init(&self); + fn start(&self); + fn stop(&self); + fn set_volume(&self, volume: u16); fn volume(&self) -> u16; - fn apply_volume<'a>(&mut self, data: &'a [i16]) -> Cow<'a, [i16]> { - Cow::Borrowed(data) + fn get_stream_editor(&self) -> Option> + { + None } +} + +pub trait StreamEditor { + fn modify_stream<'a>(&self, data: &'a [i16]) -> Cow<'a, [i16]>; } \ No newline at end of file diff --git a/src/mixer/softmixer.rs b/src/mixer/softmixer.rs index 8a36fa90..7dfd1f6b 100644 --- a/src/mixer/softmixer.rs +++ b/src/mixer/softmixer.rs @@ -1,43 +1,53 @@ use super::Mixer; +use super::StreamEditor; use std::borrow::Cow; +use std::sync::{Arc, RwLock}; pub struct SoftMixer { - volume: u16, + volume: Arc> } impl SoftMixer { pub fn new() -> SoftMixer { SoftMixer { - volume: 0xFFFF + volume: Arc::new(RwLock::new(0xFFFF)) } } } impl Mixer for SoftMixer { - fn init(&mut self) { + fn init(&self) { } - - fn inuse(&mut self) { + fn start(&self) { } - - fn release(&mut self) { + fn stop(&self) { } - - fn set_volume(&mut self, volume: u16) { - self.volume = volume; - } - fn volume(&self) -> u16 { - self.volume + *self.volume.read().unwrap() } - fn apply_volume<'a>(&mut self, data: &'a [i16]) -> Cow<'a, [i16]> { - if self.volume == 0xFFFF { + fn set_volume(&self, volume: u16) { + *self.volume.write().unwrap() = volume; + } + fn get_stream_editor(&self) -> Option> { + let vol = self.volume.clone(); + Some(Box::new(SoftVolumeApplier { get_volume: Box::new(move || *vol.read().unwrap() ) })) + } +} + +struct SoftVolumeApplier { + get_volume: Box u16> +} + +impl StreamEditor for SoftVolumeApplier { + fn modify_stream<'a>(&self, data: &'a [i16]) -> Cow<'a, [i16]> { + let volume = (self.get_volume)(); + if volume == 0xFFFF { Cow::Borrowed(data) } else { Cow::Owned(data.iter() .map(|&x| { (x as i32 - * self.volume as i32 + * volume as i32 / 0xFFFF) as i16 }) .collect())