-
Notifications
You must be signed in to change notification settings - Fork 4
/
send_and_receive_control_change.rs
98 lines (78 loc) · 2.79 KB
/
send_and_receive_control_change.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
92
93
94
95
96
97
98
#![allow(clippy::restriction)]
use std::sync::{mpsc, Arc, Mutex};
use libpd_rs::{
functions::{
block_size, close_patch, open_patch, receive::on_midi_control_change,
send::send_control_change, util::dsp_on,
},
Pd,
};
#[test]
fn send_and_receive_control_change() {
let sample_rate = 44100;
let output_channels = 2;
let control_change_messages_received: Arc<Mutex<Vec<(i32, i32, i32)>>> =
Arc::new(Mutex::new(vec![]));
let pd = Pd::init_and_configure(0, output_channels, sample_rate).unwrap();
let ctx = pd.audio_context();
dsp_on().unwrap();
let patch_handle = open_patch("tests/patches/echo.pd").unwrap();
let messages_to_fill = control_change_messages_received.clone();
on_midi_control_change(move |channel, controller_number, value| {
messages_to_fill
.lock()
.unwrap()
.push((channel, controller_number, value));
});
let (tx, rx) = mpsc::channel::<()>();
let handle = std::thread::spawn(move || {
// Mimic audio callback buffers.
let input_buffer = [0.0f32; 512];
let mut output_buffer = [0.0f32; 1024];
// Run pd
loop {
// Mimic an audio callback.
let approximate_buffer_duration =
(output_buffer.len() as f32 / sample_rate as f32) * 1000.0;
std::thread::sleep(std::time::Duration::from_millis(
approximate_buffer_duration as u64,
));
ctx.receive_midi_messages_from_pd();
let ticks = output_buffer.len() as i32 / (block_size() * output_channels);
ctx.process_float(ticks, &input_buffer, &mut output_buffer);
match rx.try_recv() {
Ok(_) => break,
_ => continue,
}
}
});
let mut channel: i32 = 0;
let mut controller_number: i32 = 0;
let mut value: i32 = 1;
#[allow(clippy::explicit_counter_loop)]
// Send 5 note on messages in sequence.
for _ in 0..5 {
send_control_change(channel, controller_number, value).unwrap();
channel += 1;
controller_number += 1;
value += 1;
}
std::thread::sleep(std::time::Duration::from_millis(50));
// Stop pd.
tx.send(()).unwrap();
handle.join().unwrap();
let values_to_compare: Vec<(i32, i32, i32)> =
vec![(0, 0, 1), (1, 1, 2), (2, 2, 3), (3, 3, 4), (4, 4, 5)];
assert_eq!(control_change_messages_received.lock().unwrap().len(), 5);
control_change_messages_received
.lock()
.unwrap()
.iter()
.zip(values_to_compare.iter())
.for_each(|((c1, p1, v1), (c2, p2, v2))| {
assert_eq!(c1, c2);
assert_eq!(p1, p2);
assert_eq!(v1, v2);
});
close_patch(patch_handle).unwrap();
}