Skip to main content

codewandler_audio/
channel.rs

1use crate::format::SampleFormat;
2use crate::{AudioSink, AudioSource, IntoAudioSource};
3use crossbeam_channel::{Receiver, Sender, bounded};
4use tracing::error;
5
6impl<T> AudioSink for Sender<T>
7where
8    T: SampleFormat,
9{
10    type Format = T;
11
12    fn audio_write(&self, d: Self::Format) -> anyhow::Result<()> {
13        match self.send(d) {
14            Ok(_) => (),
15            Err(err) => {
16                error!("Error sending audio buffer: {}", err);
17                return Err(anyhow::anyhow!("Error sending audio buffer: {}", err));
18            }
19        }
20        Ok(())
21    }
22}
23
24impl<T> AudioSource for Receiver<T>
25where
26    T: SampleFormat,
27{
28    type Format = T;
29
30    fn audio_read(&mut self) -> Option<Self::Format> {
31        self.recv().ok()
32    }
33}
34
35impl IntoAudioSource for Receiver<f32> {
36    type Format = f32;
37
38    fn into_audio_source(&mut self) -> anyhow::Result<Box<dyn AudioSource<Format = Self::Format>>> {
39        Ok(Box::new(self.clone()))
40    }
41}
42
43pub fn new_audio_channel<T: SampleFormat>() -> (Sender<T>, Receiver<T>) {
44    bounded::<T>(64)
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50    use crate::buffer::BufferWriter;
51    use crate::{Buffer, audio_pipe};
52    use std::thread;
53
54    #[test]
55    fn test_channel() {
56        let (tx1, rx1) = new_audio_channel::<f32>();
57        let (tx2, rx2) = new_audio_channel::<f32>();
58
59        tx1.audio_write_buffer(&Buffer::new(vec![
60            1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0,
61        ]))
62        .unwrap();
63
64        let h = thread::spawn(move || {
65            audio_pipe(Box::new(rx1), Box::new(tx2)).unwrap();
66        });
67
68        h.join().unwrap();
69
70        let x: Vec<f32> = rx2.iter().collect();
71        println!("{:?}", x);
72    }
73}