74 lines
2.1 KiB
Rust
74 lines
2.1 KiB
Rust
//! 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<f32> {
|
|
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.input_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<data::NonInterleaved<f32>>;
|
|
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(())
|
|
}
|