From d8723a51366305aef6e6f271e33ac7bfdbd16655 Mon Sep 17 00:00:00 2001 From: Cocalus Date: Sat, 16 Nov 2019 13:11:20 -0800 Subject: [PATCH] Generate samples at a multiple of channels (#249) * Generate samples at a multiple of channels * Fix nits --- src/source/delay.rs | 2 +- src/source/pausable.rs | 37 +++++++++++++++++++++++++++++++------ src/source/periodic.rs | 3 +-- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/source/delay.rs b/src/source/delay.rs index 8fb933a9..0fcd1fae 100644 --- a/src/source/delay.rs +++ b/src/source/delay.rs @@ -10,7 +10,7 @@ where I::Item: Sample, { let duration_ns = duration.as_secs() * 1000000000 + duration.subsec_nanos() as u64; - let samples = duration_ns * input.sample_rate() as u64 * input.channels() as u64 / 1000000000; + let samples = duration_ns * input.sample_rate() as u64 / 1000000000 * input.channels() as u64; Delay { input: input, diff --git a/src/source/pausable.rs b/src/source/pausable.rs index f01ad4e9..9a0b6e0e 100644 --- a/src/source/pausable.rs +++ b/src/source/pausable.rs @@ -4,26 +4,45 @@ use Sample; use Source; /// Internal function that builds a `Pausable` object. -pub fn pausable(source: I, paused: bool) -> Pausable { +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: paused, + paused_channels, + remaining_paused_samples: 0, } } #[derive(Clone, Debug)] pub struct Pausable { input: I, - paused: bool, + paused_channels: Option, + remaining_paused_samples: u16, } -impl Pausable { +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) { - self.paused = paused; + 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. @@ -54,7 +73,13 @@ where #[inline] fn next(&mut self) -> Option { - if self.paused { + 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()); } diff --git a/src/source/periodic.rs b/src/source/periodic.rs index 14727196..d8daebe1 100644 --- a/src/source/periodic.rs +++ b/src/source/periodic.rs @@ -12,8 +12,7 @@ where // TODO: handle the fact that the samples rate can change // TODO: generally, just wrong let update_ms = period.as_secs() as u32 * 1_000 + period.subsec_nanos() / 1_000_000; - let sample_rate = source.sample_rate() * source.channels() as u32; - let update_frequency = (update_ms * sample_rate) / 1000; + let update_frequency = (update_ms * source.sample_rate()) / 1000 * source.channels() as u32; PeriodicAccess { input: source,