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 crate::{Sample, Source}; 17 18 /// A buffer of samples treated as a source. 19 pub struct SamplesBuffer<S> { 20 data: VecIntoIter<S>, 21 channels: u16, 22 sample_rate: u32, 23 duration: Duration, 24 } 25 26 impl<S> SamplesBuffer<S> 27 where 28 S: Sample, 29 { 30 /// Builds a new `SamplesBuffer`. 31 /// 32 /// # Panic 33 /// 34 /// - Panics if the number of channels is zero. 35 /// - Panics if the samples rate is zero. 36 /// - Panics if the length of the buffer is larger than approximately 16 billion elements. 37 /// This is because the calculation of the duration would overflow. 38 /// new<D>(channels: u16, sample_rate: u32, data: D) -> SamplesBuffer<S> where D: Into<Vec<S>>,39 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 64 impl<S> Source for SamplesBuffer<S> 65 where 66 S: Sample, 67 { 68 #[inline] current_frame_len(&self) -> Option<usize>69 fn current_frame_len(&self) -> Option<usize> { 70 None 71 } 72 73 #[inline] channels(&self) -> u1674 fn channels(&self) -> u16 { 75 self.channels 76 } 77 78 #[inline] sample_rate(&self) -> u3279 fn sample_rate(&self) -> u32 { 80 self.sample_rate 81 } 82 83 #[inline] total_duration(&self) -> Option<Duration>84 fn total_duration(&self) -> Option<Duration> { 85 Some(self.duration) 86 } 87 } 88 89 impl<S> Iterator for SamplesBuffer<S> 90 where 91 S: Sample, 92 { 93 type Item = S; 94 95 #[inline] next(&mut self) -> Option<S>96 fn next(&mut self) -> Option<S> { 97 self.data.next() 98 } 99 100 #[inline] size_hint(&self) -> (usize, Option<usize>)101 fn size_hint(&self) -> (usize, Option<usize>) { 102 self.data.size_hint() 103 } 104 } 105 106 #[cfg(test)] 107 mod tests { 108 use crate::buffer::SamplesBuffer; 109 use crate::source::Source; 110 111 #[test] basic()112 fn basic() { 113 let _ = SamplesBuffer::new(1, 44100, vec![0i16, 0, 0, 0, 0, 0]); 114 } 115 116 #[test] 117 #[should_panic] panic_if_zero_channels()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] panic_if_zero_sample_rate()124 fn panic_if_zero_sample_rate() { 125 SamplesBuffer::new(1, 0, vec![0i16, 0, 0, 0, 0, 0]); 126 } 127 128 #[test] duration_basic()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] iteration()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 } 148