pub(crate) use std::sync::{Arc, RwLock}; pub(crate) use std::collections::BTreeMap; pub use ::jack; pub(crate) use ::jack::{ contrib::ClosureProcessHandler, NotificationHandler, Client, AsyncClient, ClientOptions, ClientStatus, ProcessScope, Control, Frames, Port, PortId, PortSpec, PortFlags, Unowned, MidiIn, MidiOut, AudioIn, AudioOut, }; mod from_jack; pub use self::from_jack::*; mod has_jack; pub use self::has_jack::*; mod jack_audio; pub use self::jack_audio::*; mod jack_connect; pub use self::jack_connect::*; mod jack_event; pub use self::jack_event::*; mod jack_port; pub use self::jack_port::*; pub(crate) type Usually = Result>; //////////////////////////////////////////////////////////////////////////////////// ///// `JackDevice` factory. Creates JACK `Client`s, performs port registration ///// and activation, and encapsulates a `AudioComponent` into a `JackDevice`. //pub struct Jack { //pub client: Client, //pub midi_ins: Vec, //pub audio_ins: Vec, //pub midi_outs: Vec, //pub audio_outs: Vec, //} //impl Jack { //pub fn new(name: &str) -> Usually { //Ok(Self { //midi_ins: vec![], //audio_ins: vec![], //midi_outs: vec![], //audio_outs: vec![], //client: Client::new(name, ClientOptions::NO_START_SERVER)?.0, //}) //} //pub fn run<'a: 'static, D, E>( //self, //state: impl FnOnce(JackPorts) -> Box, //) -> Usually> //where //D: AudioComponent + Sized + 'static, //E: Engine + 'static, //{ //let owned_ports = JackPorts { //audio_ins: register_ports(&self.client, self.audio_ins, AudioIn::default())?, //audio_outs: register_ports(&self.client, self.audio_outs, AudioOut::default())?, //midi_ins: register_ports(&self.client, self.midi_ins, MidiIn::default())?, //midi_outs: register_ports(&self.client, self.midi_outs, MidiOut::default())?, //}; //let midi_outs = owned_ports //.midi_outs //.values() //.map(|p| Ok(p.name()?)) //.collect::>>()?; //let midi_ins = owned_ports //.midi_ins //.values() //.map(|p| Ok(p.name()?)) //.collect::>>()?; //let audio_outs = owned_ports //.audio_outs //.values() //.map(|p| Ok(p.name()?)) //.collect::>>()?; //let audio_ins = owned_ports //.audio_ins //.values() //.map(|p| Ok(p.name()?)) //.collect::>>()?; //let state = Arc::new(RwLock::new(state(owned_ports) as Box>)); //let client = self.client.activate_async( //Notifications(Box::new({ //let _state = state.clone(); //move |_event| { //// FIXME: this deadlocks ////state.lock().unwrap().handle(&event).unwrap(); //} //}) as Box), //ClosureProcessHandler::new(Box::new({ //let state = state.clone(); //move |c: &Client, s: &ProcessScope| state.write().unwrap().process(c, s) //}) as BoxedAudioHandler), //)?; //Ok(JackDevice { //ports: UnownedJackPorts { //audio_ins: query_ports(&client.as_client(), audio_ins), //audio_outs: query_ports(&client.as_client(), audio_outs), //midi_ins: query_ports(&client.as_client(), midi_ins), //midi_outs: query_ports(&client.as_client(), midi_outs), //}, //client, //state, //}) //} //pub fn audio_in(mut self, name: &str) -> Self { //self.audio_ins.push(name.to_string()); //self //} //pub fn audio_out(mut self, name: &str) -> Self { //self.audio_outs.push(name.to_string()); //self //} //pub fn midi_in(mut self, name: &str) -> Self { //self.midi_ins.push(name.to_string()); //self //} //pub fn midi_out(mut self, name: &str) -> Self { //self.midi_outs.push(name.to_string()); //self //} //} ///// A UI component that may be associated with a JACK client by the `Jack` factory. //pub trait AudioComponent: Component + Audio { ///// Perform type erasure for collecting heterogeneous devices. //fn boxed(self) -> Box> //where //Self: Sized + 'static, //{ //Box::new(self) //} //} ///// All things that implement the required traits can be treated as `AudioComponent`. //impl + Audio> AudioComponent for W {} ///////// /* */