1 //! A simple source of samples coming from a buffer.
2 //!
3 //! The `SamplesBuffer` struct can be used to treat a list of values as a `Source`.
4 //!
5 //! # Example
6 //!
7 //! ```
8 //! use rodio::buffer::SamplesBuffer;
9 //! let _ = SamplesBuffer::new(1, 44100, vec![1i16, 2, 3, 4, 5, 6]);
10 //! ```
11 //!
12 
13 use std::time::Duration;
14 use std::vec::IntoIter as VecIntoIter;
15 
16 use source::Source;
17 
18 use Sample;
19 
20 /// A buffer of samples treated as a source.
21 pub struct SamplesBuffer<S> {
22     data: VecIntoIter<S>,
23     channels: u16,
24     sample_rate: u32,
25     duration: Duration,
26 }
27 
28 impl<S> SamplesBuffer<S>
29 where
30     S: Sample,
31 {
32     /// Builds a new `SamplesBuffer`.
33     ///
34     /// # Panic
35     ///
36     /// - Panicks if the number of channels is zero.
37     /// - Panicks if the samples rate is zero.
38     /// - Panicks if the length of the buffer is larger than approximatively 16 billion elements.
39     ///   This is because the calculation of the duration would overflow.
40     ///
new<D>(channels: u16, sample_rate: u32, data: D) -> SamplesBuffer<S> where D: Into<Vec<S>>,41     pub fn new<D>(channels: u16, sample_rate: u32, data: D) -> SamplesBuffer<S>
42     where
43         D: Into<Vec<S>>,
44     {
45         assert!(channels != 0);
46         assert!(sample_rate != 0);
47 
48         let data = data.into();
49         let duration_ns = 1_000_000_000u64.checked_mul(data.len() as u64).unwrap()
50             / sample_rate as u64 / channels as u64;
51         let duration = Duration::new(
52             duration_ns / 1_000_000_000,
53             (duration_ns % 1_000_000_000) as u32,
54         );
55 
56         SamplesBuffer {
57             data: data.into_iter(),
58             channels: channels,
59             sample_rate: sample_rate,
60             duration: duration,
61         }
62     }
63 }
64 
65 impl<S> Source for SamplesBuffer<S>
66 where
67     S: Sample,
68 {
69     #[inline]
current_frame_len(&self) -> Option<usize>70     fn current_frame_len(&self) -> Option<usize> {
71         None
72     }
73 
74     #[inline]
channels(&self) -> u1675     fn channels(&self) -> u16 {
76         self.channels
77     }
78 
79     #[inline]
sample_rate(&self) -> u3280     fn sample_rate(&self) -> u32 {
81         self.sample_rate
82     }
83 
84     #[inline]
total_duration(&self) -> Option<Duration>85     fn total_duration(&self) -> Option<Duration> {
86         Some(self.duration)
87     }
88 }
89 
90 impl<S> Iterator for SamplesBuffer<S>
91 where
92     S: Sample,
93 {
94     type Item = S;
95 
96     #[inline]
next(&mut self) -> Option<S>97     fn next(&mut self) -> Option<S> {
98         self.data.next()
99     }
100 
101     #[inline]
size_hint(&self) -> (usize, Option<usize>)102     fn size_hint(&self) -> (usize, Option<usize>) {
103         self.data.size_hint()
104     }
105 }
106 
107 #[cfg(test)]
108 mod tests {
109     use buffer::SamplesBuffer;
110     use source::Source;
111 
112     #[test]
basic()113     fn basic() {
114         let _ = SamplesBuffer::new(1, 44100, vec![0i16, 0, 0, 0, 0, 0]);
115     }
116 
117     #[test]
118     #[should_panic]
panic_if_zero_channels()119     fn panic_if_zero_channels() {
120         SamplesBuffer::new(0, 44100, vec![0i16, 0, 0, 0, 0, 0]);
121     }
122 
123     #[test]
124     #[should_panic]
panic_if_zero_sample_rate()125     fn panic_if_zero_sample_rate() {
126         SamplesBuffer::new(1, 0, vec![0i16, 0, 0, 0, 0, 0]);
127     }
128 
129     #[test]
duration_basic()130     fn duration_basic() {
131         let buf = SamplesBuffer::new(2, 2, vec![0i16, 0, 0, 0, 0, 0]);
132         let dur = buf.total_duration().unwrap();
133         assert_eq!(dur.as_secs(), 1);
134         assert_eq!(dur.subsec_nanos(), 500_000_000);
135     }
136 
137     #[test]
iteration()138     fn iteration() {
139         let mut buf = SamplesBuffer::new(1, 44100, vec![1i16, 2, 3, 4, 5, 6]);
140         assert_eq!(buf.next(), Some(1));
141         assert_eq!(buf.next(), Some(2));
142         assert_eq!(buf.next(), Some(3));
143         assert_eq!(buf.next(), Some(4));
144         assert_eq!(buf.next(), Some(5));
145         assert_eq!(buf.next(), Some(6));
146         assert_eq!(buf.next(), None);
147     }
148 }
149