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
88
89
90
91
92
93
94
95
96
97
|
use cpal::traits::HostTrait;
use cpal::traits::DeviceTrait;
use cpal::traits::StreamTrait;
use std::time;
use std::thread;
use std::sync::mpsc;
struct AudioSink {
recv: mpsc::Receiver<Box<[f32]>>,
buffer: Option<Box<[f32]>>,
idx: usize
}
impl AudioSink {
fn new(recv: mpsc::Receiver<Box<[f32]>>) -> Self {
Self {
recv: recv,
buffer: None,
idx: 0
}
}
fn pour(&mut self, mut dst: &mut [f32], i: usize) {
loop {
match self.buffer.as_ref() {
Some(src) => {
let src_new = &src[self.idx..];
let count = std::cmp::min(src_new.len(), dst.len());
let src_new = &src_new[..count];
let dst_new = &mut dst[..count];
dst_new.copy_from_slice(&src_new);
self.idx += count;
if self.idx >= src.len() {
self.buffer = None;
self.idx = 0;
}
if dst.len() > count {
dst = &mut dst[count..];
continue;
}
return;
},
None => {
self.buffer = Some(self.recv.recv().unwrap());
}
};
}
}
}
fn main() {
let host = cpal::default_host();
let dev = host.default_output_device().expect("no audio device found");
let cfg: cpal::StreamConfig = dev.supported_output_configs()
.expect("couldn't find configs")
.next()
.expect("bogus device")
.with_max_sample_rate().into();
let denom = cfg.sample_rate.0 as f32 * cfg.channels as f32;
let (send, recv) = mpsc::sync_channel(1);
let mut snk = AudioSink::new(recv);
let mut snum: f32 = 0.0;
let stream = dev.build_output_stream(
&cfg,
move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
snk.pour(data, 0);
},
move |err| {
println!("err: {}", err);
}
).expect("could not build stream");
stream.play().unwrap();
let mut snum: usize = 0;
loop {
let mut samples = vec![0.0f32;1024].into_boxed_slice();
for s in samples.iter_mut() {
*s += (snum as f32 / denom * 2.0 * 3.141592 * 200.0 as f32).sin();
snum = snum.wrapping_add(1);
}
send.send(samples).unwrap();
}
}
|