-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmain.rs
87 lines (65 loc) · 1.99 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#![cfg(any(target_os = "macos", target_os = "ios"))]
extern crate rand;
extern crate coreaudio;
use coreaudio::audio_unit::{AudioUnit, IOType, SampleFormat};
use coreaudio::audio_unit::render_callback::{self, data};
use std::iter::{ Iterator, IntoIterator };
use std::f64::consts::PI;
pub const SAMPLE_HZ: f64 = 44_100.0;
#[derive(Debug)]
pub struct WhiteNoise;
impl WhiteNoise {
pub fn new() -> WhiteNoise {
WhiteNoise { }
}
}
impl Iterator for WhiteNoise {
type Item = f64;
fn next(&mut self) -> Option<Self::Item> {
Some( rand::random::<f64>() * 0.15 )
}
}
#[derive(Debug)]
pub struct SineWave {
val: f64,
}
impl SineWave {
pub fn new(val: f64) -> SineWave {
SineWave { val: val }
}
}
impl Iterator for SineWave {
type Item = f64;
fn next(&mut self) -> Option<Self::Item> {
// 男性均值 200
// 女性均值 400
self.val += 200.0 / SAMPLE_HZ;
let phase = (self.val * PI * 2.0).sin() * 0.15;
Some(phase)
}
}
fn play<S: 'static + Iterator<Item = f64>>(mut samples: S) {
let mut audio_unit = AudioUnit::new(IOType::DefaultOutput).unwrap();
let stream_format = audio_unit.output_stream_format().unwrap();
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 as f32;
}
}
Ok(())
}).unwrap();
audio_unit.start().expect("播放失败!");
std::thread::sleep(std::time::Duration::from_millis(2000));
audio_unit.stop().expect("停止播放失败!");
}
fn main() {
println!("play white noise ...");
play(WhiteNoise::new());
println!("play sine wave ...");
play(SineWave::new(0.0));
}