1 use std::cmp;
2 use std::time::Duration;
3 
4 use cpal;
5 
6 use conversions::ChannelCountConverter;
7 use conversions::DataConverter;
8 use conversions::SampleRateConverter;
9 
10 use Sample;
11 use Source;
12 
13 /// An iterator that reads from a `Source` and converts the samples to a specific rate and
14 /// channels count.
15 ///
16 /// It implements `Source` as well, but all the data is guaranteed to be in a single frame whose
17 /// channels and samples rate have been passed to `new`.
18 #[derive(Clone)]
19 pub struct UniformSourceIterator<I, D>
20 where
21     I: Source,
22     I::Item: Sample,
23     D: Sample,
24 {
25     inner: Option<DataConverter<ChannelCountConverter<SampleRateConverter<Take<I>>>, D>>,
26     target_channels: u16,
27     target_sample_rate: u32,
28     total_duration: Option<Duration>,
29 }
30 
31 impl<I, D> UniformSourceIterator<I, D>
32 where
33     I: Source,
34     I::Item: Sample,
35     D: Sample,
36 {
37     #[inline]
new( input: I, target_channels: u16, target_sample_rate: u32, ) -> UniformSourceIterator<I, D>38     pub fn new(
39         input: I, target_channels: u16, target_sample_rate: u32,
40     ) -> UniformSourceIterator<I, D> {
41         let total_duration = input.total_duration();
42         let input = UniformSourceIterator::bootstrap(input, target_channels, target_sample_rate);
43 
44         UniformSourceIterator {
45             inner: Some(input),
46             target_channels: target_channels,
47             target_sample_rate: target_sample_rate,
48             total_duration: total_duration,
49         }
50     }
51 
52     #[inline]
bootstrap( input: I, target_channels: u16, target_sample_rate: u32, ) -> DataConverter<ChannelCountConverter<SampleRateConverter<Take<I>>>, D>53     fn bootstrap(
54         input: I, target_channels: u16, target_sample_rate: u32,
55     ) -> DataConverter<ChannelCountConverter<SampleRateConverter<Take<I>>>, D> {
56         let frame_len = input.current_frame_len();
57 
58         let from_channels = input.channels();
59         let from_sample_rate = input.sample_rate();
60 
61         let input = Take {
62             iter: input,
63             n: frame_len,
64         };
65         let input = SampleRateConverter::new(
66             input,
67             cpal::SampleRate(from_sample_rate),
68             cpal::SampleRate(target_sample_rate),
69             from_channels,
70         );
71         let input = ChannelCountConverter::new(input, from_channels, target_channels);
72         let input = DataConverter::new(input);
73 
74         input
75     }
76 }
77 
78 impl<I, D> Iterator for UniformSourceIterator<I, D>
79 where
80     I: Source,
81     I::Item: Sample,
82     D: Sample,
83 {
84     type Item = D;
85 
86     #[inline]
next(&mut self) -> Option<D>87     fn next(&mut self) -> Option<D> {
88         if let Some(value) = self.inner.as_mut().unwrap().next() {
89             return Some(value);
90         }
91 
92         let input = self.inner
93             .take()
94             .unwrap()
95             .into_inner()
96             .into_inner()
97             .into_inner()
98             .iter;
99 
100         let mut input =
101             UniformSourceIterator::bootstrap(input, self.target_channels, self.target_sample_rate);
102 
103         let value = input.next();
104         self.inner = Some(input);
105         value
106     }
107 
108     #[inline]
size_hint(&self) -> (usize, Option<usize>)109     fn size_hint(&self) -> (usize, Option<usize>) {
110         (self.inner.as_ref().unwrap().size_hint().0, None)
111     }
112 }
113 
114 impl<I, D> Source for UniformSourceIterator<I, D>
115 where
116     I: Iterator + Source,
117     I::Item: Sample,
118     D: Sample,
119 {
120     #[inline]
current_frame_len(&self) -> Option<usize>121     fn current_frame_len(&self) -> Option<usize> {
122         None
123     }
124 
125     #[inline]
channels(&self) -> u16126     fn channels(&self) -> u16 {
127         self.target_channels
128     }
129 
130     #[inline]
sample_rate(&self) -> u32131     fn sample_rate(&self) -> u32 {
132         self.target_sample_rate
133     }
134 
135     #[inline]
total_duration(&self) -> Option<Duration>136     fn total_duration(&self) -> Option<Duration> {
137         self.total_duration
138     }
139 }
140 
141 #[derive(Clone, Debug)]
142 struct Take<I> {
143     iter: I,
144     n: Option<usize>,
145 }
146 
147 impl<I> Iterator for Take<I>
148 where
149     I: Iterator,
150 {
151     type Item = <I as Iterator>::Item;
152 
153     #[inline]
next(&mut self) -> Option<<I as Iterator>::Item>154     fn next(&mut self) -> Option<<I as Iterator>::Item> {
155         if let Some(ref mut n) = self.n {
156             if *n != 0 {
157                 *n -= 1;
158                 self.iter.next()
159             } else {
160                 None
161             }
162         } else {
163             self.iter.next()
164         }
165     }
166 
167     #[inline]
size_hint(&self) -> (usize, Option<usize>)168     fn size_hint(&self) -> (usize, Option<usize>) {
169         if let Some(n) = self.n {
170             let (lower, upper) = self.iter.size_hint();
171 
172             let lower = cmp::min(lower, n);
173 
174             let upper = match upper {
175                 Some(x) if x < n => Some(x),
176                 _ => Some(n),
177             };
178 
179             (lower, upper)
180         } else {
181             self.iter.size_hint()
182         }
183     }
184 }
185 
186 impl<I> ExactSizeIterator for Take<I>
187 where
188     I: ExactSizeIterator,
189 {
190 }
191