use crate::Sound;
use super::{SetPaused, SetSpeed};
pub trait SetVolume {
fn set_volume(&mut self, multiplier: f32);
}
pub struct AdjustableVolume<S: Sound> {
inner: S,
volume_adjustment: f32,
}
impl<S> AdjustableVolume<S>
where
S: Sound,
{
pub fn new(inner: S) -> Self {
AdjustableVolume {
inner,
volume_adjustment: 1.0,
}
}
pub fn new_with_volume(inner: S, volume_adjustment: f32) -> Self {
AdjustableVolume {
inner,
volume_adjustment,
}
}
pub fn inner(&self) -> &S {
&self.inner
}
pub fn inner_mut(&mut self) -> &mut S {
&mut self.inner
}
pub fn into_inner(self) -> S {
self.inner
}
}
impl<S> Sound for AdjustableVolume<S>
where
S: Sound,
{
fn channel_count(&self) -> u16 {
self.inner.channel_count()
}
fn sample_rate(&self) -> u32 {
self.inner.sample_rate()
}
fn next_sample(&mut self) -> Result<crate::NextSample, crate::Error> {
let next = self.inner.next_sample()?;
Ok(match next {
crate::NextSample::Sample(s) => {
let adjusted = (s as f32 * self.volume_adjustment) as i16;
crate::NextSample::Sample(adjusted)
}
crate::NextSample::MetadataChanged
| crate::NextSample::Paused
| crate::NextSample::Finished => next,
})
}
fn on_start_of_batch(&mut self) {
self.inner.on_start_of_batch()
}
}
impl<S> AdjustableVolume<S>
where
S: Sound,
{
pub fn volume(&self) -> f32 {
self.volume_adjustment
}
}
impl<S> SetVolume for AdjustableVolume<S>
where
S: Sound,
{
fn set_volume(&mut self, new: f32) {
self.volume_adjustment = new;
}
}
impl<S> SetPaused for AdjustableVolume<S>
where
S: Sound + SetPaused,
{
fn set_paused(&mut self, paused: bool) {
self.inner.set_paused(paused)
}
}
impl<S> SetSpeed for AdjustableVolume<S>
where
S: Sound + SetSpeed,
{
fn set_speed(&mut self, multiplier: f32) {
self.inner.set_speed(multiplier)
}
}
#[cfg(test)]
#[path = "./tests/adjustable_volume.rs"]
mod tests;