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