From e15b8bffec381ea648d668fdb8b80c8b6a7ec31d Mon Sep 17 00:00:00 2001 From: Sebastian Imlay Date: Thu, 4 Apr 2024 21:14:17 -0400 Subject: [PATCH] Add sine integration test --- examples/sine.rs | 2 +- tests/sine.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 tests/sine.rs diff --git a/examples/sine.rs b/examples/sine.rs index 5d99b9660..2fb5a00e4 100644 --- a/examples/sine.rs +++ b/examples/sine.rs @@ -44,7 +44,7 @@ fn main() -> Result<(), coreaudio::Error> { // Read the input format. This is counterintuitive, but it's the format used when sending // audio data to the AudioUnit representing the output device. This is separate from the // format the AudioUnit later uses to send the data to the hardware device. - let stream_format = audio_unit.input_stream_format()?; + let stream_format = audio_unit.output_stream_format()?; println!("{:#?}", &stream_format); // For this example, our sine wave expects `f32` data. diff --git a/tests/sine.rs b/tests/sine.rs new file mode 100644 index 000000000..2e06c9393 --- /dev/null +++ b/tests/sine.rs @@ -0,0 +1,75 @@ + +//! A basic output stream example, using an Output AudioUnit to generate a sine wave. + +extern crate coreaudio; + +use coreaudio::audio_unit::render_callback::{self, data}; +use coreaudio::audio_unit::{AudioUnit, IOType, SampleFormat}; +use std::f64::consts::PI; + +struct SineWaveGenerator { + time: f64, + /// generated frequency in Hz + freq: f64, + /// magnitude of generated signal + volume: f64, +} + +impl SineWaveGenerator { + fn new(freq: f64, volume: f64) -> Self { + SineWaveGenerator { + time: 0., + freq, + volume, + } + } +} + +impl Iterator for SineWaveGenerator { + type Item = f32; + fn next(&mut self) -> Option { + self.time += 1. / 44_100.; + let output = ((self.freq * self.time * PI * 2.).sin() * self.volume) as f32; + Some(output) + } +} + +#[test] +fn sine() -> Result<(), coreaudio::Error> { + let frequency_hz = 440.; + let volume = 0.15; + let mut samples = SineWaveGenerator::new(frequency_hz, volume); + + // Construct an Output audio unit that delivers audio to the default output device. + let mut audio_unit = AudioUnit::new(IOType::DefaultOutput)?; + + // Read the input format. This is counterintuitive, but it's the format used when sending + // audio data to the AudioUnit representing the output device. This is separate from the + // format the AudioUnit later uses to send the data to the hardware device. + let stream_format = audio_unit.output_stream_format()?; + println!("{:#?}", &stream_format); + + // For this example, our sine wave expects `f32` data. + assert!(SampleFormat::F32 == stream_format.sample_format); + + type Args = render_callback::Args>; + audio_unit.set_render_callback(move |args| { + let Args { + num_frames, + mut data, + .. + } = args; + for i in 0..num_frames { + let sample = samples.next().unwrap(); + for channel in data.channels_mut() { + channel[i] = sample; + } + } + Ok(()) + })?; + audio_unit.start()?; + + std::thread::sleep(std::time::Duration::from_millis(50)); + + Ok(()) +}