1 //! A basic output stream example, using an Output AudioUnit to generate a sine wave.
2 
3 extern crate coreaudio;
4 
5 use coreaudio::audio_unit::{AudioUnit, IOType, SampleFormat};
6 use coreaudio::audio_unit::render_callback::{self, data};
7 use std::f64::consts::PI;
8 
9 struct SineWaveGenerator {
10     time: f64,
11     /// generated frequency in Hz
12     freq: f64,
13     /// magnitude of generated signal
14     volume: f64,
15 }
16 
17 impl SineWaveGenerator {
new(freq: f64, volume: f64) -> Self18     fn new(freq: f64, volume: f64) -> Self {
19         SineWaveGenerator {
20             time: 0.,
21             freq,
22             volume,
23         }
24     }
25 }
26 
27 impl Iterator for SineWaveGenerator {
28     type Item = f32;
next(&mut self) -> Option<f32>29     fn next(&mut self) -> Option<f32> {
30         self.time += 1. / 44_100.;
31         let output = ((self.freq * self.time * PI * 2.).sin() * self.volume) as f32;
32         Some(output)
33     }
34 }
35 
main() -> Result<(), coreaudio::Error>36 fn main() -> Result<(), coreaudio::Error> {
37     let frequency_hz = 440.;
38     let volume = 0.15;
39     let mut samples = SineWaveGenerator::new(frequency_hz, volume);
40 
41     // Construct an Output audio unit that delivers audio to the default output device.
42     let mut audio_unit = AudioUnit::new(IOType::DefaultOutput)?;
43 
44     let stream_format = audio_unit.output_stream_format()?;
45     println!("{:#?}", &stream_format);
46 
47     // For this example, our sine wave expects `f32` data.
48     assert!(SampleFormat::F32 == stream_format.sample_format);
49 
50     type Args = render_callback::Args<data::NonInterleaved<f32>>;
51     audio_unit.set_render_callback(move |args| {
52         let Args { num_frames, mut data, .. } = args;
53         for i in 0..num_frames {
54             let sample = samples.next().unwrap();
55             for channel in data.channels_mut() {
56                 channel[i] = sample;
57             }
58         }
59         Ok(())
60     })?;
61     audio_unit.start()?;
62 
63     std::thread::sleep(std::time::Duration::from_millis(3000));
64 
65     Ok(())
66 }
67