|
1 | | -//! This example demonstrates how to request a specific buffer size from the CoreAudio backend. |
2 | | -//! Probably only works on macOS. |
| 1 | +//! This example demonstrates how to request a specific buffer size from the audio backends. |
| 2 | +
|
| 3 | +use interflow::channel_map::{ChannelMap32, CreateBitset}; |
| 4 | +use interflow::prelude::*; |
| 5 | +use std::sync::{ |
| 6 | + atomic::{AtomicBool, Ordering}, |
| 7 | + Arc, |
| 8 | +}; |
| 9 | +use util::sine::SineWave; |
3 | 10 |
|
4 | 11 | mod util; |
5 | 12 |
|
6 | | -#[cfg(os_coreaudio)] |
7 | 13 | fn main() -> anyhow::Result<()> { |
8 | | - use interflow::backends::coreaudio::CoreAudioDriver; |
9 | | - use interflow::channel_map::{ChannelMap32, CreateBitset}; |
10 | | - use interflow::prelude::*; |
11 | | - use std::sync::{ |
12 | | - atomic::{AtomicBool, Ordering}, |
13 | | - Arc, |
14 | | - }; |
15 | | - use util::sine::SineWave; |
16 | | - |
17 | | - struct MyCallback { |
18 | | - first_callback: Arc<AtomicBool>, |
19 | | - sine_wave: SineWave, |
| 14 | + #[cfg(target_os = "macos")] |
| 15 | + { |
| 16 | + use interflow::backends::coreaudio::CoreAudioDriver; |
| 17 | + run(CoreAudioDriver) |
| 18 | + } |
| 19 | + #[cfg(target_os = "windows")] |
| 20 | + { |
| 21 | + use interflow::backends::wasapi::WasapiDriver; |
| 22 | + run(WasapiDriver::default()) |
20 | 23 | } |
| 24 | + #[cfg(all(target_os = "linux", not(feature = "pipewire")))] |
| 25 | + { |
| 26 | + use interflow::backends::alsa::AlsaDriver; |
| 27 | + run(AlsaDriver::default()) |
| 28 | + } |
| 29 | + #[cfg(all(target_os = "linux", feature = "pipewire"))] |
| 30 | + { |
| 31 | + use interflow::backends::pipewire::PipewireDriver; |
| 32 | + run(PipewireDriver::new()?) |
| 33 | + } |
| 34 | + #[cfg(not(any(target_os = "macos", target_os = "windows", target_os = "linux")))] |
| 35 | + { |
| 36 | + println!("This example is not available on this platform."); |
| 37 | + Ok(()) |
| 38 | + } |
| 39 | +} |
21 | 40 |
|
22 | | - impl AudioOutputCallback for MyCallback { |
23 | | - fn on_output_data(&mut self, context: AudioCallbackContext, mut output: AudioOutput<f32>) { |
24 | | - if self.first_callback.swap(false, Ordering::SeqCst) { |
25 | | - println!( |
26 | | - "Actual buffer size granted by OS: {}", |
27 | | - output.buffer.num_samples() |
28 | | - ); |
29 | | - } |
| 41 | +struct MyCallback { |
| 42 | + first_callback: Arc<AtomicBool>, |
| 43 | + sine_wave: SineWave, |
| 44 | +} |
| 45 | + |
| 46 | +impl AudioOutputCallback for MyCallback { |
| 47 | + fn on_output_data(&mut self, context: AudioCallbackContext, mut output: AudioOutput<f32>) { |
| 48 | + if self.first_callback.swap(false, Ordering::SeqCst) { |
| 49 | + println!( |
| 50 | + "Actual buffer size granted by OS: {}", |
| 51 | + output.buffer.num_samples() |
| 52 | + ); |
| 53 | + } |
30 | 54 |
|
31 | | - for mut frame in output.buffer.as_interleaved_mut().rows_mut() { |
32 | | - let sample = self |
33 | | - .sine_wave |
34 | | - .next_sample(context.stream_config.samplerate as f32); |
35 | | - for channel_sample in &mut frame { |
36 | | - *channel_sample = sample; |
37 | | - } |
| 55 | + for mut frame in output.buffer.as_interleaved_mut().rows_mut() { |
| 56 | + let sample = self |
| 57 | + .sine_wave |
| 58 | + .next_sample(context.stream_config.samplerate as f32); |
| 59 | + for channel_sample in &mut frame { |
| 60 | + *channel_sample = sample; |
38 | 61 | } |
39 | 62 | } |
40 | 63 | } |
| 64 | +} |
41 | 65 |
|
| 66 | +fn run<D>(driver: D) -> anyhow::Result<()> |
| 67 | +where |
| 68 | + D: AudioDriver, |
| 69 | + D::Device: AudioOutputDevice, |
| 70 | + <D::Device as AudioDevice>::Error: std::error::Error + Send + Sync + 'static, |
| 71 | + <D::Device as AudioOutputDevice>::StreamHandle<MyCallback>: AudioStreamHandle<MyCallback>, |
| 72 | + <<D::Device as AudioOutputDevice>::StreamHandle<MyCallback> as AudioStreamHandle<MyCallback>>::Error: |
| 73 | + std::error::Error + Send + Sync + 'static, |
| 74 | +{ |
42 | 75 | env_logger::init(); |
43 | 76 |
|
44 | | - let driver = CoreAudioDriver; |
| 77 | + let full_backend_name = std::any::type_name::<D>(); |
| 78 | + let backend_name = full_backend_name |
| 79 | + .split("::") |
| 80 | + .last() |
| 81 | + .unwrap_or(full_backend_name); |
| 82 | + println!("Using backend: {}", backend_name); |
| 83 | + |
45 | 84 | let device = driver |
46 | 85 | .default_device(DeviceType::OUTPUT) |
47 | 86 | .expect("Failed to query for default output device") |
@@ -80,8 +119,3 @@ fn main() -> anyhow::Result<()> { |
80 | 119 | stream.eject()?; |
81 | 120 | Ok(()) |
82 | 121 | } |
83 | | - |
84 | | -#[cfg(not(os_coreaudio))] |
85 | | -fn main() { |
86 | | - println!("This example is only available on platforms that support CoreAudio (e.g. macOS)."); |
87 | | -} |
|
0 commit comments