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