Skip to main content

xsynth_core/
audio_pipe.rs

1use crate::AudioStreamParams;
2
3/// An object to read audio samples from.
4pub trait AudioPipe {
5    /// The audio stream parameters of the audio pipe.
6    fn stream_params(&self) -> &'_ AudioStreamParams;
7
8    /// Reads samples from the pipe.
9    ///
10    /// When using in a MIDI synthesizer, the amount of samples determines the
11    /// time of the current active MIDI events. For example if we send a note
12    /// on event and read 44100 samples (with a 44.1kHz sample rate), then the
13    /// note will be audible for 1 second. If after reading those samples we
14    /// send a note off event for the same key, then on the next read the key
15    /// will be released. If we don't, then the note will keep playing.
16    fn read_samples(&mut self, to: &mut [f32]) {
17        assert!(to
18            .len()
19            .is_multiple_of(self.stream_params().channels.count() as usize));
20        self.read_samples_unchecked(to);
21    }
22
23    /// Reads samples from the pipe without checking the channel count of the output.
24    fn read_samples_unchecked(&mut self, to: &mut [f32]);
25}
26
27pub struct FunctionAudioPipe<F: 'static + FnMut(&mut [f32]) + Send> {
28    func: F,
29    stream_params: AudioStreamParams,
30}
31
32impl<F: 'static + FnMut(&mut [f32]) + Send> AudioPipe for FunctionAudioPipe<F> {
33    fn stream_params(&self) -> &'_ AudioStreamParams {
34        &self.stream_params
35    }
36
37    fn read_samples_unchecked(&mut self, to: &mut [f32]) {
38        (self.func)(to);
39    }
40}
41
42impl<F: 'static + FnMut(&mut [f32]) + Send> FunctionAudioPipe<F> {
43    pub fn new(stream_params: AudioStreamParams, func: F) -> Self {
44        FunctionAudioPipe {
45            func,
46            stream_params,
47        }
48    }
49}