wip: refactor: cli, snd, tui

This commit is contained in:
🪞👃🪞 2024-11-09 21:27:04 +01:00
parent 70fc3c97d1
commit 84aacfea82
58 changed files with 416 additions and 191 deletions

View file

@ -0,0 +1,55 @@
include!("lib.rs");
use tek_core::clap::{self, Parser};
pub fn main () -> Usually<()> { ArrangerCli::parse().run() }
/// Parses CLI arguments to the `tek_arranger` invocation.
#[derive(Debug, Parser)]
#[command(version, about, long_about = None)]
pub struct ArrangerCli {
/// Name of JACK client
#[arg(short, long)] name: Option<String>,
/// Whether to include a transport toolbar (default: true)
#[arg(short, long, default_value_t = true)] transport: bool,
/// Number of tracks
#[arg(short = 'x', long, default_value_t = 8)] tracks: usize,
/// Number of scenes
#[arg(short, long, default_value_t = 8)] scenes: usize,
}
impl ArrangerCli {
/// Run the arranger TUI from CLI arguments.
fn run (&self) -> Usually<()> {
Tui::run(JackClient::new("tek_arranger")?.activate_with(|jack|{
let transport = TransportToolbar::new(jack, None);
let phrases = Arc::new(RwLock::new(PhrasePool::new()));
let mut arrangement = Arrangement::new(&jack, &transport.clock, "", &phrases);
let transport = Arc::new(RwLock::new(transport));
if let Some(name) = self.name.as_ref() {
*arrangement.name.write().unwrap() = name.clone();
}
let track_color_1 = ItemColor::random();
let track_color_2 = ItemColor::random();
for i in 0..self.tracks {
let _track = arrangement.track_add(
None,
Some(track_color_1.mix(track_color_2, i as f32 / self.tracks as f32))
)?;
}
let scene_color_1 = ItemColor::random();
let scene_color_2 = ItemColor::random();
for i in 0..self.scenes {
let _scene = arrangement.scene_add(
None,
Some(scene_color_1.mix(scene_color_2, i as f32 / self.scenes as f32))
)?;
}
Ok(Arranger::new(
jack,
self.transport.then_some(transport),
arrangement,
phrases,
))
})?)?;
Ok(())
}
}

View file

@ -0,0 +1,22 @@
//! Multi-track mixer
include!("lib.rs");
use tek_core::clap::{self, Parser};
pub fn main () -> Usually<()> { MixerCli::parse().run() }
#[derive(Debug, Parser)] #[command(version, about, long_about = None)] pub struct MixerCli {
/// Name of JACK client
#[arg(short, long)] name: Option<String>,
/// Number of tracks
#[arg(short, long)] channels: Option<usize>,
}
impl MixerCli {
fn run (&self) -> Usually<()> {
Tui::run(JackClient::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)?;
}
Ok(mixer)
})?)?;
Ok(())
}
}

View file

@ -0,0 +1,23 @@
//! Plugin host
include!("lib.rs");
use tek_core::clap::{self, Parser};
pub fn main () -> Usually<()> { PluginCli::parse().run() }
#[derive(Debug, Parser)] #[command(version, about, long_about = None)] pub struct PluginCli {
/// Name of JACK client
#[arg(short, long)] name: Option<String>,
/// Path to plugin
#[arg(short, long)] path: Option<String>,
}
impl PluginCli {
fn run (&self) -> Usually<()> {
Tui::run(JackClient::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"),
self.path.as_ref().expect("pass --path /to/lv2/plugin.so")
)?;
Ok(plugin)
})?)?;
Ok(())
}
}

View file

@ -0,0 +1,23 @@
//! Sample player
include!("lib.rs");
use tek_core::clap::{self, Parser};
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<String>,
/// Path to plugin
#[arg(short, long)] path: Option<String>,
}
impl SamplerCli {
fn run (&self) -> Usually<()> {
Tui::run(JackClient::new("tek_sampler")?.activate_with(|jack|{
let mut plugin = Sampler::new(
jack,
self.name.as_ref().map(|x|x.as_str()).unwrap_or("mixer"),
None,
)?;
Ok(plugin)
})?)?;
Ok(())
}
}

View file

@ -0,0 +1,48 @@
//! Phrase editor.
include!("lib.rs");
use tek_core::clap::{self, Parser};
pub fn main () -> Usually<()> { SequencerCli::parse().run() }
#[derive(Debug, Parser)]
#[command(version, about, long_about = None)]
pub struct SequencerCli {
/// Name of JACK client
#[arg(short, long)] name: Option<String>,
/// Pulses per quarter note (sequencer resolution; default: 96)
#[arg(short, long)] ppq: Option<usize>,
/// Default phrase duration (in pulses; default: 4 * PPQ = 1 bar)
#[arg(short, long)] length: Option<usize>,
/// Whether to include a transport toolbar (default: true)
#[arg(short, long, default_value_t = true)] transport: bool
}
impl SequencerCli {
fn run (&self) -> Usually<()> {
Tui::run(JackClient::new("tek_sequencer")?.activate_with(|jack|{
let transport = TransportToolbar::new(jack, None);
let sequencer = Sequencer {
jack: jack.clone(),
focus_cursor: (1, 1),
entered: false,
phrases: Arc::new(RwLock::new(PhrasePool::new())),
editor: PhraseEditor::new(),
clock: transport.clock.clone(),
player: PhrasePlayer::new(jack, &transport.clock, "tek_sequencer")?,
transport: self.transport.then_some(Arc::new(RwLock::new(transport))),
};
if let Some(_) = self.name.as_ref() {
// TODO: sequencer.name = Arc::new(RwLock::new(name.clone()));
}
if let Some(_) = self.ppq {
// TODO: sequencer.ppq = ppq;
}
if let Some(_) = self.length {
// TODO: if let Some(phrase) = sequencer.phrase.as_mut() {
//phrase.write().unwrap().length = length;
//}
}
Ok(sequencer)
})?)?;
Ok(())
}
}

View file

@ -0,0 +1,10 @@
include!("lib.rs");
/// Application entrypoint.
pub fn main () -> Usually<()> {
Tui::run(JackClient::new("tek_transport")?.activate_with(|jack|{
let mut transport = TransportToolbarView::new(jack, None);
transport.focused = true;
Ok(transport)
})?)?;
Ok(())
}

View file