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