From e08a79b5072499dabfdebc70f830cadeb775aa22 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Fri, 27 Dec 2024 14:46:35 +0100 Subject: [PATCH] wip: multi-crate refactor --- Cargo.lock | 19 +++- Cargo.toml | 7 +- crates/cli/Cargo.toml | 40 +++++++ .../{tek/src/cli => cli/src}/cli_arranger.rs | 5 +- crates/cli/src/cli_groovebox.rs | 22 ++++ .../{tek/src/cli => cli/src}/cli_sampler.rs | 12 +-- .../{tek/src/cli => cli/src}/cli_sequencer.rs | 5 +- .../{tek/src/cli => cli/src}/cli_transport.rs | 5 +- crates/cli/src/lib.rs | 3 + .../src/cli => cli/src}/todo_cli_mixer.rs | 2 +- .../src/cli => cli/src}/todo_cli_plugin.rs | 2 +- .../src/cli => cli/src}/todo_cli_sampler.rs | 2 +- crates/edn/Cargo.toml | 8 ++ crates/{tek/src/edn.rs => edn/src/lib.rs} | 80 +++++++++++++- crates/suil/Cargo.toml | 3 +- crates/tek/Cargo.toml | 34 ------ crates/tek/src/audio.rs | 12 ++- crates/tek/src/audio/channel.rs | 56 ---------- crates/tek/src/cli/cli_groovebox.rs | 27 ----- crates/tek/src/jack.rs | 100 ++++++++++++++++-- crates/tek/src/jack/audio.rs | 78 -------------- crates/tek/src/lib.rs | 25 +++-- crates/tek/src/plugin/lv2.rs | 19 ---- crates/tek/src/tui.rs | 9 ++ crates/tek/src/tui/app_sampler.rs | 1 - 25 files changed, 311 insertions(+), 265 deletions(-) create mode 100644 crates/cli/Cargo.toml rename crates/{tek/src/cli => cli/src}/cli_arranger.rs (98%) create mode 100644 crates/cli/src/cli_groovebox.rs rename crates/{tek/src/cli => cli/src}/cli_sampler.rs (69%) rename crates/{tek/src/cli => cli/src}/cli_sequencer.rs (97%) rename crates/{tek/src/cli => cli/src}/cli_transport.rs (73%) create mode 100644 crates/cli/src/lib.rs rename crates/{tek/src/cli => cli/src}/todo_cli_mixer.rs (97%) rename crates/{tek/src/cli => cli/src}/todo_cli_plugin.rs (97%) rename crates/{tek/src/cli => cli/src}/todo_cli_sampler.rs (96%) create mode 100644 crates/edn/Cargo.toml rename crates/{tek/src/edn.rs => edn/src/lib.rs} (60%) delete mode 100644 crates/tek/src/cli/cli_groovebox.rs delete mode 100644 crates/tek/src/jack/audio.rs diff --git a/Cargo.lock b/Cargo.lock index bfd59c5e..cf73e7ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -1268,7 +1268,6 @@ dependencies = [ "atomic_float", "backtrace", "better-panic", - "clap", "clojure-reader", "crossterm", "jack", @@ -1285,6 +1284,22 @@ dependencies = [ "wavers", ] +[[package]] +name = "tek_cli" +version = "0.2.0" +dependencies = [ + "clap", + "tek", +] + +[[package]] +name = "tek_edn" +version = "0.2.0" +dependencies = [ + "clojure-reader", + "tek", +] + [[package]] name = "thiserror" version = "1.0.69" diff --git a/Cargo.toml b/Cargo.toml index 72ee139a..b502f8c8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,11 +2,8 @@ resolver = "2" members = [ "crates/tek", - #"crates/tek_core", - #"crates/tek_api", - #"crates/tek_tui", - #"crates/tek_cli", - #"crates/tek_layout" + "crates/cli", + "crates/edn", ] [profile.release] diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml new file mode 100644 index 00000000..75d1321f --- /dev/null +++ b/crates/cli/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "tek_cli" +edition = "2021" +version = "0.2.0" + +[dependencies] +tek = { path = "../tek" } +clap = { version = "4.5.4", features = [ "derive" ] } + +[[bin]] +name = "tek_arranger" +path = "src/cli_arranger.rs" + +[[bin]] +name = "tek_sequencer" +path = "src/cli_sequencer.rs" + +[[bin]] +name = "tek_groovebox" +path = "src/cli_groovebox.rs" + +[[bin]] +name = "tek_transport" +path = "src/cli_transport.rs" + +[[bin]] +name = "tek_sampler" +path = "src/cli_sampler.rs" + +#[[bin]] +#name = "tek_mixer" +#path = "src/cli_mixer.rs" + +#[[bin]] +#name = "tek_track" +#path = "src/cli_track.rs" + +#[[bin]] +#name = "tek_plugin" +#path = "src/cli_plugin.rs" diff --git a/crates/tek/src/cli/cli_arranger.rs b/crates/cli/src/cli_arranger.rs similarity index 98% rename from crates/tek/src/cli/cli_arranger.rs rename to crates/cli/src/cli_arranger.rs index 57697699..6c218c8e 100644 --- a/crates/tek/src/cli/cli_arranger.rs +++ b/crates/cli/src/cli_arranger.rs @@ -1,6 +1,5 @@ -#![allow(unused)] -#![allow(clippy::unit_arg)] -include!("../lib.rs"); +include!("./lib.rs"); +use tek::tui::ArrangerTui; pub fn main () -> Usually<()> { ArrangerCli::parse().run() diff --git a/crates/cli/src/cli_groovebox.rs b/crates/cli/src/cli_groovebox.rs new file mode 100644 index 00000000..f4c10ac2 --- /dev/null +++ b/crates/cli/src/cli_groovebox.rs @@ -0,0 +1,22 @@ +include!("./lib.rs"); +pub fn main () -> Usually<()> { GrooveboxCli::parse().run() } +#[derive(Debug, Parser)] +#[command(version, about, long_about = None)] +pub struct GrooveboxCli; +impl GrooveboxCli { + fn run (&self) -> Usually<()> { + Tui::run(JackClient::new("tek_groovebox")?.activate_with(|jack|{ + let app = tek::tui::GrooveboxTui::try_from(jack)?; + let jack = jack.read().unwrap(); + let midi_out = jack.register_port("out", MidiOut::default())?; + let midi_in_1 = jack.register_port("in1", MidiIn::default())?; + let midi_in_2 = jack.register_port("in2", MidiIn::default())?; + let audio_in_1 = jack.register_port("inL", AudioIn::default())?; + let audio_in_2 = jack.register_port("inR", AudioIn::default())?; + let audio_out_1 = jack.register_port("out1", AudioOut::default())?; + let audio_out_2 = jack.register_port("out2", AudioOut::default())?; + Ok(app) + })?)?; + Ok(()) + } +} diff --git a/crates/tek/src/cli/cli_sampler.rs b/crates/cli/src/cli_sampler.rs similarity index 69% rename from crates/tek/src/cli/cli_sampler.rs rename to crates/cli/src/cli_sampler.rs index aeda9da0..55601c18 100644 --- a/crates/tek/src/cli/cli_sampler.rs +++ b/crates/cli/src/cli_sampler.rs @@ -1,21 +1,15 @@ -#![allow(unused)] -#![allow(clippy::unit_arg)] -include!("../lib.rs"); -pub fn main () -> Usually<()> { - SamplerCli::parse().run() -} - +include!("./lib.rs"); +pub fn main () -> Usually<()> { SamplerCli::parse().run() } #[derive(Debug, Parser)] #[command(version, about, long_about = None)] pub struct SamplerCli { /// Name of JACK client #[arg(short, long)] name: Option, /// Path to plugin #[arg(short, long)] path: Option, } - impl SamplerCli { fn run (&self) -> Usually<()> { Tui::run(JackClient::new("tek_sampler")?.activate_with(|x|{ - let sampler = SamplerTui::try_from(x)?; + let sampler = tek::tui::SamplerTui::try_from(x)?; Ok(sampler) })?)?; Ok(()) diff --git a/crates/tek/src/cli/cli_sequencer.rs b/crates/cli/src/cli_sequencer.rs similarity index 97% rename from crates/tek/src/cli/cli_sequencer.rs rename to crates/cli/src/cli_sequencer.rs index 619f9381..fcbb8e9f 100644 --- a/crates/tek/src/cli/cli_sequencer.rs +++ b/crates/cli/src/cli_sequencer.rs @@ -1,6 +1,5 @@ -#![allow(unused)] -#![allow(clippy::unit_arg)] -include!("../lib.rs"); +include!("./lib.rs"); + pub fn main () -> Usually<()> { SequencerCli::parse().run() } diff --git a/crates/tek/src/cli/cli_transport.rs b/crates/cli/src/cli_transport.rs similarity index 73% rename from crates/tek/src/cli/cli_transport.rs rename to crates/cli/src/cli_transport.rs index 68fb9c7c..942978fe 100644 --- a/crates/tek/src/cli/cli_transport.rs +++ b/crates/cli/src/cli_transport.rs @@ -1,6 +1,5 @@ -#![allow(unused)] -#![allow(clippy::unit_arg)] -include!("../lib.rs"); +include!("./lib.rs"); + /// Application entrypoint. pub fn main () -> Usually<()> { Tui::run(JackClient::new("tek_transport")?.activate_with(|jack|{ diff --git a/crates/cli/src/lib.rs b/crates/cli/src/lib.rs new file mode 100644 index 00000000..5fc4389e --- /dev/null +++ b/crates/cli/src/lib.rs @@ -0,0 +1,3 @@ +use std::sync::Arc; +use clap::{self, Parser}; +use tek::{*, jack::*}; diff --git a/crates/tek/src/cli/todo_cli_mixer.rs b/crates/cli/src/todo_cli_mixer.rs similarity index 97% rename from crates/tek/src/cli/todo_cli_mixer.rs rename to crates/cli/src/todo_cli_mixer.rs index d14f9807..4130dde9 100644 --- a/crates/tek/src/cli/todo_cli_mixer.rs +++ b/crates/cli/src/todo_cli_mixer.rs @@ -1,4 +1,4 @@ -use crate::*; +include!("./lib.rs"); pub fn main () -> Usually<()> { MixerCli::parse().run() diff --git a/crates/tek/src/cli/todo_cli_plugin.rs b/crates/cli/src/todo_cli_plugin.rs similarity index 97% rename from crates/tek/src/cli/todo_cli_plugin.rs rename to crates/cli/src/todo_cli_plugin.rs index 06acc9bf..1b5a1ce5 100644 --- a/crates/tek/src/cli/todo_cli_plugin.rs +++ b/crates/cli/src/todo_cli_plugin.rs @@ -1,4 +1,4 @@ -use crate::*; +include!("./lib.rs"); pub fn main () -> Usually<()> { PluginCli::parse().run() diff --git a/crates/tek/src/cli/todo_cli_sampler.rs b/crates/cli/src/todo_cli_sampler.rs similarity index 96% rename from crates/tek/src/cli/todo_cli_sampler.rs rename to crates/cli/src/todo_cli_sampler.rs index 0fcc8a7d..bb72ec71 100644 --- a/crates/tek/src/cli/todo_cli_sampler.rs +++ b/crates/cli/src/todo_cli_sampler.rs @@ -1,4 +1,4 @@ -use crate::*; +include!("./lib.rs"); pub fn main () -> Usually<()> { SamplerCli::parse().run() diff --git a/crates/edn/Cargo.toml b/crates/edn/Cargo.toml new file mode 100644 index 00000000..01bab065 --- /dev/null +++ b/crates/edn/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "tek_edn" +edition = "2021" +version = "0.2.0" + +[dependencies] +tek = { path = "../tek" } +clojure-reader = "0.1.0" diff --git a/crates/tek/src/edn.rs b/crates/edn/src/lib.rs similarity index 60% rename from crates/tek/src/edn.rs rename to crates/edn/src/lib.rs index c60ba9ca..28b2d67b 100644 --- a/crates/tek/src/edn.rs +++ b/crates/edn/src/lib.rs @@ -1,6 +1,7 @@ -#![allow(unused)] +use tek::{*, jack::*}; +use std::sync::{Arc, RwLock}; +use std::collections::BTreeMap; -use crate::*; pub use clojure_reader::edn::Edn; //pub use clojure_reader::{edn::{read, Edn}, error::Error as EdnError}; @@ -107,6 +108,81 @@ from_edn!(|(jack, dir) = (&Arc>, &str), "sample", args| -> Mi })))) }); +impl LV2Plugin { + pub fn from_edn <'e> (jack: &Arc>, args: &[Edn<'e>]) -> Usually { + let mut name = String::new(); + let mut path = String::new(); + edn!(edn in args { + Edn::Map(map) => { + if let Some(Edn::Str(n)) = map.get(&Edn::Key(":name")) { + name = String::from(*n); + } + if let Some(Edn::Str(p)) = map.get(&Edn::Key(":path")) { + path = String::from(*p); + } + }, + _ => panic!("unexpected in lv2 '{name}'"), + }); + Plugin::new_lv2(jack, &name, &path) + } +} + +impl MixerTrack { + const SYM_NAME: &'static str = ":name"; + const SYM_GAIN: &'static str = ":gain"; + const SYM_SAMPLER: &'static str = "sampler"; + const SYM_LV2: &'static str = "lv2"; + pub fn from_edn <'a, 'e> (jack: &Arc>, args: &[Edn<'e>]) -> Usually { + let mut _gain = 0.0f64; + let mut track = MixerTrack { + name: String::new(), + audio_ins: vec![], + audio_outs: vec![], + devices: vec![], + }; + edn!(edn in args { + Edn::Map(map) => { + if let Some(Edn::Str(n)) = map.get(&Edn::Key(Self::SYM_NAME)) { + track.name = n.to_string(); + } + if let Some(Edn::Double(g)) = map.get(&Edn::Key(Self::SYM_GAIN)) { + _gain = f64::from(*g); + } + }, + Edn::List(args) => match args.get(0) { + // Add a sampler device to the track + Some(Edn::Symbol(Self::SYM_SAMPLER)) => { + track.devices.push( + Box::new(Sampler::from_edn(jack, &args[1..])?) as Box + ); + panic!( + "unsupported in track {}: {:?}; tek_mixer not compiled with feature \"sampler\"", + &track.name, + args.get(0).unwrap() + ) + }, + // Add a LV2 plugin to the track. + Some(Edn::Symbol(Self::SYM_LV2)) => { + track.devices.push( + Box::new(LV2Plugin::from_edn(jack, &args[1..])?) as Box + ); + panic!( + "unsupported in track {}: {:?}; tek_mixer not compiled with feature \"plugin\"", + &track.name, + args.get(0).unwrap() + ) + }, + None => + panic!("empty list track {}", &track.name), + _ => + panic!("unexpected in track {}: {:?}", &track.name, args.get(0).unwrap()) + }, + _ => {} + }); + Ok(track) + } +} + //impl ArrangerScene { ////TODO diff --git a/crates/suil/Cargo.toml b/crates/suil/Cargo.toml index db586670..7e6211bd 100644 --- a/crates/suil/Cargo.toml +++ b/crates/suil/Cargo.toml @@ -1,11 +1,12 @@ [package] -name = "suil-rs" +name = "tek_suil" version = "0.1.0" edition = "2021" [dependencies] gtk = "0.18.1" livi = "0.7.4" +#winit = { version = "0.30.4", features = [ "x11" ] } [build-dependencies] bindgen = "0.69.4" diff --git a/crates/tek/Cargo.toml b/crates/tek/Cargo.toml index 5c22e156..71d2ad10 100644 --- a/crates/tek/Cargo.toml +++ b/crates/tek/Cargo.toml @@ -9,7 +9,6 @@ version = "0.2.0" atomic_float = "1.0.0" backtrace = "0.3.72" better-panic = "0.3.0" -clap = { version = "4.5.4", features = [ "derive" ] } clojure-reader = "0.1.0" crossterm = "0.27" jack = "0.13" @@ -29,37 +28,4 @@ wavers = "1.4.3" #winit = { version = "0.30.4", features = [ "x11" ] } [lib] -name = "tek_lib" path = "src/lib.rs" - -[[bin]] -name = "tek_arranger" -path = "src/cli/cli_arranger.rs" - -[[bin]] -name = "tek_sequencer" -path = "src/cli/cli_sequencer.rs" - -[[bin]] -name = "tek_groovebox" -path = "src/cli/cli_groovebox.rs" - -[[bin]] -name = "tek_transport" -path = "src/cli/cli_transport.rs" - -[[bin]] -name = "tek_sampler" -path = "src/cli/cli_sampler.rs" - -#[[bin]] -#name = "tek_mixer" -#path = "src/cli_mixer.rs" - -#[[bin]] -#name = "tek_track" -#path = "src/cli_track.rs" - -#[[bin]] -#name = "tek_plugin" -#path = "src/cli_plugin.rs" diff --git a/crates/tek/src/audio.rs b/crates/tek/src/audio.rs index a44f6276..24900710 100644 --- a/crates/tek/src/audio.rs +++ b/crates/tek/src/audio.rs @@ -1,3 +1,9 @@ -pub(crate) mod audio_in; -pub(crate) mod audio_out; -pub(crate) mod sampler; pub(crate) use sampler::*; +use crate::*; + +mod audio_in; + +mod audio_out; + +mod sampler; +pub(crate) use sampler::*; +pub use self::sampler::{Sampler, Sample, Voice}; diff --git a/crates/tek/src/audio/channel.rs b/crates/tek/src/audio/channel.rs index 513a6934..b850147a 100644 --- a/crates/tek/src/audio/channel.rs +++ b/crates/tek/src/audio/channel.rs @@ -16,62 +16,6 @@ pub struct MixerTrack { //impl MixerTrackDevice for LV2Plugin {} -impl MixerTrack { - const SYM_NAME: &'static str = ":name"; - const SYM_GAIN: &'static str = ":gain"; - const SYM_SAMPLER: &'static str = "sampler"; - const SYM_LV2: &'static str = "lv2"; - pub fn from_edn <'a, 'e> (jack: &Arc>, args: &[Edn<'e>]) -> Usually { - let mut _gain = 0.0f64; - let mut track = MixerTrack { - name: String::new(), - audio_ins: vec![], - audio_outs: vec![], - devices: vec![], - }; - edn!(edn in args { - Edn::Map(map) => { - if let Some(Edn::Str(n)) = map.get(&Edn::Key(Self::SYM_NAME)) { - track.name = n.to_string(); - } - if let Some(Edn::Double(g)) = map.get(&Edn::Key(Self::SYM_GAIN)) { - _gain = f64::from(*g); - } - }, - Edn::List(args) => match args.get(0) { - // Add a sampler device to the track - Some(Edn::Symbol(Self::SYM_SAMPLER)) => { - track.devices.push( - Box::new(Sampler::from_edn(jack, &args[1..])?) as Box - ); - panic!( - "unsupported in track {}: {:?}; tek_mixer not compiled with feature \"sampler\"", - &track.name, - args.get(0).unwrap() - ) - }, - // Add a LV2 plugin to the track. - Some(Edn::Symbol(Self::SYM_LV2)) => { - track.devices.push( - Box::new(LV2Plugin::from_edn(jack, &args[1..])?) as Box - ); - panic!( - "unsupported in track {}: {:?}; tek_mixer not compiled with feature \"plugin\"", - &track.name, - args.get(0).unwrap() - ) - }, - None => - panic!("empty list track {}", &track.name), - _ => - panic!("unexpected in track {}: {:?}", &track.name, args.get(0).unwrap()) - }, - _ => {} - }); - Ok(track) - } -} - pub trait MixerTrackDevice: Debug + Send + Sync { fn boxed (self) -> Box where Self: Sized + 'static { Box::new(self) diff --git a/crates/tek/src/cli/cli_groovebox.rs b/crates/tek/src/cli/cli_groovebox.rs deleted file mode 100644 index d3339871..00000000 --- a/crates/tek/src/cli/cli_groovebox.rs +++ /dev/null @@ -1,27 +0,0 @@ -#![allow(unused)] -#![allow(clippy::unit_arg)] -include!("../lib.rs"); -pub fn main () -> Usually<()> { - GrooveboxCli::parse().run() -} - -#[derive(Debug, Parser)] -#[command(version, about, long_about = None)] -pub struct GrooveboxCli; - -impl GrooveboxCli { - fn run (&self) -> Usually<()> { - Tui::run(JackClient::new("tek_groovebox")?.activate_with(|jack|{ - let app = GrooveboxTui::try_from(jack)?; - let midi_out = jack.read().unwrap().register_port("out", MidiOut::default())?; - let midi_in_1 = jack.read().unwrap().register_port("in1", MidiIn::default())?; - let midi_in_2 = jack.read().unwrap().register_port("in2", MidiIn::default())?; - let audio_in_1 = jack.read().unwrap().register_port("inL", AudioIn::default())?; - let audio_in_2 = jack.read().unwrap().register_port("inR", AudioIn::default())?; - let audio_out_1 = jack.read().unwrap().register_port("out1", AudioOut::default())?; - let audio_out_2 = jack.read().unwrap().register_port("out2", AudioOut::default())?; - Ok(app) - })?)?; - Ok(()) - } -} diff --git a/crates/tek/src/jack.rs b/crates/tek/src/jack.rs index ee6f698e..0a21d92d 100644 --- a/crates/tek/src/jack.rs +++ b/crates/tek/src/jack.rs @@ -1,10 +1,7 @@ +use crate::*; + pub use ::jack as libjack; -pub(crate) mod activate; #[allow(unused)] pub(crate) use self::activate::*; -pub(crate) mod audio; pub(crate) use self::audio::*; -pub(crate) mod client; pub(crate) use self::client::*; -pub(crate) mod jack_event; pub(crate) use self::jack_event::*; -pub(crate) mod ports; pub(crate) use self::ports::*; -pub(crate) use ::jack::{ +pub use ::jack::{ contrib::ClosureProcessHandler, NotificationHandler, Client, AsyncClient, ClientOptions, ClientStatus, ProcessScope, Control, CycleTimes, Frames, @@ -12,6 +9,20 @@ pub(crate) use ::jack::{ Transport, TransportState, MidiIter, MidiWriter, RawMidi, }; +pub mod activate; +pub(crate) use self::activate::*; +pub use self::activate::JackActivate; + +pub mod client; +pub(crate) use self::client::*; +pub use self::client::JackClient; + +pub mod jack_event; +pub(crate) use self::jack_event::*; + +pub mod ports; +pub(crate) use self::ports::*; + /// 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) => { @@ -24,6 +35,83 @@ pub(crate) use ::jack::{ }; } +/// Implement [Audio]: provide JACK callbacks. +#[macro_export] macro_rules! audio { + (|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?,$c:ident,$s:ident|$cb:expr) => { + impl $(<$($L),*$($T $(: $U)?),*>)? Audio for $Struct $(<$($L),*$($T),*>)? { + #[inline] fn process (&mut $self, $c: &Client, $s: &ProcessScope) -> Control { $cb } + } + } +} + +/// Trait for thing that has a JACK process callback. +pub trait Audio: Send + Sync { + fn process (&mut self, _: &Client, _: &ProcessScope) -> Control { + Control::Continue + } + fn callback ( + state: &Arc>, client: &Client, scope: &ProcessScope + ) -> Control where Self: Sized { + if let Ok(mut state) = state.write() { + state.process(client, scope) + } else { + Control::Quit + } + } +} + + +/// Trait for things that wrap a JACK client. +pub trait AudioEngine { + + fn transport (&self) -> Transport { + self.client().transport() + } + + fn port_by_name (&self, name: &str) -> Option> { + self.client().port_by_name(name) + } + + fn register_port (&self, name: &str, spec: PS) -> Usually> { + Ok(self.client().register_port(name, spec)?) + } + + fn client (&self) -> &Client; + + fn activate ( + self, + process: impl FnMut(&Arc>, &Client, &ProcessScope) -> Control + Send + 'static + ) -> Usually>> where Self: Send + Sync + 'static; + + fn thread_init (&self, _: &Client) {} + + unsafe fn shutdown (&mut self, _status: ClientStatus, _reason: &str) {} + + fn freewheel (&mut self, _: &Client, _enabled: bool) {} + + fn client_registration (&mut self, _: &Client, _name: &str, _reg: bool) {} + + fn port_registration (&mut self, _: &Client, _id: PortId, _reg: bool) {} + + fn ports_connected (&mut self, _: &Client, _a: PortId, _b: PortId, _are: bool) {} + + fn sample_rate (&mut self, _: &Client, _frames: Frames) -> Control { + Control::Continue + } + + fn port_rename (&mut self, _: &Client, _id: PortId, _old: &str, _new: &str) -> Control { + Control::Continue + } + + fn graph_reorder (&mut self, _: &Client) -> Control { + Control::Continue + } + + fn xrun (&mut self, _: &Client) -> Control { + Control::Continue + } +} + //////////////////////////////////////////////////////////////////////////////////// ///// A [AudioComponent] bound to a JACK client and a set of ports. diff --git a/crates/tek/src/jack/audio.rs b/crates/tek/src/jack/audio.rs deleted file mode 100644 index b78c7e65..00000000 --- a/crates/tek/src/jack/audio.rs +++ /dev/null @@ -1,78 +0,0 @@ -use crate::*; - -/// Implement [Audio]: provide JACK callbacks. -#[macro_export] macro_rules! audio { - (|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?,$c:ident,$s:ident|$cb:expr) => { - impl $(<$($L),*$($T $(: $U)?),*>)? Audio for $Struct $(<$($L),*$($T),*>)? { - #[inline] fn process (&mut $self, $c: &Client, $s: &ProcessScope) -> Control { $cb } - } - } -} - -/// Trait for thing that has a JACK process callback. -pub trait Audio: Send + Sync { - fn process (&mut self, _: &Client, _: &ProcessScope) -> Control { - Control::Continue - } - fn callback ( - state: &Arc>, client: &Client, scope: &ProcessScope - ) -> Control where Self: Sized { - if let Ok(mut state) = state.write() { - state.process(client, scope) - } else { - Control::Quit - } - } -} - - -/// Trait for things that wrap a JACK client. -pub trait AudioEngine { - - fn transport (&self) -> Transport { - self.client().transport() - } - - fn port_by_name (&self, name: &str) -> Option> { - self.client().port_by_name(name) - } - - fn register_port (&self, name: &str, spec: PS) -> Usually> { - Ok(self.client().register_port(name, spec)?) - } - - fn client (&self) -> &Client; - - fn activate ( - self, - process: impl FnMut(&Arc>, &Client, &ProcessScope) -> Control + Send + 'static - ) -> Usually>> where Self: Send + Sync + 'static; - - fn thread_init (&self, _: &Client) {} - - unsafe fn shutdown (&mut self, _status: ClientStatus, _reason: &str) {} - - fn freewheel (&mut self, _: &Client, _enabled: bool) {} - - fn client_registration (&mut self, _: &Client, _name: &str, _reg: bool) {} - - fn port_registration (&mut self, _: &Client, _id: PortId, _reg: bool) {} - - fn ports_connected (&mut self, _: &Client, _a: PortId, _b: PortId, _are: bool) {} - - fn sample_rate (&mut self, _: &Client, _frames: Frames) -> Control { - Control::Continue - } - - fn port_rename (&mut self, _: &Client, _id: PortId, _old: &str, _new: &str) -> Control { - Control::Continue - } - - fn graph_reorder (&mut self, _: &Client) -> Control { - Control::Continue - } - - fn xrun (&mut self, _: &Client) -> Control { - Control::Continue - } -} diff --git a/crates/tek/src/lib.rs b/crates/tek/src/lib.rs index 0ab08cec..d25ba66c 100644 --- a/crates/tek/src/lib.rs +++ b/crates/tek/src/lib.rs @@ -1,16 +1,22 @@ -const FOO: () = (); +#![allow(unused)] +#![allow(clippy::unit_arg)] pub mod core; pub use self::core::*; pub mod time; pub(crate) use self::time::*; pub mod space; pub(crate) use self::space::*; -pub mod tui; pub(crate) use self::tui::*; -pub mod edn; -pub mod jack; pub(crate) use self::jack::*; -pub mod midi; pub(crate) use self::midi::*; -pub mod audio; pub(crate) use self::audio::*; -//pub mod plugin; pub(crate) use self::plugin::*; -pub(crate) use clap::{self, Parser}; +pub mod tui; pub(crate) use self::tui::*; +pub use tui::{Tui, TransportTui, SequencerTui, SamplerTui, GrooveboxTui, ArrangerTui}; + +pub mod jack; pub(crate) use self::jack::*; +pub use jack::JackClient; + +pub mod midi; pub(crate) use self::midi::*; + +pub mod audio; pub(crate) use self::audio::*; +pub use audio::{Sampler, Sample, Voice}; + +//pub mod plugin; pub(crate) use self::plugin::*; pub use ::better_panic; pub(crate) use better_panic::{Settings, Verbosity}; @@ -44,13 +50,12 @@ pub(crate) use ratatui::{ backend::{Backend, CrosstermBackend, ClearType} }; -pub use ::midly; +pub use ::midly::{self, num::u7}; pub(crate) use ::midly::{ Smf, MidiMessage, TrackEventKind, live::LiveEvent, - num::u7 }; pub use ::palette; diff --git a/crates/tek/src/plugin/lv2.rs b/crates/tek/src/plugin/lv2.rs index b47c159b..206a79c3 100644 --- a/crates/tek/src/plugin/lv2.rs +++ b/crates/tek/src/plugin/lv2.rs @@ -40,22 +40,3 @@ impl LV2Plugin { }) } } - -impl LV2Plugin { - pub fn from_edn <'e> (jack: &Arc>, args: &[Edn<'e>]) -> Usually { - let mut name = String::new(); - let mut path = String::new(); - edn!(edn in args { - Edn::Map(map) => { - if let Some(Edn::Str(n)) = map.get(&Edn::Key(":name")) { - name = String::from(*n); - } - if let Some(Edn::Str(p)) = map.get(&Edn::Key(":path")) { - path = String::from(*p); - } - }, - _ => panic!("unexpected in lv2 '{name}'"), - }); - Plugin::new_lv2(jack, &name, &path) - } -} diff --git a/crates/tek/src/tui.rs b/crates/tek/src/tui.rs index 5990d455..35c167ad 100644 --- a/crates/tek/src/tui.rs +++ b/crates/tek/src/tui.rs @@ -15,10 +15,19 @@ mod tui_border; pub(crate) use self::tui_border::*; //////////////////////////////////////////////////////// mod app_transport; #[allow(unused)] pub(crate) use self::app_transport::*; +pub use self::app_transport::TransportTui; + mod app_sequencer; #[allow(unused)] pub(crate) use self::app_sequencer::*; +pub use self::app_sequencer::SequencerTui; + mod app_sampler; #[allow(unused)] pub(crate) use self::app_sampler::*; +pub use self::app_sampler::SamplerTui; + mod app_groovebox; #[allow(unused)] pub(crate) use self::app_groovebox::*; +pub use self::app_groovebox::GrooveboxTui; + mod app_arranger; #[allow(unused)] pub(crate) use self::app_arranger::*; +pub use self::app_arranger::ArrangerTui; /////////////////////////////////////////////////////// diff --git a/crates/tek/src/tui/app_sampler.rs b/crates/tek/src/tui/app_sampler.rs index 75d75a8f..c1fb49b6 100644 --- a/crates/tek/src/tui/app_sampler.rs +++ b/crates/tek/src/tui/app_sampler.rs @@ -13,7 +13,6 @@ use symphonia::{ }, default::get_codecs, }; - pub struct SamplerTui { pub state: Sampler, pub cursor: (usize, usize),