geng_rodio/source/
from_iter.rs1use std::time::Duration;
2
3use crate::{Sample, Source};
4
5pub fn from_iter<I>(iterator: I) -> FromIter<I::IntoIter>
13where
14 I: IntoIterator,
15{
16 let mut iterator = iterator.into_iter();
17 let first_source = iterator.next();
18
19 FromIter {
20 iterator,
21 current_source: first_source,
22 }
23}
24
25#[derive(Clone)]
27pub struct FromIter<I>
28where
29 I: Iterator,
30{
31 iterator: I,
33 current_source: Option<I::Item>,
35}
36
37impl<I> Iterator for FromIter<I>
38where
39 I: Iterator,
40 I::Item: Iterator + Source,
41 <I::Item as Iterator>::Item: Sample,
42{
43 type Item = <I::Item as Iterator>::Item;
44
45 #[inline]
46 fn next(&mut self) -> Option<<I::Item as Iterator>::Item> {
47 loop {
48 if let Some(src) = &mut self.current_source {
49 if let Some(value) = src.next() {
50 return Some(value);
51 }
52 }
53
54 if let Some(src) = self.iterator.next() {
55 self.current_source = Some(src);
56 } else {
57 return None;
58 }
59 }
60 }
61
62 #[inline]
63 fn size_hint(&self) -> (usize, Option<usize>) {
64 if let Some(cur) = &self.current_source {
65 (cur.size_hint().0, None)
66 } else {
67 (0, None)
68 }
69 }
70}
71
72impl<I> Source for FromIter<I>
73where
74 I: Iterator,
75 I::Item: Iterator + Source,
76 <I::Item as Iterator>::Item: Sample,
77{
78 #[inline]
79 fn current_frame_len(&self) -> Option<usize> {
80 const THRESHOLD: usize = 10240;
91
92 if let Some(src) = &self.current_source {
94 if let Some(val) = src.current_frame_len() {
95 if val != 0 {
96 return Some(val);
97 }
98 }
99 }
100
101 if let Some(src) = &self.current_source {
103 if let Some(val) = src.size_hint().1 {
104 if val < THRESHOLD && val != 0 {
105 return Some(val);
106 }
107 }
108 }
109
110 Some(THRESHOLD)
112 }
113
114 #[inline]
115 fn channels(&self) -> u16 {
116 if let Some(src) = &self.current_source {
117 src.channels()
118 } else {
119 2
121 }
122 }
123
124 #[inline]
125 fn sample_rate(&self) -> u32 {
126 if let Some(src) = &self.current_source {
127 src.sample_rate()
128 } else {
129 44100
131 }
132 }
133
134 #[inline]
135 fn total_duration(&self) -> Option<Duration> {
136 None
137 }
138}
139
140#[cfg(test)]
141mod tests {
142 use crate::buffer::SamplesBuffer;
143 use crate::source::{from_iter, Source};
144
145 #[test]
146 fn basic() {
147 let mut rx = from_iter((0..2).map(|n| {
148 if n == 0 {
149 SamplesBuffer::new(1, 48000, vec![10i16, -10, 10, -10])
150 } else if n == 1 {
151 SamplesBuffer::new(2, 96000, vec![5i16, 5, 5, 5])
152 } else {
153 unreachable!()
154 }
155 }));
156
157 assert_eq!(rx.channels(), 1);
158 assert_eq!(rx.sample_rate(), 48000);
159 assert_eq!(rx.next(), Some(10));
160 assert_eq!(rx.next(), Some(-10));
161 assert_eq!(rx.next(), Some(10));
162 assert_eq!(rx.next(), Some(-10));
163 assert_eq!(rx.next(), Some(5));
167 assert_eq!(rx.next(), Some(5));
168 assert_eq!(rx.next(), Some(5));
169 assert_eq!(rx.next(), Some(5));
170 assert_eq!(rx.next(), None);
171 }
172}