47 lines
1.6 KiB
Rust
47 lines
1.6 KiB
Rust
use crate::config::NanoKeys;
|
|
use crossbeam_channel::Sender;
|
|
use midir::{Ignore, MidiInput};
|
|
use regex::Regex;
|
|
use std::error::Error;
|
|
use std::time;
|
|
|
|
pub fn list_ports() -> () {
|
|
let midi_in = MidiInput::new("PicoKontroller").expect("Creating Midi device failed");
|
|
let in_ports = midi_in.ports();
|
|
println!("All available midi devices:");
|
|
for (_, p) in in_ports.iter().enumerate() {
|
|
println!("{}", midi_in.port_name(p).unwrap());
|
|
}
|
|
}
|
|
|
|
pub fn run(port_name: &str, out_channel: Sender<KeyEvent>) -> Result<(), Box<dyn Error>> {
|
|
let port_filter = Regex::new(port_name).expect("Creating RegEx failed");
|
|
|
|
let mut midi_in = MidiInput::new("PicoKontroller").expect("Creating Midi device failed");
|
|
midi_in.ignore(Ignore::None);
|
|
|
|
let in_ports = midi_in.ports();
|
|
let in_port = in_ports
|
|
.iter()
|
|
.find(|p| port_filter.is_match(&midi_in.port_name(p).unwrap()))
|
|
.expect("Couldn't find a port matching the supplied RegEx");
|
|
|
|
// _conn_in needs to be a named parameter, because it needs to be kept alive until the end of the scope
|
|
let _conn_in = midi_in.connect(
|
|
in_port,
|
|
"PicoController Input",
|
|
move |_, message, _| {
|
|
let key = NanoKeys::try_from(message[1]).unwrap();
|
|
let state = message[2];
|
|
let _ = out_channel.send((key, state));
|
|
},
|
|
(),
|
|
)?;
|
|
loop {
|
|
// sleep forever, callback functions happen on separate thread
|
|
// couldn't reuse this thread, since _conn_in needs to be alive in this scope
|
|
std::thread::sleep(time::Duration::from_secs(u64::MAX));
|
|
}
|
|
}
|
|
|
|
pub type KeyEvent = (NanoKeys, u8);
|