rodio/
static_buffer.rs
1use std::slice::Iter as SliceIter;
14use std::time::Duration;
15
16use crate::source::SeekError;
17use crate::{Sample, Source};
18
19#[derive(Clone)]
21pub struct StaticSamplesBuffer<S>
22where
23 S: 'static,
24{
25 data: SliceIter<'static, S>,
26 channels: u16,
27 sample_rate: u32,
28 duration: Duration,
29}
30
31impl<S> StaticSamplesBuffer<S>
32where
33 S: Sample,
34{
35 pub fn new(channels: u16, sample_rate: u32, data: &'static [S]) -> StaticSamplesBuffer<S> {
45 assert!(channels != 0);
46 assert!(sample_rate != 0);
47
48 let duration_ns = 1_000_000_000u64.checked_mul(data.len() as u64).unwrap()
49 / sample_rate as u64
50 / 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 StaticSamplesBuffer {
57 data: data.iter(),
58 channels,
59 sample_rate,
60 duration,
61 }
62 }
63}
64
65impl<S> Source for StaticSamplesBuffer<S>
66where
67 S: Sample,
68{
69 #[inline]
70 fn current_frame_len(&self) -> Option<usize> {
71 None
72 }
73
74 #[inline]
75 fn channels(&self) -> u16 {
76 self.channels
77 }
78
79 #[inline]
80 fn sample_rate(&self) -> u32 {
81 self.sample_rate
82 }
83
84 #[inline]
85 fn total_duration(&self) -> Option<Duration> {
86 Some(self.duration)
87 }
88
89 #[inline]
90 fn try_seek(&mut self, _: Duration) -> Result<(), SeekError> {
91 Err(SeekError::NotSupported {
92 underlying_source: std::any::type_name::<Self>(),
93 })
94 }
95}
96
97impl<S> Iterator for StaticSamplesBuffer<S>
98where
99 S: Sample + Clone,
100{
101 type Item = S;
102
103 #[inline]
104 fn next(&mut self) -> Option<S> {
105 self.data.next().cloned()
106 }
107
108 #[inline]
109 fn size_hint(&self) -> (usize, Option<usize>) {
110 self.data.size_hint()
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use crate::source::Source;
117 use crate::static_buffer::StaticSamplesBuffer;
118
119 #[test]
120 fn basic() {
121 let _ = StaticSamplesBuffer::new(1, 44100, &[0i16, 0, 0, 0, 0, 0]);
122 }
123
124 #[test]
125 #[should_panic]
126 fn panic_if_zero_channels() {
127 StaticSamplesBuffer::new(0, 44100, &[0i16, 0, 0, 0, 0, 0]);
128 }
129
130 #[test]
131 #[should_panic]
132 fn panic_if_zero_sample_rate() {
133 StaticSamplesBuffer::new(1, 0, &[0i16, 0, 0, 0, 0, 0]);
134 }
135
136 #[test]
137 fn duration_basic() {
138 let buf = StaticSamplesBuffer::new(2, 2, &[0i16, 0, 0, 0, 0, 0]);
139 let dur = buf.total_duration().unwrap();
140 assert_eq!(dur.as_secs(), 1);
141 assert_eq!(dur.subsec_nanos(), 500_000_000);
142 }
143
144 #[test]
145 fn iteration() {
146 let mut buf = StaticSamplesBuffer::new(1, 44100, &[1i16, 2, 3, 4, 5, 6]);
147 assert_eq!(buf.next(), Some(1));
148 assert_eq!(buf.next(), Some(2));
149 assert_eq!(buf.next(), Some(3));
150 assert_eq!(buf.next(), Some(4));
151 assert_eq!(buf.next(), Some(5));
152 assert_eq!(buf.next(), Some(6));
153 assert_eq!(buf.next(), None);
154 }
155}