From 3d669d7d24980103ded9bb87c15aa31a7d4bfb3a Mon Sep 17 00:00:00 2001 From: unspeaker Date: Wed, 18 Dec 2024 16:23:48 +0100 Subject: [PATCH] readd todos --- crates/tek/src/api.rs | 3 - crates/tek/src/api/_todo_api_plugin_kind.rs | 21 -- crates/tek/src/audio.rs | 3 + crates/tek/src/audio/audio_in.rs | 0 crates/tek/src/audio/audio_out.rs | 0 .../_todo_api_channel.rs => audio/channel.rs} | 0 .../_todo_api_mixer.rs => audio/mixer.rs} | 0 crates/tek/src/{api => audio}/sampler.rs | 0 crates/tek/src/jack.rs | 12 +- crates/tek/src/lib.rs | 15 +- crates/tek/src/midi.rs | 262 +++++++++++++++++- .../{api/phrase.rs => midi/midi_phrase.rs} | 0 crates/tek/src/midi/midi_player.rs | 255 ----------------- .../src/{api/scene.rs => midi/midi_scene.rs} | 0 .../src/{api/track.rs => midi/midi_track.rs} | 0 .../{api/_todo_api_plugin.rs => plugin.rs} | 23 +- .../_todo_api_plugin_lv2.rs => plugin/lv2.rs} | 0 crates/tek/src/tui/app_arranger.rs | 2 - crates/tek/src/tui/phrase_list.rs | 2 +- 19 files changed, 299 insertions(+), 299 deletions(-) delete mode 100644 crates/tek/src/api/_todo_api_plugin_kind.rs create mode 100644 crates/tek/src/audio.rs create mode 100644 crates/tek/src/audio/audio_in.rs create mode 100644 crates/tek/src/audio/audio_out.rs rename crates/tek/src/{api/_todo_api_channel.rs => audio/channel.rs} (100%) rename crates/tek/src/{api/_todo_api_mixer.rs => audio/mixer.rs} (100%) rename crates/tek/src/{api => audio}/sampler.rs (100%) rename crates/tek/src/{api/phrase.rs => midi/midi_phrase.rs} (100%) delete mode 100644 crates/tek/src/midi/midi_player.rs rename crates/tek/src/{api/scene.rs => midi/midi_scene.rs} (100%) rename crates/tek/src/{api/track.rs => midi/midi_track.rs} (100%) rename crates/tek/src/{api/_todo_api_plugin.rs => plugin.rs} (86%) rename crates/tek/src/{api/_todo_api_plugin_lv2.rs => plugin/lv2.rs} (100%) diff --git a/crates/tek/src/api.rs b/crates/tek/src/api.rs index cc13d65c..a4b2c74b 100644 --- a/crates/tek/src/api.rs +++ b/crates/tek/src/api.rs @@ -1,4 +1 @@ -mod phrase; pub(crate) use phrase::*; -mod scene; pub(crate) use scene::*; -mod track; pub(crate) use track::*; mod sampler; pub(crate) use sampler::*; diff --git a/crates/tek/src/api/_todo_api_plugin_kind.rs b/crates/tek/src/api/_todo_api_plugin_kind.rs deleted file mode 100644 index 0f35ca3a..00000000 --- a/crates/tek/src/api/_todo_api_plugin_kind.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::*; - -/// Supported plugin formats. -#[derive(Default)] -pub enum PluginKind { - #[default] None, - LV2(LV2Plugin), - VST2 { instance: ::vst::host::PluginInstance }, - VST3, -} - -impl Debug for PluginKind { - fn fmt (&self, f: &mut Formatter<'_>) -> std::result::Result<(), Error> { - write!(f, "{}", match self { - Self::None => "(none)", - Self::LV2(_) => "LV2", - Self::VST2{..} => "VST2", - Self::VST3 => "VST3", - }) - } -} diff --git a/crates/tek/src/audio.rs b/crates/tek/src/audio.rs new file mode 100644 index 00000000..46aa0557 --- /dev/null +++ b/crates/tek/src/audio.rs @@ -0,0 +1,3 @@ +pub(crate) mod audio_in; pub(crate) use audio_in::*; +pub(crate) mod audio_out; pub(crate) use audio_out::*; +pub(crate) mod sampler; pub(crate) use sampler::*; diff --git a/crates/tek/src/audio/audio_in.rs b/crates/tek/src/audio/audio_in.rs new file mode 100644 index 00000000..e69de29b diff --git a/crates/tek/src/audio/audio_out.rs b/crates/tek/src/audio/audio_out.rs new file mode 100644 index 00000000..e69de29b diff --git a/crates/tek/src/api/_todo_api_channel.rs b/crates/tek/src/audio/channel.rs similarity index 100% rename from crates/tek/src/api/_todo_api_channel.rs rename to crates/tek/src/audio/channel.rs diff --git a/crates/tek/src/api/_todo_api_mixer.rs b/crates/tek/src/audio/mixer.rs similarity index 100% rename from crates/tek/src/api/_todo_api_mixer.rs rename to crates/tek/src/audio/mixer.rs diff --git a/crates/tek/src/api/sampler.rs b/crates/tek/src/audio/sampler.rs similarity index 100% rename from crates/tek/src/api/sampler.rs rename to crates/tek/src/audio/sampler.rs diff --git a/crates/tek/src/jack.rs b/crates/tek/src/jack.rs index ac04ed72..aabea352 100644 --- a/crates/tek/src/jack.rs +++ b/crates/tek/src/jack.rs @@ -1,11 +1,11 @@ use crate::*; -pub(crate) mod activate; pub(crate) use activate::*; -pub(crate) mod audio; pub(crate) use audio::*; -pub(crate) mod client; pub(crate) use client::*; -pub(crate) mod from_jack; pub(crate) use from_jack::*; -pub(crate) mod jack_event; pub(crate) use jack_event::*; -pub(crate) mod ports; pub(crate) use ports::*; +pub(crate) mod activate; 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 from_jack; pub(crate) use self::from_jack::*; +pub(crate) mod jack_event; pub(crate) use self::jack_event::*; +pub(crate) mod ports; pub(crate) use self::ports::*; //////////////////////////////////////////////////////////////////////////////////// diff --git a/crates/tek/src/lib.rs b/crates/tek/src/lib.rs index 73455b36..782eac2e 100644 --- a/crates/tek/src/lib.rs +++ b/crates/tek/src/lib.rs @@ -1,11 +1,12 @@ pub mod core; pub(crate) use self::core::*; -pub mod api; pub(crate) use self::api::*; -pub mod tui; pub(crate) use self::tui::*; -pub mod edn; pub(crate) use self::edn::*; -pub mod jack; pub(crate) use self::jack::*; -pub mod midi; pub(crate) use self::midi::*; -pub mod time; pub(crate) use self::time::*; -pub mod space; pub(crate) use self::space::*; +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(crate) use self::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::*; /// Standard result type. pub type Usually = Result>; diff --git a/crates/tek/src/midi.rs b/crates/tek/src/midi.rs index db92d43f..240d102f 100644 --- a/crates/tek/src/midi.rs +++ b/crates/tek/src/midi.rs @@ -1,12 +1,14 @@ use crate::*; -pub(crate) mod midi_note; pub(crate) use midi_note::*; pub(crate) mod midi_in; pub(crate) use midi_in::*; -pub(crate) mod midi_out; pub(crate) use midi_out::*; -pub(crate) mod midi_player; pub(crate) use midi_player::*; pub(crate) mod midi_launch; pub(crate) use midi_launch::*; +pub(crate) mod midi_note; pub(crate) use midi_note::*; +pub(crate) mod midi_out; pub(crate) use midi_out::*; +pub(crate) mod midi_phrase; pub(crate) use midi_phrase::*; pub(crate) mod midi_play; pub(crate) use midi_play::*; pub(crate) mod midi_rec; pub(crate) use midi_rec::*; +pub(crate) mod midi_scene; pub(crate) use midi_scene::*; +pub(crate) mod midi_track; pub(crate) use midi_track::*; /// Add "all notes off" to the start of a buffer. pub fn all_notes_off (output: &mut [Vec>]) { @@ -55,3 +57,257 @@ pub const MIDI_NOTE_NAMES: [&'static str;128] = [ "C9", "C#9", "D9", "D#9", "E9", "F9", "F#9", "G9", "G#9", "A9", "A#9", "B9", "C10", "C#10", "D10", "D#10", "E10", "F10", "F#10", "G10", ]; + +pub trait MidiPlayerApi: MidiRecordApi + MidiPlaybackApi + Send + Sync {} + +impl MidiPlayerApi for PhrasePlayerModel {} + +pub trait HasPlayer { + fn player (&self) -> &impl MidiPlayerApi; + fn player_mut (&mut self) -> &mut impl MidiPlayerApi; +} + +#[macro_export] macro_rules! has_player { + (|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => { + impl $(<$($L),*$($T $(: $U)?),*>)? HasPlayer for $Struct $(<$($L),*$($T),*>)? { + fn player (&$self) -> &impl MidiPlayerApi { &$cb } + fn player_mut (&mut $self) -> &mut impl MidiPlayerApi { &mut$cb } + } + } +} + +/// Contains state for playing a phrase +pub struct PhrasePlayerModel { + /// State of clock and playhead + pub(crate) clock: ClockModel, + /// Start time and phrase being played + pub(crate) play_phrase: Option<(Moment, Option>>)>, + /// Start time and next phrase + pub(crate) next_phrase: Option<(Moment, Option>>)>, + /// Play input through output. + pub(crate) monitoring: bool, + /// Write input to sequence. + pub(crate) recording: bool, + /// Overdub input to sequence. + pub(crate) overdub: bool, + /// Send all notes off + pub(crate) reset: bool, // TODO?: after Some(nframes) + /// Record from MIDI ports to current sequence. + pub midi_ins: Vec>, + /// Play from current sequence to MIDI ports + pub midi_outs: Vec>, + /// Notes currently held at input + pub(crate) notes_in: Arc>, + /// Notes currently held at output + pub(crate) notes_out: Arc>, + /// MIDI output buffer + pub note_buf: Vec, +} + +impl std::fmt::Debug for PhrasePlayerModel { + fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { + f.debug_struct("PhrasePlayerModel") + .field("clock", &self.clock) + .field("play_phrase", &self.play_phrase) + .field("next_phrase", &self.next_phrase) + .finish() + } +} + +impl From<&ClockModel> for PhrasePlayerModel { + fn from (clock: &ClockModel) -> Self { + Self { + clock: clock.clone(), + midi_ins: vec![], + midi_outs: vec![], + note_buf: vec![0;8], + reset: true, + recording: false, + monitoring: false, + overdub: false, + play_phrase: None, + next_phrase: None, + notes_in: RwLock::new([false;128]).into(), + notes_out: RwLock::new([false;128]).into(), + } + } +} + +impl From<(&ClockModel, &Arc>)> for PhrasePlayerModel { + fn from ((clock, phrase): (&ClockModel, &Arc>)) -> Self { + let mut model = Self::from(clock); + model.play_phrase = Some((Moment::zero(&clock.timebase), Some(phrase.clone()))); + model + } +} + +has_clock!(|self:PhrasePlayerModel|&self.clock); + +impl HasMidiIns for PhrasePlayerModel { + fn midi_ins (&self) -> &Vec> { + &self.midi_ins + } + fn midi_ins_mut (&mut self) -> &mut Vec> { + &mut self.midi_ins + } +} + +impl HasMidiOuts for PhrasePlayerModel { + fn midi_outs (&self) -> &Vec> { + &self.midi_outs + } + fn midi_outs_mut (&mut self) -> &mut Vec> { + &mut self.midi_outs + } + fn midi_note (&mut self) -> &mut Vec { + &mut self.note_buf + } +} + +/// Hosts the JACK callback for a single MIDI player +pub struct PlayerAudio<'a, T: MidiPlayerApi>( + /// Player + pub &'a mut T, + /// Note buffer + pub &'a mut Vec, + /// Note chunk buffer + pub &'a mut Vec>>, +); + +/// JACK process callback for a sequencer's phrase player/recorder. +impl<'a, T: MidiPlayerApi> Audio for PlayerAudio<'a, T> { + fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control { + let model = &mut self.0; + let note_buf = &mut self.1; + let midi_buf = &mut self.2; + // Clear output buffer(s) + model.clear(scope, midi_buf, false); + // Write chunk of phrase to output, handle switchover + if model.play(scope, note_buf, midi_buf) { + model.switchover(scope, note_buf, midi_buf); + } + if model.has_midi_ins() { + if model.recording() || model.monitoring() { + // Record and/or monitor input + model.record(scope, midi_buf) + } else if model.has_midi_outs() && model.monitoring() { + // Monitor input to output + model.monitor(scope, midi_buf) + } + } + // Write to output port(s) + model.write(scope, midi_buf); + Control::Continue + } +} + +impl MidiRecordApi for PhrasePlayerModel { + fn recording (&self) -> bool { + self.recording + } + fn recording_mut (&mut self) -> &mut bool { + &mut self.recording + } + fn monitoring (&self) -> bool { + self.monitoring + } + fn monitoring_mut (&mut self) -> &mut bool { + &mut self.monitoring + } + fn overdub (&self) -> bool { + self.overdub + } + fn overdub_mut (&mut self) -> &mut bool { + &mut self.overdub + } + fn notes_in (&self) -> &Arc> { + &self.notes_in + } +} + +impl MidiPlaybackApi for PhrasePlayerModel { + fn notes_out (&self) -> &Arc> { + &self.notes_in + } +} + +impl HasPlayPhrase for PhrasePlayerModel { + fn reset (&self) -> bool { + self.reset + } + fn reset_mut (&mut self) -> &mut bool { + &mut self.reset + } + fn play_phrase (&self) -> &Option<(Moment, Option>>)> { + &self.play_phrase + } + fn play_phrase_mut (&mut self) -> &mut Option<(Moment, Option>>)> { + &mut self.play_phrase + } + fn next_phrase (&self) -> &Option<(Moment, Option>>)> { + &self.next_phrase + } + fn next_phrase_mut (&mut self) -> &mut Option<(Moment, Option>>)> { + &mut self.next_phrase + } +} + +//#[derive(Debug)] +//pub struct MIDIPlayer { + ///// Global timebase + //pub clock: Arc, + ///// Start time and phrase being played + //pub play_phrase: Option<(Moment, Option>>)>, + ///// Start time and next phrase + //pub next_phrase: Option<(Moment, Option>>)>, + ///// Play input through output. + //pub monitoring: bool, + ///// Write input to sequence. + //pub recording: bool, + ///// Overdub input to sequence. + //pub overdub: bool, + ///// Send all notes off + //pub reset: bool, // TODO?: after Some(nframes) + ///// Record from MIDI ports to current sequence. + //pub midi_inputs: Vec>, + ///// Play from current sequence to MIDI ports + //pub midi_outputs: Vec>, + ///// MIDI output buffer + //pub midi_note: Vec, + ///// MIDI output buffer + //pub midi_chunk: Vec>>, + ///// Notes currently held at input + //pub notes_in: Arc>, + ///// Notes currently held at output + //pub notes_out: Arc>, +//} + +///// Methods used primarily by the process callback +//impl MIDIPlayer { + //pub fn new ( + //jack: &Arc>, + //clock: &Arc, + //name: &str + //) -> Usually { + //let jack = jack.read().unwrap(); + //Ok(Self { + //clock: clock.clone(), + //phrase: None, + //next_phrase: None, + //notes_in: Arc::new(RwLock::new([false;128])), + //notes_out: Arc::new(RwLock::new([false;128])), + //monitoring: false, + //recording: false, + //overdub: true, + //reset: true, + //midi_note: Vec::with_capacity(8), + //midi_chunk: vec![Vec::with_capacity(16);16384], + //midi_outputs: vec![ + //jack.client().register_port(format!("{name}_out0").as_str(), MidiOut::default())? + //], + //midi_inputs: vec![ + //jack.client().register_port(format!("{name}_in0").as_str(), MidiIn::default())? + //], + //}) + //} +//} diff --git a/crates/tek/src/api/phrase.rs b/crates/tek/src/midi/midi_phrase.rs similarity index 100% rename from crates/tek/src/api/phrase.rs rename to crates/tek/src/midi/midi_phrase.rs diff --git a/crates/tek/src/midi/midi_player.rs b/crates/tek/src/midi/midi_player.rs deleted file mode 100644 index e0eedd3c..00000000 --- a/crates/tek/src/midi/midi_player.rs +++ /dev/null @@ -1,255 +0,0 @@ -use crate::*; - -pub trait MidiPlayerApi: MidiRecordApi + MidiPlaybackApi + Send + Sync {} - -impl MidiPlayerApi for PhrasePlayerModel {} - -pub trait HasPlayer { - fn player (&self) -> &impl MidiPlayerApi; - fn player_mut (&mut self) -> &mut impl MidiPlayerApi; -} - -#[macro_export] macro_rules! has_player { - (|$self:ident:$Struct:ident$(<$($L:lifetime),*$($T:ident$(:$U:path)?),*>)?|$cb:expr) => { - impl $(<$($L),*$($T $(: $U)?),*>)? HasPlayer for $Struct $(<$($L),*$($T),*>)? { - fn player (&$self) -> &impl MidiPlayerApi { &$cb } - fn player_mut (&mut $self) -> &mut impl MidiPlayerApi { &mut$cb } - } - } -} - -/// Contains state for playing a phrase -pub struct PhrasePlayerModel { - /// State of clock and playhead - pub(crate) clock: ClockModel, - /// Start time and phrase being played - pub(crate) play_phrase: Option<(Moment, Option>>)>, - /// Start time and next phrase - pub(crate) next_phrase: Option<(Moment, Option>>)>, - /// Play input through output. - pub(crate) monitoring: bool, - /// Write input to sequence. - pub(crate) recording: bool, - /// Overdub input to sequence. - pub(crate) overdub: bool, - /// Send all notes off - pub(crate) reset: bool, // TODO?: after Some(nframes) - /// Record from MIDI ports to current sequence. - pub midi_ins: Vec>, - /// Play from current sequence to MIDI ports - pub midi_outs: Vec>, - /// Notes currently held at input - pub(crate) notes_in: Arc>, - /// Notes currently held at output - pub(crate) notes_out: Arc>, - /// MIDI output buffer - pub note_buf: Vec, -} - -impl std::fmt::Debug for PhrasePlayerModel { - fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { - f.debug_struct("PhrasePlayerModel") - .field("clock", &self.clock) - .field("play_phrase", &self.play_phrase) - .field("next_phrase", &self.next_phrase) - .finish() - } -} - -impl From<&ClockModel> for PhrasePlayerModel { - fn from (clock: &ClockModel) -> Self { - Self { - clock: clock.clone(), - midi_ins: vec![], - midi_outs: vec![], - note_buf: vec![0;8], - reset: true, - recording: false, - monitoring: false, - overdub: false, - play_phrase: None, - next_phrase: None, - notes_in: RwLock::new([false;128]).into(), - notes_out: RwLock::new([false;128]).into(), - } - } -} - -impl From<(&ClockModel, &Arc>)> for PhrasePlayerModel { - fn from ((clock, phrase): (&ClockModel, &Arc>)) -> Self { - let mut model = Self::from(clock); - model.play_phrase = Some((Moment::zero(&clock.timebase), Some(phrase.clone()))); - model - } -} - -has_clock!(|self:PhrasePlayerModel|&self.clock); - -impl HasMidiIns for PhrasePlayerModel { - fn midi_ins (&self) -> &Vec> { - &self.midi_ins - } - fn midi_ins_mut (&mut self) -> &mut Vec> { - &mut self.midi_ins - } -} - -impl HasMidiOuts for PhrasePlayerModel { - fn midi_outs (&self) -> &Vec> { - &self.midi_outs - } - fn midi_outs_mut (&mut self) -> &mut Vec> { - &mut self.midi_outs - } - fn midi_note (&mut self) -> &mut Vec { - &mut self.note_buf - } -} - -/// Hosts the JACK callback for a single MIDI player -pub struct PlayerAudio<'a, T: MidiPlayerApi>( - /// Player - pub &'a mut T, - /// Note buffer - pub &'a mut Vec, - /// Note chunk buffer - pub &'a mut Vec>>, -); - -/// JACK process callback for a sequencer's phrase player/recorder. -impl<'a, T: MidiPlayerApi> Audio for PlayerAudio<'a, T> { - fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control { - let model = &mut self.0; - let note_buf = &mut self.1; - let midi_buf = &mut self.2; - // Clear output buffer(s) - model.clear(scope, midi_buf, false); - // Write chunk of phrase to output, handle switchover - if model.play(scope, note_buf, midi_buf) { - model.switchover(scope, note_buf, midi_buf); - } - if model.has_midi_ins() { - if model.recording() || model.monitoring() { - // Record and/or monitor input - model.record(scope, midi_buf) - } else if model.has_midi_outs() && model.monitoring() { - // Monitor input to output - model.monitor(scope, midi_buf) - } - } - // Write to output port(s) - model.write(scope, midi_buf); - Control::Continue - } -} - -impl MidiRecordApi for PhrasePlayerModel { - fn recording (&self) -> bool { - self.recording - } - fn recording_mut (&mut self) -> &mut bool { - &mut self.recording - } - fn monitoring (&self) -> bool { - self.monitoring - } - fn monitoring_mut (&mut self) -> &mut bool { - &mut self.monitoring - } - fn overdub (&self) -> bool { - self.overdub - } - fn overdub_mut (&mut self) -> &mut bool { - &mut self.overdub - } - fn notes_in (&self) -> &Arc> { - &self.notes_in - } -} - -impl MidiPlaybackApi for PhrasePlayerModel { - fn notes_out (&self) -> &Arc> { - &self.notes_in - } -} - -impl HasPlayPhrase for PhrasePlayerModel { - fn reset (&self) -> bool { - self.reset - } - fn reset_mut (&mut self) -> &mut bool { - &mut self.reset - } - fn play_phrase (&self) -> &Option<(Moment, Option>>)> { - &self.play_phrase - } - fn play_phrase_mut (&mut self) -> &mut Option<(Moment, Option>>)> { - &mut self.play_phrase - } - fn next_phrase (&self) -> &Option<(Moment, Option>>)> { - &self.next_phrase - } - fn next_phrase_mut (&mut self) -> &mut Option<(Moment, Option>>)> { - &mut self.next_phrase - } -} - -//#[derive(Debug)] -//pub struct MIDIPlayer { - ///// Global timebase - //pub clock: Arc, - ///// Start time and phrase being played - //pub play_phrase: Option<(Moment, Option>>)>, - ///// Start time and next phrase - //pub next_phrase: Option<(Moment, Option>>)>, - ///// Play input through output. - //pub monitoring: bool, - ///// Write input to sequence. - //pub recording: bool, - ///// Overdub input to sequence. - //pub overdub: bool, - ///// Send all notes off - //pub reset: bool, // TODO?: after Some(nframes) - ///// Record from MIDI ports to current sequence. - //pub midi_inputs: Vec>, - ///// Play from current sequence to MIDI ports - //pub midi_outputs: Vec>, - ///// MIDI output buffer - //pub midi_note: Vec, - ///// MIDI output buffer - //pub midi_chunk: Vec>>, - ///// Notes currently held at input - //pub notes_in: Arc>, - ///// Notes currently held at output - //pub notes_out: Arc>, -//} - -///// Methods used primarily by the process callback -//impl MIDIPlayer { - //pub fn new ( - //jack: &Arc>, - //clock: &Arc, - //name: &str - //) -> Usually { - //let jack = jack.read().unwrap(); - //Ok(Self { - //clock: clock.clone(), - //phrase: None, - //next_phrase: None, - //notes_in: Arc::new(RwLock::new([false;128])), - //notes_out: Arc::new(RwLock::new([false;128])), - //monitoring: false, - //recording: false, - //overdub: true, - //reset: true, - //midi_note: Vec::with_capacity(8), - //midi_chunk: vec![Vec::with_capacity(16);16384], - //midi_outputs: vec![ - //jack.client().register_port(format!("{name}_out0").as_str(), MidiOut::default())? - //], - //midi_inputs: vec![ - //jack.client().register_port(format!("{name}_in0").as_str(), MidiIn::default())? - //], - //}) - //} -//} diff --git a/crates/tek/src/api/scene.rs b/crates/tek/src/midi/midi_scene.rs similarity index 100% rename from crates/tek/src/api/scene.rs rename to crates/tek/src/midi/midi_scene.rs diff --git a/crates/tek/src/api/track.rs b/crates/tek/src/midi/midi_track.rs similarity index 100% rename from crates/tek/src/api/track.rs rename to crates/tek/src/midi/midi_track.rs diff --git a/crates/tek/src/api/_todo_api_plugin.rs b/crates/tek/src/plugin.rs similarity index 86% rename from crates/tek/src/api/_todo_api_plugin.rs rename to crates/tek/src/plugin.rs index 161c59d7..086f17bf 100644 --- a/crates/tek/src/api/_todo_api_plugin.rs +++ b/crates/tek/src/plugin.rs @@ -1,3 +1,4 @@ +pub(crate) mod lv2; pub(crate) use lv2::*; use crate::*; /// A plugin device. @@ -15,6 +16,26 @@ pub struct Plugin { pub audio_ins: Vec>, pub audio_outs: Vec>, } + +/// Supported plugin formats. +#[derive(Default)] +pub enum PluginKind { + #[default] None, + LV2(LV2Plugin), + VST2 { instance: ::vst::host::PluginInstance }, + VST3, +} + +impl Debug for PluginKind { + fn fmt (&self, f: &mut Formatter<'_>) -> std::result::Result<(), Error> { + write!(f, "{}", match self { + Self::None => "(none)", + Self::LV2(_) => "LV2", + Self::VST2{..} => "VST2", + Self::VST3 => "VST3", + }) + } +} impl Plugin { pub fn new_lv2 ( jack: &Arc>, @@ -62,7 +83,7 @@ impl From<&Arc>> for PluginAudio { } } -audio!(|self: PluginAudio, _, _|{ +audio!(|self: PluginAudio, client_, _scope|{ let state = &mut*self.0.write().unwrap(); match state.plugin.as_mut() { Some(PluginKind::LV2(LV2Plugin { diff --git a/crates/tek/src/api/_todo_api_plugin_lv2.rs b/crates/tek/src/plugin/lv2.rs similarity index 100% rename from crates/tek/src/api/_todo_api_plugin_lv2.rs rename to crates/tek/src/plugin/lv2.rs diff --git a/crates/tek/src/tui/app_arranger.rs b/crates/tek/src/tui/app_arranger.rs index e22156fa..7c8920ce 100644 --- a/crates/tek/src/tui/app_arranger.rs +++ b/crates/tek/src/tui/app_arranger.rs @@ -1,6 +1,4 @@ use crate::*; -use crate::api::ArrangerTrackCommand; -use crate::api::ArrangerSceneCommand; /// Root view for standalone `tek_arranger` pub struct ArrangerTui { pub jack: Arc>, diff --git a/crates/tek/src/tui/phrase_list.rs b/crates/tek/src/tui/phrase_list.rs index a7e38ad2..6de320af 100644 --- a/crates/tek/src/tui/phrase_list.rs +++ b/crates/tek/src/tui/phrase_list.rs @@ -1,9 +1,9 @@ use super::*; use crate::{ + PhrasePoolCommand as Pool, tui::phrase_rename::PhraseRenameCommand as Rename, tui::phrase_length::PhraseLengthCommand as Length, tui::file_browser::FileBrowserCommand as Browse, - api::PhrasePoolCommand as Pool, }; use Ordering::Relaxed;