1use std::time::Duration;
14use std::vec::IntoIter as VecIntoIter;
15
16use crate::{Sample, Source};
17
18pub struct SamplesBuffer<S> {
20 data: VecIntoIter<S>,
21 channels: u16,
22 sample_rate: u32,
23 duration: Duration,
24}
25
26impl<S> SamplesBuffer<S>
27where
28 S: Sample,
29{
30 pub fn new<D>(channels: u16, sample_rate: u32, data: D) -> SamplesBuffer<S>
40 where
41 D: Into<Vec<S>>,
42 {
43 assert!(channels != 0);
44 assert!(sample_rate != 0);
45
46 let data = data.into();
47 let duration_ns = 1_000_000_000u64.checked_mul(data.len() as u64).unwrap()
48 / sample_rate as u64
49 / channels as u64;
50 let duration = Duration::new(
51 duration_ns / 1_000_000_000,
52 (duration_ns % 1_000_000_000) as u32,
53 );
54
55 SamplesBuffer {
56 data: data.into_iter(),
57 channels,
58 sample_rate,
59 duration,
60 }
61 }
62}
63
64impl<S> Source for SamplesBuffer<S>
65where
66 S: Sample,
67{
68 #[inline]
69 fn current_frame_len(&self) -> Option<usize> {
70 None
71 }
72
73 #[inline]
74 fn channels(&self) -> u16 {
75 self.channels
76 }
77
78 #[inline]
79 fn sample_rate(&self) -> u32 {
80 self.sample_rate
81 }
82
83 #[inline]
84 fn total_duration(&self) -> Option<Duration> {
85 Some(self.duration)
86 }
87}
88
89impl<S> Iterator for SamplesBuffer<S>
90where
91 S: Sample,
92{
93 type Item = S;
94
95 #[inline]
96 fn next(&mut self) -> Option<S> {
97 self.data.next()
98 }
99
100 #[inline]
101 fn size_hint(&self) -> (usize, Option<usize>) {
102 self.data.size_hint()
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use crate::buffer::SamplesBuffer;
109 use crate::source::Source;
110
111 #[test]
112 fn basic() {
113 let _ = SamplesBuffer::new(1, 44100, vec![0i16, 0, 0, 0, 0, 0]);
114 }
115
116 #[test]
117 #[should_panic]
118 fn panic_if_zero_channels() {
119 SamplesBuffer::new(0, 44100, vec![0i16, 0, 0, 0, 0, 0]);
120 }
121
122 #[test]
123 #[should_panic]
124 fn panic_if_zero_sample_rate() {
125 SamplesBuffer::new(1, 0, vec![0i16, 0, 0, 0, 0, 0]);
126 }
127
128 #[test]
129 fn duration_basic() {
130 let buf = SamplesBuffer::new(2, 2, vec![0i16, 0, 0, 0, 0, 0]);
131 let dur = buf.total_duration().unwrap();
132 assert_eq!(dur.as_secs(), 1);
133 assert_eq!(dur.subsec_nanos(), 500_000_000);
134 }
135
136 #[test]
137 fn iteration() {
138 let mut buf = SamplesBuffer::new(1, 44100, vec![1i16, 2, 3, 4, 5, 6]);
139 assert_eq!(buf.next(), Some(1));
140 assert_eq!(buf.next(), Some(2));
141 assert_eq!(buf.next(), Some(3));
142 assert_eq!(buf.next(), Some(4));
143 assert_eq!(buf.next(), Some(5));
144 assert_eq!(buf.next(), Some(6));
145 assert_eq!(buf.next(), None);
146 }
147}