diff --git a/bin/cli_arranger.rs b/bin/cli_arranger.rs index 5cf780db..e275ff09 100644 --- a/bin/cli_arranger.rs +++ b/bin/cli_arranger.rs @@ -38,7 +38,7 @@ impl ArrangerCli { if let Some(name) = self.name.as_ref() { client_name = name.clone(); } - Tui::run(JackClient::new(client_name.as_str())?.activate_with(|jack|{ + Tui::run(JackConnection::new(client_name.as_str())?.activate_with(|jack|{ let mut app = ArrangerTui::try_from(jack)?; let jack = jack.read().unwrap(); app.color = ItemPalette::random(); @@ -50,7 +50,7 @@ impl ArrangerCli { } } -fn add_tracks (jack: &JackClient, app: &mut ArrangerTui, cli: &ArrangerCli) -> Usually<()> { +fn add_tracks (jack: &JackConnection, app: &mut ArrangerTui, cli: &ArrangerCli) -> Usually<()> { let n = cli.tracks; let track_color_1 = ItemColor::random(); let track_color_2 = ItemColor::random(); diff --git a/bin/cli_groovebox.rs b/bin/cli_groovebox.rs index dcc85a17..59e3c663 100644 --- a/bin/cli_groovebox.rs +++ b/bin/cli_groovebox.rs @@ -33,7 +33,7 @@ pub struct GrooveboxCli { } impl GrooveboxCli { fn run (&self) -> Usually<()> { - Tui::run(JackClient::new("tek_groovebox")?.activate_with(|jack|{ + Tui::run(JackConnection::new("tek_groovebox")?.activate_with(|jack|{ let app = tek::GrooveboxTui::try_from(jack)?; jack.read().unwrap().client().connect_ports(&app.player.midi_outs[0], &app.sampler.midi_in)?; jack.connect_midi_from(&app.player.midi_ins[0], &self.midi_from)?; @@ -44,11 +44,10 @@ impl GrooveboxCli { jack.connect_audio_to(&app.sampler.audio_outs[0], &self.l_to)?; jack.connect_audio_to(&app.sampler.audio_outs[1], &self.r_to)?; if self.sync { - jack.read().unwrap().client().register_timebase_callback(false, |state|{ - let ::jack::contrib::TimebaseInfo { state, new_pos, nframes, mut position } = state; - app.clock().playhead.update_from_sample(position.frame() as f64); - position.bbt = Some(app.clock().bbt()); - position + jack.read().unwrap().client().register_timebase_callback(false, |mut state|{ + app.clock().playhead.update_from_sample(state.position.frame() as f64); + state.position.bbt = Some(app.clock().bbt()); + state.position })? } Ok(app) diff --git a/bin/cli_sampler.rs b/bin/cli_sampler.rs index ae7f7bd1..b2305de6 100644 --- a/bin/cli_sampler.rs +++ b/bin/cli_sampler.rs @@ -8,7 +8,7 @@ pub fn main () -> Usually<()> { SamplerCli::parse().run() } } impl SamplerCli { fn run (&self) -> Usually<()> { - Tui::run(JackClient::new("tek_sampler")?.activate_with(|x|{ + Tui::run(JackConnection::new("tek_sampler")?.activate_with(|x|{ let sampler = tek::SamplerTui::try_from(x)?; Ok(sampler) })?)?; diff --git a/bin/cli_sequencer.rs b/bin/cli_sequencer.rs index e8474507..a5ef676b 100644 --- a/bin/cli_sequencer.rs +++ b/bin/cli_sequencer.rs @@ -25,7 +25,7 @@ pub struct SequencerCli { impl SequencerCli { fn run (&self) -> Usually<()> { let name = self.name.as_deref().unwrap_or("tek_sequencer"); - Tui::run(JackClient::new(name)?.activate_with(|jack|{ + Tui::run(JackConnection::new(name)?.activate_with(|jack|{ let mut app = SequencerTui::try_from(jack)?; let jack = jack.read().unwrap(); let midi_in = jack.register_port("i", MidiIn::default())?; diff --git a/bin/cli_transport.rs b/bin/cli_transport.rs index 942978fe..bb2e56b6 100644 --- a/bin/cli_transport.rs +++ b/bin/cli_transport.rs @@ -2,7 +2,7 @@ include!("./lib.rs"); /// Application entrypoint. pub fn main () -> Usually<()> { - Tui::run(JackClient::new("tek_transport")?.activate_with(|jack|{ + Tui::run(JackConnection::new("tek_transport")?.activate_with(|jack|{ TransportTui::try_from(jack) })?)?; Ok(()) diff --git a/bin/lib.rs b/bin/lib.rs index 538ecfe7..87eec13e 100644 --- a/bin/lib.rs +++ b/bin/lib.rs @@ -3,7 +3,7 @@ #[allow(unused_imports)] use tek::{*, jack::*}; #[allow(unused)] -fn connect_from (jack: &JackClient, input: &Port, ports: &[String]) -> Usually<()> { +fn connect_from (jack: &JackConnection, input: &Port, ports: &[String]) -> Usually<()> { for port in ports.iter() { if let Some(port) = jack.port_by_name(port).as_ref() { jack.client().connect_ports(port, input)?; @@ -15,7 +15,7 @@ fn connect_from (jack: &JackClient, input: &Port, ports: &[String]) -> U } #[allow(unused)] -fn connect_to (jack: &JackClient, output: &Port, ports: &[String]) -> Usually<()> { +fn connect_to (jack: &JackConnection, output: &Port, ports: &[String]) -> Usually<()> { for port in ports.iter() { if let Some(port) = jack.port_by_name(port).as_ref() { jack.client().connect_ports(output, port)?; @@ -27,7 +27,7 @@ fn connect_to (jack: &JackClient, output: &Port, ports: &[String]) -> U } #[allow(unused)] -fn connect_audio_from (jack: &JackClient, input: &Port, ports: &[String]) -> Usually<()> { +fn connect_audio_from (jack: &JackConnection, input: &Port, ports: &[String]) -> Usually<()> { for port in ports.iter() { if let Some(port) = jack.port_by_name(port).as_ref() { jack.client().connect_ports(port, input)?; @@ -39,7 +39,7 @@ fn connect_audio_from (jack: &JackClient, input: &Port, ports: &[String } #[allow(unused)] -fn connect_audio_to (jack: &JackClient, output: &Port, ports: &[String]) -> Usually<()> { +fn connect_audio_to (jack: &JackConnection, output: &Port, ports: &[String]) -> Usually<()> { for port in ports.iter() { if let Some(port) = jack.port_by_name(port).as_ref() { jack.client().connect_ports(output, port)?; diff --git a/bin/todo_cli_mixer.rs b/bin/todo_cli_mixer.rs index 4130dde9..e419ffed 100644 --- a/bin/todo_cli_mixer.rs +++ b/bin/todo_cli_mixer.rs @@ -13,7 +13,7 @@ pub fn main () -> Usually<()> { impl MixerCli { fn run (&self) -> Usually<()> { - Tui::run(JackClient::new("tek_mixer")?.activate_with(|jack|{ + Tui::run(JackConnection::new("tek_mixer")?.activate_with(|jack|{ let mut mixer = Mixer::new(jack, self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"))?; for channel in 0..self.channels.unwrap_or(8) { mixer.track_add(&format!("Track {}", channel + 1), 1)?; diff --git a/bin/todo_cli_plugin.rs b/bin/todo_cli_plugin.rs index 1b5a1ce5..cfb81fe2 100644 --- a/bin/todo_cli_plugin.rs +++ b/bin/todo_cli_plugin.rs @@ -13,7 +13,7 @@ pub fn main () -> Usually<()> { impl PluginCli { fn run (&self) -> Usually<()> { - Tui::run(JackClient::new("tek_plugin")?.activate_with(|jack|{ + Tui::run(JackConnection::new("tek_plugin")?.activate_with(|jack|{ let mut plugin = Plugin::new_lv2( jack, self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"), diff --git a/bin/todo_cli_sampler.rs b/bin/todo_cli_sampler.rs index bb72ec71..75e4c62a 100644 --- a/bin/todo_cli_sampler.rs +++ b/bin/todo_cli_sampler.rs @@ -13,7 +13,7 @@ pub fn main () -> Usually<()> { impl SamplerCli { fn run (&self) -> Usually<()> { - Tui::run(JackClient::new("tek_sampler")?.activate_with(|jack|{ + Tui::run(JackConnection::new("tek_sampler")?.activate_with(|jack|{ let mut plugin = Sampler::new( jack, self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"), diff --git a/src/arranger.rs b/src/arranger.rs index 9aea0de3..6b4ab255 100644 --- a/src/arranger.rs +++ b/src/arranger.rs @@ -10,7 +10,7 @@ mod arranger_h; /// Root view for standalone `tek_arranger` pub struct ArrangerTui { - jack: Arc>, + jack: Arc>, pub clock: ClockModel, pub phrases: PoolModel, pub tracks: Vec, diff --git a/src/edn.rs b/src/edn.rs index 8067b562..289d3e81 100644 --- a/src/edn.rs +++ b/src/edn.rs @@ -33,7 +33,7 @@ pub trait FromEdn: Sized { } } -from_edn!("sampler" => |jack: &Arc>, args| -> crate::Sampler { +from_edn!("sampler" => |jack: &Arc>, args| -> crate::Sampler { let mut name = String::new(); let mut dir = String::new(); let mut samples = BTreeMap::new(); @@ -64,7 +64,7 @@ from_edn!("sampler" => |jack: &Arc>, args| -> crate::Sampler type MidiSample = (Option, Arc>); -from_edn!("sample" => |(_jack, dir): (&Arc>, &str), args| -> MidiSample { +from_edn!("sample" => |(_jack, dir): (&Arc>, &str), args| -> MidiSample { let mut name = String::new(); let mut file = String::new(); let mut midi = None; @@ -97,7 +97,7 @@ from_edn!("sample" => |(_jack, dir): (&Arc>, &str), args| -> })))) }); -from_edn!("plugin/lv2" => |jack: &Arc>, args| -> Plugin { +from_edn!("plugin/lv2" => |jack: &Arc>, args| -> Plugin { let mut name = String::new(); let mut path = String::new(); edn!(edn in args { @@ -119,7 +119,7 @@ const SYM_GAIN: &str = ":gain"; const SYM_SAMPLER: &str = "sampler"; const SYM_LV2: &str = "lv2"; -from_edn!("mixer/track" => |jack: &Arc>, args| -> MixerTrack { +from_edn!("mixer/track" => |jack: &Arc>, args| -> MixerTrack { let mut _gain = 0.0f64; let mut track = MixerTrack { name: String::new(), diff --git a/src/groovebox.rs b/src/groovebox.rs index 932fcd5a..d3659008 100644 --- a/src/groovebox.rs +++ b/src/groovebox.rs @@ -7,7 +7,7 @@ use PhraseCommand::*; use PhrasePoolCommand::*; pub struct GrooveboxTui { - _jack: Arc>, + _jack: Arc>, pub player: MidiPlayer, pub pool: PoolModel, diff --git a/src/jack.rs b/src/jack.rs index fae62340..bf729a57 100644 --- a/src/jack.rs +++ b/src/jack.rs @@ -15,7 +15,7 @@ pub use self::activate::JackActivate; pub mod client; pub(crate) use self::client::*; -pub use self::client::JackClient; +pub use self::client::JackConnection; pub mod jack_event; pub(crate) use self::jack_event::*; @@ -24,12 +24,12 @@ pub mod ports; pub(crate) use self::ports::*; pub use self::ports::RegisterPort; -/// Implement [TryFrom<&Arc>>]: create app state from wrapped JACK handle. +/// Implement [TryFrom<&Arc>>]: create app state from wrapped JACK handle. #[macro_export] macro_rules! from_jack { (|$jack:ident|$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)? $cb:expr) => { - impl $(<$($L),*$($T $(: $U)?),*>)? TryFrom<&Arc>> for $Struct $(<$($L),*$($T),*>)? { + impl $(<$($L),*$($T $(: $U)?),*>)? TryFrom<&Arc>> for $Struct $(<$($L),*$($T),*>)? { type Error = Box; - fn try_from ($jack: &Arc>) -> Usually { + fn try_from ($jack: &Arc>) -> Usually { Ok($cb) } } diff --git a/src/jack/activate.rs b/src/jack/activate.rs index 37829f3c..5b7e4923 100644 --- a/src/jack/activate.rs +++ b/src/jack/activate.rs @@ -3,15 +3,15 @@ use crate::*; pub trait JackActivate: Sized { fn activate_with ( self, - init: impl FnOnce(&Arc>)->Usually + init: impl FnOnce(&Arc>)->Usually ) -> Usually>>; } -impl JackActivate for JackClient { +impl JackActivate for JackConnection { fn activate_with ( self, - init: impl FnOnce(&Arc>)->Usually + init: impl FnOnce(&Arc>)->Usually ) -> Usually>> { diff --git a/src/jack/client.rs b/src/jack/client.rs index be18cb0f..674737fd 100644 --- a/src/jack/client.rs +++ b/src/jack/client.rs @@ -4,7 +4,7 @@ pub type DynamicAudioHandler = ClosureProcessHandler<(), BoxedAudioHandler>; pub type BoxedAudioHandler = Box Control + Send>; /// Wraps [Client] or [DynamicAsyncClient] in place. #[derive(Debug)] -pub enum JackClient { +pub enum JackConnection { /// Before activation. Inactive(Client), /// During activation. @@ -12,18 +12,19 @@ pub enum JackClient { /// After activation. Must not be dropped for JACK thread to persist. Active(DynamicAsyncClient), } -from!(|jack: JackClient|Client = match jack { - JackClient::Inactive(client) => client, - JackClient::Activating => panic!("jack client still activating"), - JackClient::Active(_) => panic!("jack client already activated"), +from!(|jack: JackConnection|Client = match jack { + JackConnection::Inactive(client) => client, + JackConnection::Activating => panic!("jack client still activating"), + JackConnection::Active(_) => panic!("jack client already activated"), }); -impl JackClient { +impl JackConnection { pub fn new (name: &str) -> Usually { let (client, _) = Client::new(name, ClientOptions::NO_START_SERVER)?; Ok(Self::Inactive(client)) } } -impl AudioEngine for JackClient { +impl AudioEngine for JackConnection { + /// Return the internal [Client] handle that lets you call the JACK API. fn client(&self) -> &Client { match self { Self::Inactive(ref client) => client, @@ -31,6 +32,10 @@ impl AudioEngine for JackClient { Self::Active(ref client) => client.as_client(), } } + /// Bind a process callback to a `JackConnection::Inactive`, + /// turning it into a `JackConnection::Active`. Needs work. + /// Strange ownership situation between the callback and + /// the host object. fn activate( self, mut cb: impl FnMut(&Arc>, &Client, &ProcessScope) -> Control + Send + 'static, diff --git a/src/jack/ports.rs b/src/jack/ports.rs index d65ac790..584207cf 100644 --- a/src/jack/ports.rs +++ b/src/jack/ports.rs @@ -11,7 +11,7 @@ pub trait RegisterPort { fn connect_audio_to (&self, my_output: &Port, ports: &[String]) -> Usually<()>; } -impl RegisterPort for Arc> { +impl RegisterPort for Arc> { fn midi_in (&self, name: &str) -> Usually> { Ok(self.read().unwrap().client().register_port(name, MidiIn::default())?) } diff --git a/src/midi.rs b/src/midi.rs index da2f3018..f9c483aa 100644 --- a/src/midi.rs +++ b/src/midi.rs @@ -127,7 +127,7 @@ pub struct MidiPlayer { pub note_buf: Vec, } impl MidiPlayer { - pub fn new (jack: &Arc>, name: &str) -> Usually { + pub fn new (jack: &Arc>, name: &str) -> Usually { Ok(Self { clock: ClockModel::from(jack), play_phrase: None, @@ -324,7 +324,7 @@ impl HasPlayPhrase for MidiPlayer { ///// Methods used primarily by the process callback //impl MIDIPlayer { //pub fn new ( - //jack: &Arc>, + //jack: &Arc>, //clock: &Arc, //name: &str //) -> Usually { diff --git a/src/mixer.rs b/src/mixer.rs index 71aba47f..54c28716 100644 --- a/src/mixer.rs +++ b/src/mixer.rs @@ -3,7 +3,7 @@ use crate::*; #[derive(Debug)] pub struct Mixer { /// JACK client handle (needs to not be dropped for standalone mode to work). - pub jack: Arc>, + pub jack: Arc>, pub name: String, pub tracks: Vec, pub selected_track: usize, @@ -25,7 +25,7 @@ pub struct MixerTrack { audio!(|self: Mixer, _client, _scope|Control::Continue); impl Mixer { - pub fn new (jack: &Arc>, name: &str) -> Usually { + pub fn new (jack: &Arc>, name: &str) -> Usually { Ok(Self { jack: jack.clone(), name: name.into(), diff --git a/src/plugin.rs b/src/plugin.rs index 63595c17..c6f8e493 100644 --- a/src/plugin.rs +++ b/src/plugin.rs @@ -7,7 +7,7 @@ pub use self::lv2::LV2Plugin; #[derive(Debug)] pub struct Plugin { /// JACK client handle (needs to not be dropped for standalone mode to work). - pub jack: Arc>, + pub jack: Arc>, pub name: String, pub path: Option, pub plugin: Option, @@ -40,7 +40,7 @@ impl Debug for PluginKind { } impl Plugin { pub fn new_lv2 ( - jack: &Arc>, + jack: &Arc>, name: &str, path: &str, ) -> Usually { @@ -131,7 +131,7 @@ audio!(|self: PluginAudio, client, scope|{ impl Plugin { /// Create a plugin host device. pub fn new ( - jack: &Arc>, + jack: &Arc>, name: &str, ) -> Usually { Ok(Self { diff --git a/src/sampler.rs b/src/sampler.rs index 54926e09..363bba41 100644 --- a/src/sampler.rs +++ b/src/sampler.rs @@ -35,7 +35,7 @@ pub use self::sample_viewer::SampleViewer; /// The sampler plugin plays sounds. #[derive(Debug)] pub struct Sampler { - pub jack: Arc>, + pub jack: Arc>, pub name: String, pub mapped: [Option>>;128], pub recording: Option<(usize, Arc>)>, @@ -49,7 +49,7 @@ pub struct Sampler { pub output_gain: f32 } impl Sampler { - pub fn new (jack: &Arc>, name: &str) -> Usually { + pub fn new (jack: &Arc>, name: &str) -> Usually { Ok(Self { midi_in: jack.midi_in(&format!("M/{name}"))?, audio_ins: vec![ diff --git a/src/sequencer.rs b/src/sequencer.rs index 791279c9..d24f5511 100644 --- a/src/sequencer.rs +++ b/src/sequencer.rs @@ -6,7 +6,7 @@ use PhraseCommand::*; use PhrasePoolCommand::*; /// Root view for standalone `tek_sequencer`. pub struct SequencerTui { - _jack: Arc>, + _jack: Arc>, pub transport: bool, pub selectors: bool, pub clock: ClockModel, diff --git a/src/time.rs b/src/time.rs index 0f1241c8..a8fd4112 100644 --- a/src/time.rs +++ b/src/time.rs @@ -82,7 +82,7 @@ pub struct ClockModel { pub chunk: Arc, } -from!(|jack: &Arc>| ClockModel = { +from!(|jack: &Arc>| ClockModel = { let jack = jack.read().unwrap(); let chunk = jack.client().buffer_size(); let transport = jack.client().transport(); diff --git a/src/transport.rs b/src/transport.rs index 629217d1..5a1cb9e2 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -5,7 +5,7 @@ use FocusCommand::{Next, Prev}; use KeyCode::{Enter, Left, Right, Char}; /// Transport clock app. pub struct TransportTui { - pub jack: Arc>, + pub jack: Arc>, pub clock: ClockModel, pub size: Measure, pub cursor: (usize, usize),