geng_rodio/conversions/
channels.rs1#[derive(Clone, Debug)]
3pub struct ChannelCountConverter<I>
4where
5 I: Iterator,
6{
7 input: I,
8 from: cpal::ChannelCount,
9 to: cpal::ChannelCount,
10 sample_repeat: Option<I::Item>,
11 next_output_sample_pos: cpal::ChannelCount,
12}
13
14impl<I> ChannelCountConverter<I>
15where
16 I: Iterator,
17{
18 #[inline]
25 pub fn new(
26 input: I,
27 from: cpal::ChannelCount,
28 to: cpal::ChannelCount,
29 ) -> ChannelCountConverter<I> {
30 assert!(from >= 1);
31 assert!(to >= 1);
32
33 ChannelCountConverter {
34 input,
35 from,
36 to,
37 sample_repeat: None,
38 next_output_sample_pos: 0,
39 }
40 }
41
42 #[inline]
44 pub fn into_inner(self) -> I {
45 self.input
46 }
47}
48
49impl<I> Iterator for ChannelCountConverter<I>
50where
51 I: Iterator,
52 I::Item: Clone,
53{
54 type Item = I::Item;
55
56 fn next(&mut self) -> Option<I::Item> {
57 let result = if self.next_output_sample_pos == self.from - 1 {
58 let value = self.input.next();
59 self.sample_repeat = value.clone();
60 value
61 } else if self.next_output_sample_pos < self.from {
62 self.input.next()
63 } else {
64 self.sample_repeat.clone()
65 };
66
67 self.next_output_sample_pos += 1;
68
69 if self.next_output_sample_pos == self.to {
70 self.next_output_sample_pos -= self.to;
71
72 if self.from > self.to {
73 for _ in self.to..self.from {
74 self.input.next(); }
76 }
77 }
78
79 result
80 }
81
82 #[inline]
83 fn size_hint(&self) -> (usize, Option<usize>) {
84 let (min, max) = self.input.size_hint();
85
86 let min =
87 (min / self.from as usize) * self.to as usize + self.next_output_sample_pos as usize;
88 let max = max.map(|max| {
89 (max / self.from as usize) * self.to as usize + self.next_output_sample_pos as usize
90 });
91
92 (min, max)
93 }
94}
95
96impl<I> ExactSizeIterator for ChannelCountConverter<I>
97where
98 I: ExactSizeIterator,
99 I::Item: Clone,
100{
101}
102
103#[cfg(test)]
104mod test {
105 use super::ChannelCountConverter;
106
107 #[test]
108 fn remove_channels() {
109 let input = vec![1u16, 2, 3, 1, 2, 3];
110 let output = ChannelCountConverter::new(input.into_iter(), 3, 2).collect::<Vec<_>>();
111 assert_eq!(output, [1, 2, 1, 2]);
112
113 let input = vec![1u16, 2, 3, 4, 1, 2, 3, 4];
114 let output = ChannelCountConverter::new(input.into_iter(), 4, 1).collect::<Vec<_>>();
115 assert_eq!(output, [1, 1]);
116 }
117
118 #[test]
119 fn add_channels() {
120 let input = vec![1u16, 2, 1, 2];
121 let output = ChannelCountConverter::new(input.into_iter(), 2, 3).collect::<Vec<_>>();
122 assert_eq!(output, [1, 2, 2, 1, 2, 2]);
123
124 let input = vec![1u16, 2, 1, 2];
125 let output = ChannelCountConverter::new(input.into_iter(), 2, 4).collect::<Vec<_>>();
126 assert_eq!(output, [1, 2, 2, 2, 1, 2, 2, 2]);
127 }
128
129 #[test]
130 fn len_more() {
131 let input = vec![1u16, 2, 1, 2];
132 let output = ChannelCountConverter::new(input.into_iter(), 2, 3);
133 assert_eq!(output.len(), 6);
134 }
135
136 #[test]
137 fn len_less() {
138 let input = vec![1u16, 2, 1, 2];
139 let output = ChannelCountConverter::new(input.into_iter(), 2, 1);
140 assert_eq!(output.len(), 2);
141 }
142}