1use std::cmp;
2use std::time::Duration;
3
4use super::SeekError;
5use crate::common::{ChannelCount, SampleRate};
6use crate::conversions::{ChannelCountConverter, SampleRateConverter};
7use crate::Source;
8
9#[derive(Clone)]
15pub struct UniformSourceIterator<I>
16where
17 I: Source,
18{
19 inner: Option<ChannelCountConverter<SampleRateConverter<Take<I>>>>,
20 target_channels: ChannelCount,
21 target_sample_rate: SampleRate,
22 total_duration: Option<Duration>,
23}
24
25impl<I> UniformSourceIterator<I>
26where
27 I: Source,
28{
29 #[inline]
32 pub fn new(
33 input: I,
34 target_channels: ChannelCount,
35 target_sample_rate: SampleRate,
36 ) -> UniformSourceIterator<I> {
37 let total_duration = input.total_duration();
38 let input = UniformSourceIterator::bootstrap(input, target_channels, target_sample_rate);
39
40 UniformSourceIterator {
41 inner: Some(input),
42 target_channels,
43 target_sample_rate,
44 total_duration,
45 }
46 }
47
48 #[inline]
49 fn bootstrap(
50 input: I,
51 target_channels: ChannelCount,
52 target_sample_rate: SampleRate,
53 ) -> ChannelCountConverter<SampleRateConverter<Take<I>>> {
54 let span_len = input.current_span_len().map(|x| x.min(32768));
56
57 let from_channels = input.channels();
58 let from_sample_rate = input.sample_rate();
59
60 let input = Take {
61 iter: input,
62 n: span_len,
63 };
64 let input =
65 SampleRateConverter::new(input, from_sample_rate, target_sample_rate, from_channels);
66 ChannelCountConverter::new(input, from_channels, target_channels)
67 }
68}
69
70impl<I> Iterator for UniformSourceIterator<I>
71where
72 I: Source,
73{
74 type Item = I::Item;
75
76 #[inline]
77 fn next(&mut self) -> Option<Self::Item> {
78 if let Some(value) = self.inner.as_mut().unwrap().next() {
79 return Some(value);
80 }
81
82 let input = self.inner.take().unwrap().into_inner().into_inner().iter;
83
84 let mut input =
85 UniformSourceIterator::bootstrap(input, self.target_channels, self.target_sample_rate);
86
87 let value = input.next();
88 self.inner = Some(input);
89 value
90 }
91
92 #[inline]
93 fn size_hint(&self) -> (usize, Option<usize>) {
94 (self.inner.as_ref().unwrap().size_hint().0, None)
95 }
96}
97
98impl<I> Source for UniformSourceIterator<I>
99where
100 I: Iterator + Source,
101{
102 #[inline]
103 fn current_span_len(&self) -> Option<usize> {
104 None
105 }
106
107 #[inline]
108 fn channels(&self) -> ChannelCount {
109 self.target_channels
110 }
111
112 #[inline]
113 fn sample_rate(&self) -> SampleRate {
114 self.target_sample_rate
115 }
116
117 #[inline]
118 fn total_duration(&self) -> Option<Duration> {
119 self.total_duration
120 }
121
122 #[inline]
123 fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
124 if let Some(input) = self.inner.as_mut() {
125 input.inner_mut().inner_mut().inner_mut().try_seek(pos)
126 } else {
127 Ok(())
128 }
129 }
130}
131
132#[derive(Clone, Debug)]
133struct Take<I> {
134 iter: I,
135 n: Option<usize>,
136}
137
138impl<I> Take<I> {
139 #[inline]
140 pub fn inner_mut(&mut self) -> &mut I {
141 &mut self.iter
142 }
143}
144
145impl<I> Iterator for Take<I>
146where
147 I: Iterator,
148{
149 type Item = <I as Iterator>::Item;
150
151 #[inline]
152 fn next(&mut self) -> Option<<I as Iterator>::Item> {
153 if let Some(n) = &mut self.n {
154 if *n != 0 {
155 *n -= 1;
156 self.iter.next()
157 } else {
158 None
159 }
160 } else {
161 self.iter.next()
162 }
163 }
164
165 #[inline]
166 fn size_hint(&self) -> (usize, Option<usize>) {
167 if let Some(n) = self.n {
168 let (lower, upper) = self.iter.size_hint();
169
170 let lower = cmp::min(lower, n);
171
172 let upper = match upper {
173 Some(x) if x < n => Some(x),
174 _ => Some(n),
175 };
176
177 (lower, upper)
178 } else {
179 self.iter.size_hint()
180 }
181 }
182}
183
184impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}