//! 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) } } fn main() -> 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(3000)); Ok(()) }