audio_callback/
audio_callback.rs1use {
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}