-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathspdif.rs
More file actions
78 lines (69 loc) · 2.05 KB
/
spdif.rs
File metadata and controls
78 lines (69 loc) · 2.05 KB
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
use cty;
use vumeter_lib::audio_hw::AudioEvent;
use AudioEvent::*;
#[link(name = "libteensy")]
extern "C" {
fn copy_from_spdif_buffer(max : cty::uint32_t, l : *mut f32, r : *mut f32) -> cty::uint32_t;
fn config_spdif();
fn get_sample_rate() -> f32;
pub fn spdif_dma_isr();
pub fn spdif_isr();
}
pub struct SPDIF {
lbuf : [f32;128],
rbuf : [f32;128],
sr : Option<f32>
}
#[no_mangle]
static mut SPDIF_TAKEN: bool = false;
fn very_different(a : Option<f32>, b : Option<f32>) -> bool {
match a {
None => match b {
None => false,
Some(_) => true
},
Some(af) => match b {
None => true,
Some(bf) => {
let ratio = (af / bf);
ratio > 1.001 || ratio < 0.999
}
}
}
}
impl SPDIF {
pub fn initialize() -> Option<SPDIF> {
unsafe {
if SPDIF_TAKEN {return None};
SPDIF_TAKEN=true;
config_spdif();
}
Some(SPDIF{lbuf:[0.;128],rbuf:[0.;128],sr:None})
}
pub fn read<'a>(&'a mut self) -> Option<AudioEvent<impl Iterator<Item=(f32,f32)> + 'a>> {
use AudioEvent::*;
let sr = unsafe { get_sample_rate() };
let sr = if sr < 0. {None} else {Some(sr)};
if very_different(sr, self.sr) {
self.sr = sr;
match sr {
None => Some(LockLost),
Some(freq) => Some(LockAcquired(freq))
}
} else {
match self.sr {
None => None, // Waiting for SPDIF to get plugged in
Some(_) => {
let copied = unsafe {
copy_from_spdif_buffer(128, self.lbuf.as_mut_ptr(), self.rbuf.as_mut_ptr())
};
if copied > 0 {
Some(Samples(self.lbuf[0..copied as usize].iter().cloned().zip(self.rbuf[0..copied as usize].iter().cloned())))
} else {
None
}
}
}
}
}
}