Skip to main content

codewandler_audio/
playback.rs

1use crate::channel::new_audio_channel;
2use crate::format::SampleFormat;
3use crossbeam_channel::{Receiver, Sender};
4use rodio::dynamic_mixer::DynamicMixerController;
5use rodio::dynamic_mixer::mixer;
6use rodio::source::SineWave;
7use rodio::{OutputStream, Sink, Source};
8use std::sync::Arc;
9use std::time::Duration;
10
11pub struct AudioPlayback<F>
12where
13    F: SampleFormat,
14{
15    _stream: OutputStream,
16    _sink: Arc<Sink>,
17    _mixer_handle: Arc<DynamicMixerController<F>>,
18}
19
20pub struct AudioPlaybackOutput<F>
21where
22    F: SampleFormat,
23{
24    sample_rate: u32,
25    _tx: Sender<F>,
26    rx: Receiver<F>,
27}
28
29impl Source for AudioPlaybackOutput<f32> {
30    fn current_frame_len(&self) -> Option<usize> {
31        None
32    }
33
34    fn channels(&self) -> u16 {
35        1
36    }
37
38    fn sample_rate(&self) -> u32 {
39        self.sample_rate
40    }
41
42    fn total_duration(&self) -> Option<Duration> {
43        None
44    }
45}
46
47impl Iterator for AudioPlaybackOutput<f32> {
48    type Item = f32;
49
50    fn next(&mut self) -> Option<Self::Item> {
51        match self.rx.try_recv() {
52            Ok(data) => Some(data),
53            Err(err) => match err {
54                crossbeam_channel::TryRecvError::Empty => Some(0.0),
55                crossbeam_channel::TryRecvError::Disconnected => None,
56            },
57        }
58    }
59}
60
61impl AudioPlayback<f32> {
62    pub fn new(sample_rate: u32) -> anyhow::Result<Self> {
63        let (_stream, stream_handle) = OutputStream::try_default()?;
64        let sink = Sink::try_new(&stream_handle)?;
65
66        let (mixer_handle, mixer_source) = mixer::<f32>(1, sample_rate);
67        sink.append(mixer_source);
68        sink.play();
69
70        Ok(Self {
71            _stream,
72            _sink: Arc::new(sink),
73            _mixer_handle: mixer_handle,
74        })
75    }
76
77    pub fn sine(&self, freq: f32, duration: Duration) {
78        self.play(SineWave::new(freq).take_duration(duration))
79    }
80
81    pub fn play<S>(&self, source: S)
82    where
83        S: Source<Item = f32> + Send + 'static,
84    {
85        self._mixer_handle.add(source);
86    }
87
88    pub fn new_output(&self, sample_rate: u32) -> Sender<f32> {
89        let (tx1, rx1) = new_audio_channel();
90
91        let out = AudioPlaybackOutput {
92            _tx: tx1.clone(),
93            rx: rx1,
94            sample_rate,
95        };
96
97        self.play(out);
98
99        tx1
100    }
101}