use std::time::Duration; use crate::{Sample, Source}; use super::SeekError; /// Builds a `Pausable` object. pub fn pausable(source: I, paused: bool) -> Pausable where I: Source, I::Item: Sample, { let paused_channels = if paused { Some(source.channels()) } else { None }; Pausable { input: source, paused_channels, remaining_paused_samples: 0, } } /// Wraps a source and makes it pausable by calling [`Pausable::set_paused`] on /// this object. When the source is paused it returns zero value samples. /// /// You can usually still use this from another source wrapping this one by /// calling `inner_mut` on it. Similarly this provides [`Pausable::inner`] and /// mutable/destructing variants for accessing the underlying source. #[derive(Clone, Debug)] pub struct Pausable { input: I, paused_channels: Option, remaining_paused_samples: u16, } impl Pausable where I: Source, I::Item: Sample, { /// Sets whether the filter applies. /// /// If set to true, the inner sound stops playing and no samples are processed from it. #[inline] pub fn set_paused(&mut self, paused: bool) { match (self.paused_channels, paused) { (None, true) => self.paused_channels = Some(self.input.channels()), (Some(_), false) => self.paused_channels = None, _ => (), } } /// Returns a reference to the inner source. #[inline] pub fn inner(&self) -> &I { &self.input } /// Returns a mutable reference to the inner source. #[inline] pub fn inner_mut(&mut self) -> &mut I { &mut self.input } /// Returns the inner source. #[inline] pub fn into_inner(self) -> I { self.input } } impl Iterator for Pausable where I: Source, I::Item: Sample, { type Item = I::Item; #[inline] fn next(&mut self) -> Option { if self.remaining_paused_samples > 0 { self.remaining_paused_samples -= 1; return Some(I::Item::zero_value()); } if let Some(paused_channels) = self.paused_channels { self.remaining_paused_samples = paused_channels - 1; return Some(I::Item::zero_value()); } self.input.next() } #[inline] fn size_hint(&self) -> (usize, Option) { self.input.size_hint() } } impl Source for Pausable where I: Source, I::Item: Sample, { #[inline] fn current_frame_len(&self) -> Option { self.input.current_frame_len() } #[inline] fn channels(&self) -> u16 { self.input.channels() } #[inline] fn sample_rate(&self) -> u32 { self.input.sample_rate() } #[inline] fn total_duration(&self) -> Option { self.input.total_duration() } #[inline] fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> { self.input.try_seek(pos) } }