diff --git a/Cargo.lock b/Cargo.lock index b64724cb3f09a26586a6ef103f5b5ef2f05890dc..044c33a4041955431dbb4a9e58467b67ad8d2285 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,6 +21,23 @@ dependencies = [ "syn", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + [[package]] name = "bitflags" version = "1.2.1" @@ -39,16 +56,83 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "3.0.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", + "strsim", + "termcolor", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clap_derive" +version = "3.0.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +dependencies = [ + "libc", +] + [[package]] name = "hexmatrix" version = "0.1.0" dependencies = [ "arr_macro", + "clap", "jack", "libc", "rosc", ] +[[package]] +name = "indexmap" +version = "1.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "jack" version = "0.7.1" @@ -94,6 +178,36 @@ dependencies = [ "winapi", ] +[[package]] +name = "os_str_bytes" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro-hack" version = "0.5.19" @@ -127,6 +241,12 @@ dependencies = [ "byteorder", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "1.0.73" @@ -138,12 +258,54 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "unicode-segmentation" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + [[package]] name = "unicode-xid" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + [[package]] name = "winapi" version = "0.3.9" @@ -160,6 +322,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index cec92eec817ef28d420a8de14ac9d24e0be68646..999c2dd719a1def9ca32f3070f4dbdad82468378 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ name = "hexmatrix" version = "0.1.0" authors = ["David Huss <dh@atoav.com>"] edition = "2018" +description = "A 16×16 channel matrix mixer for Jack, controllable via OSC" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -10,4 +11,5 @@ edition = "2018" jack = "0.7" libc = "0.2" rosc = "~0.5" -arr_macro = "0.1.3" \ No newline at end of file +arr_macro = "0.1.3" +clap = { version = "3.0.0-beta.2", features = ["color", "suggestions"] } \ No newline at end of file diff --git a/README.md b/README.md index 06f13509c8d4ebe928e8bc19f81aacac4b93e179..6193982f67a4a67c844a63e8ab1d0111942c249a 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ A matrix mixer allows you to send any input to any number of outputs. Internal c 1. Start up hexmatrix and patch the jack connections to taste (e.g. using Catia) -2. Send OSC messages to `127.0.0.1:7011` (as for now hardcoded) +2. Send OSC messages to the chosen ip-address and port (see `hexmatrix --help`) diff --git a/src/main.rs b/src/main.rs index 6b171d14fe2008851ab3b35a2ea1212d7f7ad2e0..00074567dac98bd43c49f13a956360694ebc6ad3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ use std::net::{SocketAddrV4, UdpSocket}; use std::str::FromStr; use std::sync::atomic::{AtomicUsize, Ordering}; use arr_macro::arr; +use clap::{Arg, App}; @@ -43,14 +44,47 @@ static VOLS16: [AtomicUsize; 16] = arr![AtomicUsize::new(0); 16]; fn main() { + let matches = App::new(option_env!("CARGO_PKG_NAME").unwrap()) + .version(option_env!("CARGO_PKG_VERSION").unwrap()) + .about(option_env!("CARGO_PKG_DESCRIPTION").unwrap()) + .help_template("{bin} ({version})\n{about}\n\nUsage:\n {usage}\n\nTo send a certain amount of one input to a output send a OSC message that looks like this: /ch/1/send/16 <volume>\nThis would set the send volume of input 1 to output 16 to the value of <volume>. A value of 0.0 would be off, a value of 1.0 would result in a unattenuated signal. Values above 1.0 result in amplification.\n\nOSC-Addresses:\n /ch/<in>/send/<out> <volume> Set the send volume (in → out)\n\nOptions:\n{options}") + .arg(Arg::new("--host") + .long("--host") + .value_name("HOST") + .required(true) + .about(format!("Set IP-address of {}", option_env!("CARGO_PKG_NAME").unwrap()).as_str()) + .takes_value(true)) + .arg(Arg::new("--receiving-port") + .long("--receiving-port") + .value_name("INPORT") + .required(true) + .about("Set receiving port (OSC)") + .takes_value(true)) + .arg(Arg::new("--sending-port") + .long("--sending-port") + .value_name("OUTPORT") + .about("Set sending port (OSC)") + .takes_value(true)) + .arg(Arg::new("--name") + .long("--name") + .value_name("NAME") + .about("Set the name of the jack node") + .takes_value(true)) + .get_matches(); + + + + let ip = matches.value_of("--host").unwrap(); + let inport = matches.value_of("--receiving-port").unwrap(); + // Receive OSC-Packets at this address - let addr = SocketAddrV4::from_str("127.0.0.1:7011").expect("Please use a valid IP:Port addr"); + let addr = SocketAddrV4::from_str(format!("{}:{}", ip, inport).as_str()).expect("Please use a valid IP:Port addr"); let sock = UdpSocket::bind(addr).unwrap(); let mut buf = [0u8; rosc::decoder::MTU]; // Create new jack client (visible e.g. in Catia) let (client, _status) = - jack::Client::new("Hexmatrix", jack::ClientOptions::NO_START_SERVER).expect("Couldn't connect to jack server. Not running?"); + jack::Client::new(matches.value_of("--name").unwrap_or("Hexmatrix"), jack::ClientOptions::NO_START_SERVER).expect("Couldn't connect to jack server. Not running?"); // Open n Jack Input Ports via arr! macro. let mut i = 0u16; @@ -246,7 +280,7 @@ struct Notifications; impl jack::NotificationHandler for Notifications { fn thread_init(&self, _: &jack::Client) { - println!("JACK: thread init"); + // println!("JACK: thread init"); } fn shutdown(&mut self, status: jack::ClientStatus, reason: &str) { @@ -256,11 +290,11 @@ impl jack::NotificationHandler for Notifications { ); } - fn freewheel(&mut self, _: &jack::Client, is_enabled: bool) { - println!( - "JACK: freewheel mode is {}", - if is_enabled { "on" } else { "off" } - ); + 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 { @@ -268,62 +302,62 @@ impl jack::NotificationHandler for Notifications { 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 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_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, + _port_id: jack::PortId, + _old_name: &str, + _new_name: &str, ) -> jack::Control { - println!( - "JACK: port with id {} renamed from {} to {}", - port_id, old_name, new_name - ); + // println!( + // "JACK: port with id {} renamed from {} to {}", + // port_id, old_name, 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, + _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" - } - ); + // 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"); + // println!("JACK: graph reordered"); jack::Control::Continue } fn xrun(&mut self, _: &jack::Client) -> jack::Control { - println!("JACK: xrun occurred"); + // println!("JACK: xrun occurred"); jack::Control::Continue }