use std::convert::From;
use std::io;
use std::sync::mpsc::sync_channel;
const MAX_MIDI: usize = 3;
#[derive(Copy, Clone)]
struct MidiCopy {
len: usize,
data: [u8; MAX_MIDI],
time: jack::Frames,
}
impl From<jack::RawMidi<'_>> for MidiCopy {
fn from(midi: jack::RawMidi<'_>) -> Self {
let len = std::cmp::min(MAX_MIDI, midi.bytes.len());
let mut data = [0; MAX_MIDI];
data[..len].copy_from_slice(&midi.bytes[..len]);
MidiCopy {
len,
data,
time: midi.time,
}
}
}
impl std::fmt::Debug for MidiCopy {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"Midi {{ time: {}, len: {}, data: {:?} }}",
self.time,
self.len,
&self.data[..self.len]
)
}
}
fn main() {
let (client, _status) =
jack::Client::new("rust_jack_show_midi", jack::ClientOptions::default()).unwrap();
let (sender, receiver) = sync_channel(64);
let mut maker = client
.register_port("rust_midi_maker", jack::MidiOut::default())
.unwrap();
let shower = client
.register_port("rust_midi_shower", jack::MidiIn::default())
.unwrap();
let cback = move |_: &jack::Client, ps: &jack::ProcessScope| -> jack::Control {
let show_p = shower.iter(ps);
for e in show_p {
let c: MidiCopy = e.into();
let _ = sender.try_send(c);
}
let mut put_p = maker.writer(ps);
put_p
.write(&jack::RawMidi {
time: 0,
bytes: &[
0b10010000,
0b01000000,
0b01111111,
],
})
.unwrap();
put_p
.write(&jack::RawMidi {
time: ps.n_frames() / 2,
bytes: &[
0b10000000,
0b01000000,
0b01111111,
],
})
.unwrap();
jack::Control::Continue
};
let active_client = client
.activate_async((), jack::contrib::ClosureProcessHandler::new(cback))
.unwrap();
std::thread::spawn(move || {
while let Ok(m) = receiver.recv() {
println!("{m:?}");
}
});
println!("Press any key to quit");
let mut user_input = String::new();
io::stdin().read_line(&mut user_input).ok();
if let Err(err) = active_client.deactivate() {
eprintln!("JACK exited with error: {err}");
};
}