//! Takes 2 audio inputs and outputs them to 2 audio outputs. //! All JACK notifications are also printed out. use std::io; fn main() { // Create client jack::set_logger(jack::LoggerType::Stdio); let (client, _status) = jack::Client::new("rust_jack_simple", jack::ClientOptions::default()).unwrap(); // Register ports. They will be used in a callback that will be // called when new data is available. let in_a = client .register_port("rust_in_l", jack::AudioIn::default()) .unwrap(); let in_b = client .register_port("rust_in_r", jack::AudioIn::default()) .unwrap(); let mut out_a = client .register_port("rust_out_l", jack::AudioOut::default()) .unwrap(); let mut out_b = client .register_port("rust_out_r", jack::AudioOut::default()) .unwrap(); let process_callback = move |_: &jack::Client, ps: &jack::ProcessScope| -> jack::Control { let out_a_p = out_a.as_mut_slice(ps); let out_b_p = out_b.as_mut_slice(ps); let in_a_p = in_a.as_slice(ps); let in_b_p = in_b.as_slice(ps); out_a_p.clone_from_slice(in_a_p); out_b_p.clone_from_slice(in_b_p); jack::Control::Continue }; let process = jack::contrib::ClosureProcessHandler::new(process_callback); // Activate the client, which starts the processing. let active_client = client.activate_async(Notifications, process).unwrap(); // 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(); if let Err(err) = active_client.deactivate() { eprintln!("JACK exited with error: {err}"); }; } struct Notifications; impl jack::NotificationHandler for Notifications { fn thread_init(&self, _: &jack::Client) { println!("JACK: thread init"); } /// Not much we can do here, see https://man7.org/linux/man-pages/man7/signal-safety.7.html. unsafe fn shutdown(&mut self, _: jack::ClientStatus, _: &str) {} fn freewheel(&mut self, _: &jack::Client, is_enabled: bool) { println!( "JACK: freewheel mode is {}", if is_enabled { "on" } else { "off" } ); } fn sample_rate(&mut self, _: &jack::Client, srate: jack::Frames) -> jack::Control { println!("JACK: sample rate changed to {srate}"); jack::Control::Continue } fn client_registration(&mut self, _: &jack::Client, name: &str, is_reg: bool) { println!( "JACK: {} client with name \"{}\"", if is_reg { "registered" } else { "unregistered" }, name ); } fn port_registration(&mut self, _: &jack::Client, port_id: jack::PortId, is_reg: bool) { println!( "JACK: {} port with id {}", if is_reg { "registered" } else { "unregistered" }, port_id ); } fn port_rename( &mut self, _: &jack::Client, port_id: jack::PortId, old_name: &str, new_name: &str, ) -> jack::Control { println!("JACK: port with id {port_id} renamed from {old_name} to {new_name}",); jack::Control::Continue } fn ports_connected( &mut self, _: &jack::Client, port_id_a: jack::PortId, port_id_b: jack::PortId, are_connected: bool, ) { println!( "JACK: ports with id {} and {} are {}", port_id_a, port_id_b, if are_connected { "connected" } else { "disconnected" } ); } fn graph_reorder(&mut self, _: &jack::Client) -> jack::Control { println!("JACK: graph reordered"); jack::Control::Continue } fn xrun(&mut self, _: &jack::Client) -> jack::Control { println!("JACK: xrun occurred"); jack::Control::Continue } }