diff options
Diffstat (limited to 'third_party/rust/midir/examples')
-rw-r--r-- | third_party/rust/midir/examples/test_forward.rs | 65 | ||||
-rw-r--r-- | third_party/rust/midir/examples/test_list_ports.rs | 46 | ||||
-rw-r--r-- | third_party/rust/midir/examples/test_play.rs | 74 | ||||
-rw-r--r-- | third_party/rust/midir/examples/test_read_input.rs | 58 | ||||
-rw-r--r-- | third_party/rust/midir/examples/test_reuse.rs | 82 | ||||
-rw-r--r-- | third_party/rust/midir/examples/test_sysex.rs | 79 |
6 files changed, 404 insertions, 0 deletions
diff --git a/third_party/rust/midir/examples/test_forward.rs b/third_party/rust/midir/examples/test_forward.rs new file mode 100644 index 0000000000..1ecb142c2e --- /dev/null +++ b/third_party/rust/midir/examples/test_forward.rs @@ -0,0 +1,65 @@ +extern crate midir; + +use std::io::{stdin, stdout, Write}; +use std::error::Error; + +use midir::{MidiInput, MidiOutput, MidiIO, Ignore}; + +fn main() { + match run() { + Ok(_) => (), + Err(err) => println!("Error: {}", err) + } +} + +#[cfg(not(target_arch = "wasm32"))] // conn_out is not `Send` in Web MIDI, which means it cannot be passed to connect +fn run() -> Result<(), Box<dyn Error>> { + let mut midi_in = MidiInput::new("midir forwarding input")?; + midi_in.ignore(Ignore::None); + let midi_out = MidiOutput::new("midir forwarding output")?; + + let in_port = select_port(&midi_in, "input")?; + println!(); + let out_port = select_port(&midi_out, "output")?; + + println!("\nOpening connections"); + let in_port_name = midi_in.port_name(&in_port)?; + let out_port_name = midi_out.port_name(&out_port)?; + + let mut conn_out = midi_out.connect(&out_port, "midir-forward")?; + + // _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, "midir-forward", move |stamp, message, _| { + conn_out.send(message).unwrap_or_else(|_| println!("Error when forwarding message ...")); + println!("{}: {:?} (len = {})", stamp, message, message.len()); + }, ())?; + + println!("Connections open, forwarding from '{}' to '{}' (press enter to exit) ...", in_port_name, out_port_name); + + let mut input = String::new(); + stdin().read_line(&mut input)?; // wait for next enter key press + + println!("Closing connections"); + Ok(()) +} + +fn select_port<T: MidiIO>(midi_io: &T, descr: &str) -> Result<T::Port, Box<dyn Error>> { + println!("Available {} ports:", descr); + let midi_ports = midi_io.ports(); + for (i, p) in midi_ports.iter().enumerate() { + println!("{}: {}", i, midi_io.port_name(p)?); + } + print!("Please select {} port: ", descr); + stdout().flush()?; + let mut input = String::new(); + stdin().read_line(&mut input)?; + let port = midi_ports.get(input.trim().parse::<usize>()?) + .ok_or("Invalid port number")?; + Ok(port.clone()) +} + +#[cfg(target_arch = "wasm32")] +fn run() -> Result<(), Box<dyn Error>> { + println!("test_forward cannot run on Web MIDI"); + Ok(()) +} diff --git a/third_party/rust/midir/examples/test_list_ports.rs b/third_party/rust/midir/examples/test_list_ports.rs new file mode 100644 index 0000000000..4bc4c6b948 --- /dev/null +++ b/third_party/rust/midir/examples/test_list_ports.rs @@ -0,0 +1,46 @@ +extern crate midir; + +use std::io::{stdin, stdout, Write}; +use std::error::Error; + +use midir::{MidiInput, MidiOutput, Ignore}; + +fn main() { + match run() { + Ok(_) => (), + Err(err) => println!("Error: {}", err) + } +} + +fn run() -> Result<(), Box<dyn Error>> { + let mut midi_in = MidiInput::new("midir test input")?; + midi_in.ignore(Ignore::None); + let midi_out = MidiOutput::new("midir test output")?; + + let mut input = String::new(); + + loop { + println!("Available input ports:"); + for (i, p) in midi_in.ports().iter().enumerate() { + println!("{}: {}", i, midi_in.port_name(p)?); + } + + println!("\nAvailable output ports:"); + for (i, p) in midi_out.ports().iter().enumerate() { + println!("{}: {}", i, midi_out.port_name(p)?); + } + + // run in endless loop if "--loop" parameter is specified + match ::std::env::args().nth(1) { + Some(ref arg) if arg == "--loop" => {} + _ => break + } + print!("\nPress <enter> to retry ..."); + stdout().flush()?; + input.clear(); + stdin().read_line(&mut input)?; + println!("\n"); + } + + Ok(()) +} diff --git a/third_party/rust/midir/examples/test_play.rs b/third_party/rust/midir/examples/test_play.rs new file mode 100644 index 0000000000..d34e87f8aa --- /dev/null +++ b/third_party/rust/midir/examples/test_play.rs @@ -0,0 +1,74 @@ +extern crate midir; + +use std::thread::sleep; +use std::time::Duration; +use std::io::{stdin, stdout, Write}; +use std::error::Error; + +use midir::{MidiOutput, MidiOutputPort}; + +fn main() { + match run() { + Ok(_) => (), + Err(err) => println!("Error: {}", err) + } +} + +fn run() -> Result<(), Box<dyn Error>> { + let midi_out = MidiOutput::new("My Test Output")?; + + // Get an output port (read from console if multiple are available) + let out_ports = midi_out.ports(); + let out_port: &MidiOutputPort = match out_ports.len() { + 0 => return Err("no output port found".into()), + 1 => { + println!("Choosing the only available output port: {}", midi_out.port_name(&out_ports[0]).unwrap()); + &out_ports[0] + }, + _ => { + println!("\nAvailable output ports:"); + for (i, p) in out_ports.iter().enumerate() { + println!("{}: {}", i, midi_out.port_name(p).unwrap()); + } + print!("Please select output port: "); + stdout().flush()?; + let mut input = String::new(); + stdin().read_line(&mut input)?; + out_ports.get(input.trim().parse::<usize>()?) + .ok_or("invalid output port selected")? + } + }; + + println!("\nOpening connection"); + let mut conn_out = midi_out.connect(out_port, "midir-test")?; + println!("Connection open. Listen!"); + { + // Define a new scope in which the closure `play_note` borrows conn_out, so it can be called easily + let mut play_note = |note: u8, duration: u64| { + const NOTE_ON_MSG: u8 = 0x90; + const NOTE_OFF_MSG: u8 = 0x80; + const VELOCITY: u8 = 0x64; + // We're ignoring errors in here + let _ = conn_out.send(&[NOTE_ON_MSG, note, VELOCITY]); + sleep(Duration::from_millis(duration * 150)); + let _ = conn_out.send(&[NOTE_OFF_MSG, note, VELOCITY]); + }; + + sleep(Duration::from_millis(4 * 150)); + + play_note(66, 4); + play_note(65, 3); + play_note(63, 1); + play_note(61, 6); + play_note(59, 2); + play_note(58, 4); + play_note(56, 4); + play_note(54, 4); + } + sleep(Duration::from_millis(150)); + println!("\nClosing connection"); + // This is optional, the connection would automatically be closed as soon as it goes out of scope + conn_out.close(); + println!("Connection closed"); + Ok(()) +} diff --git a/third_party/rust/midir/examples/test_read_input.rs b/third_party/rust/midir/examples/test_read_input.rs new file mode 100644 index 0000000000..321ccc7d15 --- /dev/null +++ b/third_party/rust/midir/examples/test_read_input.rs @@ -0,0 +1,58 @@ +extern crate midir; + +use std::io::{stdin, stdout, Write}; +use std::error::Error; + +use midir::{MidiInput, Ignore}; + +fn main() { + match run() { + Ok(_) => (), + Err(err) => println!("Error: {}", err) + } +} + +fn run() -> Result<(), Box<dyn Error>> { + let mut input = String::new(); + + let mut midi_in = MidiInput::new("midir reading input")?; + midi_in.ignore(Ignore::None); + + // Get an input port (read from console if multiple are available) + let in_ports = midi_in.ports(); + let in_port = match in_ports.len() { + 0 => return Err("no input port found".into()), + 1 => { + println!("Choosing the only available input port: {}", midi_in.port_name(&in_ports[0]).unwrap()); + &in_ports[0] + }, + _ => { + println!("\nAvailable input ports:"); + for (i, p) in in_ports.iter().enumerate() { + println!("{}: {}", i, midi_in.port_name(p).unwrap()); + } + print!("Please select input port: "); + stdout().flush()?; + let mut input = String::new(); + stdin().read_line(&mut input)?; + in_ports.get(input.trim().parse::<usize>()?) + .ok_or("invalid input port selected")? + } + }; + + println!("\nOpening connection"); + let in_port_name = midi_in.port_name(in_port)?; + + // _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, "midir-read-input", move |stamp, message, _| { + println!("{}: {:?} (len = {})", stamp, message, message.len()); + }, ())?; + + println!("Connection open, reading input from '{}' (press enter to exit) ...", in_port_name); + + input.clear(); + stdin().read_line(&mut input)?; // wait for next enter key press + + println!("Closing connection"); + Ok(()) +} diff --git a/third_party/rust/midir/examples/test_reuse.rs b/third_party/rust/midir/examples/test_reuse.rs new file mode 100644 index 0000000000..79eeaf9b37 --- /dev/null +++ b/third_party/rust/midir/examples/test_reuse.rs @@ -0,0 +1,82 @@ +extern crate midir; + +use std::thread::sleep; +use std::time::Duration; +use std::io::{stdin, stdout, Write}; +use std::error::Error; + +use midir::{MidiInput, MidiOutput, Ignore}; + +fn main() { + match run() { + Ok(_) => (), + Err(err) => println!("Error: {}", err) + } +} + +fn run() -> Result<(), Box<dyn Error>> { + let mut input = String::new(); + + let mut midi_in = MidiInput::new("My Test Input")?; + midi_in.ignore(Ignore::None); + let mut midi_out = MidiOutput::new("My Test Output")?; + + println!("Available input ports:"); + let midi_in_ports = midi_in.ports(); + for (i, p) in midi_in_ports.iter().enumerate() { + println!("{}: {}", i, midi_in.port_name(p)?); + } + print!("Please select input port: "); + stdout().flush()?; + stdin().read_line(&mut input)?; + let in_port = midi_in_ports.get(input.trim().parse::<usize>()?) + .ok_or("Invalid port number")?; + + println!("\nAvailable output ports:"); + let midi_out_ports = midi_out.ports(); + for (i, p) in midi_out_ports.iter().enumerate() { + println!("{}: {}", i, midi_out.port_name(p)?); + } + print!("Please select output port: "); + stdout().flush()?; + input.clear(); + stdin().read_line(&mut input)?; + let out_port = midi_out_ports.get(input.trim().parse::<usize>()?) + .ok_or("Invalid port number")?; + + // This shows how to reuse input and output objects: + // Open/close the connections twice using the same MidiInput/MidiOutput objects + for _ in 0..2 { + println!("\nOpening connections"); + let log_all_bytes = Vec::new(); // We use this as an example custom data to pass into the callback + let conn_in = midi_in.connect(in_port, "midir-test", |stamp, message, log| { + // The last of the three callback parameters is the object that we pass in as last parameter of `connect`. + println!("{}: {:?} (len = {})", stamp, message, message.len()); + log.extend_from_slice(message); + }, log_all_bytes)?; + + // One could get the log back here out of the error + let mut conn_out = midi_out.connect(out_port, "midir-test")?; + + println!("Connections open, enter `q` to exit ..."); + + loop { + input.clear(); + stdin().read_line(&mut input)?; + if input.trim() == "q" { + break; + } else { + conn_out.send(&[144, 60, 1])?; + sleep(Duration::from_millis(200)); + conn_out.send(&[144, 60, 0])?; + } + } + println!("Closing connections"); + let (midi_in_, log_all_bytes) = conn_in.close(); + midi_in = midi_in_; + midi_out = conn_out.close(); + println!("Connections closed"); + println!("Received bytes: {:?}", log_all_bytes); + } + Ok(()) +} diff --git a/third_party/rust/midir/examples/test_sysex.rs b/third_party/rust/midir/examples/test_sysex.rs new file mode 100644 index 0000000000..79149b3c39 --- /dev/null +++ b/third_party/rust/midir/examples/test_sysex.rs @@ -0,0 +1,79 @@ +extern crate midir; + +fn main() { + match example::run() { + Ok(_) => (), + Err(err) => println!("Error: {}", err) + } +} + +#[cfg(not(any(windows, target_arch = "wasm32")))] // virtual ports are not supported on Windows nor on Web MIDI +mod example { + +use std::thread::sleep; +use std::time::Duration; +use std::error::Error; + +use midir::{MidiInput, MidiOutput, Ignore}; +use midir::os::unix::VirtualInput; + +const LARGE_SYSEX_SIZE: usize = 5572; // This is the maximum that worked for me + +pub fn run() -> Result<(), Box<dyn Error>> { + let mut midi_in = MidiInput::new("My Test Input")?; + midi_in.ignore(Ignore::None); + let midi_out = MidiOutput::new("My Test Output")?; + + let previous_count = midi_out.port_count(); + + println!("Creating virtual input port ..."); + let conn_in = midi_in.create_virtual("midir-test", |stamp, message, _| { + println!("{}: {:?} (len = {})", stamp, message, message.len()); + }, ())?; + + assert_eq!(midi_out.port_count(), previous_count + 1); + + let out_ports = midi_out.ports(); + let new_port = out_ports.last().unwrap(); + println!("Connecting to port '{}' ...", midi_out.port_name(&new_port).unwrap()); + let mut conn_out = midi_out.connect(&new_port, "midir-test")?; + println!("Starting to send messages ..."); + //sleep(Duration::from_millis(2000)); + println!("Sending NoteOn message"); + conn_out.send(&[144, 60, 1])?; + sleep(Duration::from_millis(200)); + println!("Sending small SysEx message ..."); + conn_out.send(&[0xF0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xF7])?; + sleep(Duration::from_millis(200)); + println!("Sending large SysEx message ..."); + let mut v = Vec::with_capacity(LARGE_SYSEX_SIZE); + v.push(0xF0u8); + for _ in 1..LARGE_SYSEX_SIZE-1 { + v.push(0u8); + } + v.push(0xF7u8); + assert_eq!(v.len(), LARGE_SYSEX_SIZE); + conn_out.send(&v)?; + sleep(Duration::from_millis(200)); + // FIXME: the following doesn't seem to work with ALSA + println!("Sending large SysEx message (chunked)..."); + for ch in v.chunks(4) { + conn_out.send(ch)?; + } + sleep(Duration::from_millis(200)); + println!("Sending small SysEx message ..."); + conn_out.send(&[0xF0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xF7])?; + sleep(Duration::from_millis(200)); + println!("Closing output ..."); + conn_out.close(); + println!("Closing virtual input ..."); + conn_in.close().0; + Ok(()) +} +} + + // needed to compile successfully +#[cfg(any(windows, target_arch = "wasm32"))] mod example { + use std::error::Error; + pub fn run() -> Result<(), Box<dyn Error>> { Ok(()) } +} |