1use std::collections::VecDeque;
2use std::sync::{Arc, Mutex};
3use std::time::Duration;
4
5use rodio::source::SeekError;
6use rodio::{ChannelCount, SampleRate, Source};
7
8pub struct SampleTap<S: Source<Item = f32>> {
9 inner: S,
10 buffer: Arc<Mutex<VecDeque<f32>>>,
11}
12
13impl<S: Source<Item = f32>> SampleTap<S> {
14 pub fn new(inner: S, buffer: Arc<Mutex<VecDeque<f32>>>) -> Self {
15 Self { inner, buffer }
16 }
17}
18
19impl<S: Source<Item = f32>> Iterator for SampleTap<S> {
20 type Item = f32;
21 fn next(&mut self) -> Option<f32> {
22 let sample = self.inner.next()?;
23 if let Ok(mut buf) = self.buffer.try_lock() {
24 buf.push_back(sample);
25 if buf.len() > 4096 {
26 buf.pop_front();
27 }
28 }
29 Some(sample)
30 }
31}
32
33impl<S: Source<Item = f32>> Source for SampleTap<S> {
34 fn current_span_len(&self) -> Option<usize> { self.inner.current_span_len() }
35 fn channels(&self) -> ChannelCount { self.inner.channels() }
36 fn sample_rate(&self) -> SampleRate { self.inner.sample_rate() }
37 fn total_duration(&self) -> Option<Duration> { self.inner.total_duration() }
38
39 fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
40 if let Ok(mut buf) = self.buffer.try_lock() {
42 buf.clear();
43 }
44 self.inner.try_seek(pos)
45 }
46}