1use core::fmt;
15use std::slice::Iter as SliceIter;
16use std::time::Duration;
17
18use crate::common::{ChannelCount, SampleRate};
19use crate::math::NANOS_PER_SEC;
20use crate::source::SeekError;
21use crate::{Sample, Source};
22
23#[derive(Clone)]
25pub struct StaticSamplesBuffer {
26 data: SliceIter<'static, Sample>,
27 channels: ChannelCount,
28 sample_rate: SampleRate,
29 duration: Duration,
30}
31
32impl fmt::Debug for StaticSamplesBuffer {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 f.debug_struct("StaticSamplesBuffer")
35 .field("channels", &self.channels)
36 .field("sample_rate", &self.sample_rate)
37 .field("duration", &self.duration)
38 .finish()
39 }
40}
41
42impl StaticSamplesBuffer {
43 pub fn new(
53 channels: ChannelCount,
54 sample_rate: SampleRate,
55 data: &'static [Sample],
56 ) -> StaticSamplesBuffer {
57 let duration_ns = NANOS_PER_SEC.checked_mul(data.len() as u64).unwrap()
58 / sample_rate.get() as u64
59 / channels.get() as u64;
60 let duration = Duration::new(
61 duration_ns / NANOS_PER_SEC,
62 (duration_ns % NANOS_PER_SEC) as u32,
63 );
64
65 StaticSamplesBuffer {
66 data: data.iter(),
67 channels,
68 sample_rate,
69 duration,
70 }
71 }
72}
73
74impl Source for StaticSamplesBuffer {
75 #[inline]
76 fn current_span_len(&self) -> Option<usize> {
77 None
78 }
79
80 #[inline]
81 fn channels(&self) -> ChannelCount {
82 self.channels
83 }
84
85 #[inline]
86 fn sample_rate(&self) -> SampleRate {
87 self.sample_rate
88 }
89
90 #[inline]
91 fn total_duration(&self) -> Option<Duration> {
92 Some(self.duration)
93 }
94
95 #[inline]
96 fn try_seek(&mut self, _: Duration) -> Result<(), SeekError> {
97 Err(SeekError::NotSupported {
98 underlying_source: std::any::type_name::<Self>(),
99 })
100 }
101}
102
103impl Iterator for StaticSamplesBuffer {
104 type Item = Sample;
105
106 #[inline]
107 fn next(&mut self) -> Option<Self::Item> {
108 self.data.next().cloned()
109 }
110
111 #[inline]
112 fn size_hint(&self) -> (usize, Option<usize>) {
113 self.data.size_hint()
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use crate::math::nz;
120 use crate::source::Source;
121 use crate::static_buffer::StaticSamplesBuffer;
122
123 #[test]
124 fn basic() {
125 let _ = StaticSamplesBuffer::new(nz!(1), nz!(44100), &[0.0, 0.0, 0.0, 0.0, 0.0, 0.0]);
126 }
127
128 #[test]
129 fn duration_basic() {
130 let buf = StaticSamplesBuffer::new(nz!(2), nz!(2), &[0.0, 0.0, 0.0, 0.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 = StaticSamplesBuffer::new(nz!(1), nz!(44100), &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);
139 assert_eq!(buf.next(), Some(1.0));
140 assert_eq!(buf.next(), Some(2.0));
141 assert_eq!(buf.next(), Some(3.0));
142 assert_eq!(buf.next(), Some(4.0));
143 assert_eq!(buf.next(), Some(5.0));
144 assert_eq!(buf.next(), Some(6.0));
145 assert_eq!(buf.next(), None);
146 }
147}