-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsfnov.rs
91 lines (78 loc) · 2.25 KB
/
sfnov.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
88
89
90
91
use dev_helpers::rtrb;
use dev_helpers::{AudioHost, AudioProcessor};
use microdsp::sfnov::{HardKneeCompression, SpectralFluxNoveltyDetector};
use std::thread;
use std::time::Duration;
enum DetectorMessage {
NoveltyValue(f32),
}
const WINDOW_SIZE: usize = 1024;
type DetectorType = SpectralFluxNoveltyDetector<HardKneeCompression>;
struct NoveltyDetectorProcessor {
detector: DetectorType,
}
impl NoveltyDetectorProcessor {
fn new() -> Self {
NoveltyDetectorProcessor {
detector: DetectorType::new(WINDOW_SIZE),
}
}
}
impl AudioProcessor<DetectorMessage> for NoveltyDetectorProcessor {
fn process(
&mut self,
in_buffer: &[f32],
_: &mut [f32],
_: usize,
to_main_thread: &mut rtrb::Producer<DetectorMessage>,
_: &mut rtrb::Consumer<DetectorMessage>,
) -> bool {
self.detector.process(in_buffer, |novelty| {
let _ = to_main_thread.push(DetectorMessage::NoveltyValue(novelty.novelty()));
});
true
}
}
struct PeakDetector {
threshold: f32,
is_armed: bool,
}
impl PeakDetector {
fn new(threshold: f32) -> Self {
PeakDetector {
threshold,
is_armed: true,
}
}
fn process(&mut self, input: f32) -> bool {
if input > self.threshold && self.is_armed {
self.is_armed = false;
return true;
} else if input < self.threshold {
self.is_armed = true;
};
false
}
}
fn main() {
let sample_rate = 44100.0;
let mut audio_host = AudioHost::new(sample_rate, NoveltyDetectorProcessor::new());
println!("Listening for sounds...");
let poll_interval_ms = 30;
let mut novelty_peak_detector = PeakDetector::new(0.4);
loop {
thread::sleep(Duration::from_millis(poll_interval_ms));
loop {
match audio_host.from_audio_thread.pop() {
Ok(message) => match message {
DetectorMessage::NoveltyValue(value) => {
if novelty_peak_detector.process(value) {
println!("Onset detected (novelty {value})")
}
}
},
_ => {}
}
}
}
}