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
use std::io;
use std::sync::{
atomic::{AtomicBool, Ordering},
Arc,
};
fn main() {
// Create client
let (client, _status) =
jack::Client::new("rust_jack_trans", jack::ClientOptions::default()).unwrap();
let transport = client.transport();
let stop = Arc::new(AtomicBool::new(false));
let show = {
let stop = stop.clone();
std::thread::spawn(move || {
let mut state_last: Option<jack::TransportStatePosition> = None;
while !stop.load(Ordering::Relaxed) {
std::thread::sleep(std::time::Duration::from_millis(10));
if let Ok(state) = transport.query() {
//print if state has changed
if state_last
.as_ref()
.map_or_else(|| true, |l| l.state != state.state)
{
println!("{:?}", state.state);
};
//print if bbt structure changes (ignoring tick and bar_start_tick)
if let Some(mut bbt) = state.pos.bbt() {
let print = if let Some(last) = &state_last {
if let Some(mut last) = last.pos.bbt() {
//zero out some details so we can just compare directly
bbt.tick = 0;
bbt.bar_start_tick = 0.0;
last.tick = 0;
last.bar_start_tick = 0.0;
bbt != last
} else {
true
}
} else {
true
};
if print {
println!(
"bar {} beat {} bpm {} sig: {}/{} tpb {}",
bbt.bar,
bbt.beat,
bbt.bpm,
bbt.sig_num,
bbt.sig_denom,
bbt.ticks_per_beat
);
}
}
state_last = Some(state);
} else {
eprint!("couldn't get state");
break;
}
}
})
};
// Wait for user input to quit
println!("Press enter/return to quit...");
let mut user_input = String::new();
io::stdin().read_line(&mut user_input).ok();
stop.store(true, Ordering::Relaxed);
show.join().expect("failed to join");
}