1use std::time::Duration;
2
3use super::SeekError;
4use crate::common::{ChannelCount, SampleRate};
5use crate::Source;
6
7pub fn pausable<I>(source: I, paused: bool) -> Pausable<I>
9where
10 I: Source,
11{
12 let paused_channels = if paused {
13 Some(source.channels())
14 } else {
15 None
16 };
17 Pausable {
18 input: source,
19 paused_channels,
20 remaining_paused_samples: 0,
21 }
22}
23
24#[derive(Clone, Debug)]
31pub struct Pausable<I> {
32 input: I,
33 paused_channels: Option<ChannelCount>,
34 remaining_paused_samples: ChannelCount,
35}
36
37impl<I> Pausable<I>
38where
39 I: Source,
40{
41 #[inline]
45 pub fn set_paused(&mut self, paused: bool) {
46 match (self.paused_channels, paused) {
47 (None, true) => self.paused_channels = Some(self.input.channels()),
48 (Some(_), false) => self.paused_channels = None,
49 _ => (),
50 }
51 }
52
53 #[inline]
55 pub fn is_paused(&self) -> bool {
56 self.paused_channels.is_some()
57 }
58
59 #[inline]
61 pub fn inner(&self) -> &I {
62 &self.input
63 }
64
65 #[inline]
67 pub fn inner_mut(&mut self) -> &mut I {
68 &mut self.input
69 }
70
71 #[inline]
73 pub fn into_inner(self) -> I {
74 self.input
75 }
76}
77
78impl<I> Iterator for Pausable<I>
79where
80 I: Source,
81{
82 type Item = I::Item;
83
84 #[inline]
85 fn next(&mut self) -> Option<I::Item> {
86 if self.remaining_paused_samples > 0 {
87 self.remaining_paused_samples -= 1;
88 return Some(0.0);
89 }
90
91 if let Some(paused_channels) = self.paused_channels {
92 self.remaining_paused_samples = paused_channels - 1;
93 return Some(0.0);
94 }
95
96 self.input.next()
97 }
98
99 #[inline]
100 fn size_hint(&self) -> (usize, Option<usize>) {
101 self.input.size_hint()
102 }
103}
104
105impl<I> Source for Pausable<I>
106where
107 I: Source,
108{
109 #[inline]
110 fn current_span_len(&self) -> Option<usize> {
111 self.input.current_span_len()
112 }
113
114 #[inline]
115 fn channels(&self) -> ChannelCount {
116 self.input.channels()
117 }
118
119 #[inline]
120 fn sample_rate(&self) -> SampleRate {
121 self.input.sample_rate()
122 }
123
124 #[inline]
125 fn total_duration(&self) -> Option<Duration> {
126 self.input.total_duration()
127 }
128
129 #[inline]
130 fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
131 self.input.try_seek(pos)
132 }
133}