audio_callback/
audio_callback.rs

1use {
2    cxx_juce::{
3        juce_audio_devices::{
4            AudioDeviceManager, AudioIODevice, AudioIODeviceCallback, InputAudioSampleBuffer,
5            OutputAudioSampleBuffer,
6        },
7        Result, JUCE,
8    },
9    std::{iter::successors, thread::sleep, time::Duration},
10};
11
12#[derive(Debug, Default, Copy, Clone)]
13struct ToneGenerator {
14    amplitude: f64,
15    frequency: f64,
16    phase: f64,
17    increment: f64,
18}
19
20impl Iterator for ToneGenerator {
21    type Item = f64;
22
23    fn next(&mut self) -> Option<Self::Item> {
24        let sample = self.phase.sin() * self.amplitude;
25        self.phase += self.increment;
26        Some(sample)
27    }
28}
29
30#[derive(Default)]
31struct AudioCallback {
32    tones: Vec<ToneGenerator>,
33}
34
35impl AudioIODeviceCallback for AudioCallback {
36    fn about_to_start(&mut self, device: &mut dyn AudioIODevice) {
37        const STARTING_FREQUENCY: f64 = 1024.0;
38
39        let output_channels = device.output_channels() as usize;
40
41        self.tones = successors(
42            Some(ToneGenerator {
43                amplitude: 0.25,
44                frequency: STARTING_FREQUENCY,
45                phase: 0.0,
46                increment: STARTING_FREQUENCY / device.sample_rate(),
47            }),
48            |prev| {
49                let frequency = prev.frequency * 2.5;
50                Some(ToneGenerator {
51                    frequency,
52                    increment: frequency / device.sample_rate(),
53                    ..*prev
54                })
55            },
56        )
57        .take(output_channels)
58        .collect();
59    }
60
61    fn process_block(
62        &mut self,
63        _input: &InputAudioSampleBuffer<'_>,
64        output: &mut OutputAudioSampleBuffer<'_>,
65    ) {
66        for channel in 0..output.channels() {
67            let samples = &mut output[channel];
68            let tone = &mut self.tones[channel];
69
70            for (sample, tone) in samples.iter_mut().zip(tone) {
71                *sample = tone as f32;
72            }
73        }
74    }
75
76    fn stopped(&mut self) {}
77}
78
79fn main() -> Result<()> {
80    let juce = JUCE::initialise();
81    let mut device_manager = AudioDeviceManager::new(&juce);
82    device_manager.initialise(0, 2)?;
83
84    let handle = device_manager.add_audio_callback(AudioCallback::default());
85
86    sleep(Duration::from_secs(2));
87
88    device_manager.remove_audio_callback(handle);
89
90    Ok(())
91}