reenable mixer crate

This commit is contained in:
🪞👃🪞 2024-11-03 18:15:58 +02:00
parent 792dab9714
commit 2f189c6d7e
7 changed files with 51 additions and 79 deletions

View file

@ -10,7 +10,17 @@ push:
fpush: fpush:
git push -fu codeberg main git push -fu codeberg main
git push -fu origin main git push -fu origin main
transport:
cargo run --bin tek_transport
arranger: arranger:
cargo run --bin tek_arranger cargo run --bin tek_arranger
sequencer: sequencer:
cargo run --bin tek_sequencer cargo run --bin tek_sequencer
mixer:
cargo run --bin tek_mixer
track:
cargo run --bin tek_track
sampler:
cargo run --bin tek_sampler
plugin:
cargo run --bin tek_plugin

View file

@ -19,16 +19,16 @@ path = "src/lib.rs"
[[bin]] [[bin]]
name = "tek_mixer" name = "tek_mixer"
path = "src/mixer_main.rs" path = "src/mixer_cli.rs"
[[bin]] [[bin]]
name = "tek_track" name = "tek_track"
path = "src/track_main.rs" path = "src/track_cli.rs"
[[bin]] [[bin]]
name = "tek_sampler" name = "tek_sampler"
path = "src/sampler_main.rs" path = "src/sampler_cli.rs"
[[bin]] [[bin]]
name = "tek_plugin" name = "tek_plugin"
path = "src/plugin_main.rs" path = "src/plugin_cli.rs"

View file

@ -1,31 +0,0 @@
//! Multi-track mixer
include!("lib.rs");
use tek_core::clap::{self, Parser};
#[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<E: Engine> Mixer<E> {
pub fn from_args () -> Usually<Self> {
let args = MixerCli::parse();
let mut mix = Self::new("")?;
if let Some(name) = args.name {
mix.name = name.clone();
}
if let Some(channels) = args.channels {
for channel in 0..channels {
mix.track_add(&format!("Track {}", channel + 1), 1)?;
}
}
Ok(mix)
}
}
pub fn main () -> Usually<()> {
Tui::run(Arc::new(RwLock::new(crate::Mixer::from_args()?)))?;
Ok(())
}

View file

@ -128,21 +128,16 @@ impl<'a> Content for VerticalArranger<'a, Tui> {
type Engine = Tui; type Engine = Tui;
fn content (&self) -> impl Widget<Engine = Tui> { fn content (&self) -> impl Widget<Engine = Tui> {
let Self(state, factor) = self; let Self(state, factor) = self;
let cols = state.track_widths(); let tracks = state.tracks.as_ref() as &[ArrangementTrack];
let rows = Scene::ppqs(state.scenes.as_slice(), *factor); let scenes = state.scenes.as_ref();
let tracks = state.tracks.as_ref() as &[ArrangementTrack]; let cols = state.track_widths();
let scenes = state.scenes.as_ref(); let rows = Scene::ppqs(scenes, *factor);
let bg = state.color; let bg = state.color;
let clip_bg = Color::Rgb(40, 50, 30); let clip_bg = Color::Rgb(40, 50, 30);
//let border_hi = Color::Rgb(100, 110, 40); let header_h = 3u16;//5u16;
//let border_lo = Color::Rgb(70, 80, 50); let scenes_w = 3 + Scene::longest_name(scenes) as u16; // x of 1st track
//let border_bg = Color::Rgb(40, 50, 30); let clock = &self.0.clock;
//let border_fg = if self.0.focused { border_hi } else { border_lo }; let arrangement = Layers::new(move |add|{
//let border = Lozenge(Style::default().bg(border_bg).fg(border_fg));
let track_title_h = 3u16;//5u16;
let scene_title_w = 3 + Scene::longest_name(scenes) as u16; // x of 1st track
let clock = &self.0.clock;
let arrangement = Layers::new(move |add|{
let rows: &[(usize, usize)] = rows.as_ref(); let rows: &[(usize, usize)] = rows.as_ref();
let cols: &[(usize, usize)] = cols.as_ref(); let cols: &[(usize, usize)] = cols.as_ref();
let any_size = |_|Ok(Some([0,0])); let any_size = |_|Ok(Some([0,0]));
@ -150,7 +145,7 @@ impl<'a> Content for VerticalArranger<'a, Tui> {
add(&CustomWidget::new(any_size, move|to: &mut TuiOutput|{ add(&CustomWidget::new(any_size, move|to: &mut TuiOutput|{
let style = Some(Style::default().fg(Color::Rgb(0, 0, 0))); let style = Some(Style::default().fg(Color::Rgb(0, 0, 0)));
Ok(for x in cols.iter().map(|col|col.1) { Ok(for x in cols.iter().map(|col|col.1) {
let x = scene_title_w + to.area().x() + x as u16; let x = scenes_w + to.area().x() + x as u16;
for y in to.area().y()..to.area().y2() { to.blit(&"", x, y, style); } for y in to.area().y()..to.area().y2() { to.blit(&"", x, y, style); }
}) })
}))?; }))?;
@ -176,11 +171,6 @@ impl<'a> Content for VerticalArranger<'a, Tui> {
let max_w = w.saturating_sub(1).min(name.len()).max(2); let max_w = w.saturating_sub(1).min(name.len()).max(2);
let name = format!("{}", &name[0..max_w]); let name = format!("{}", &name[0..max_w]);
let name = TuiStyle::bold(name, true); let name = TuiStyle::bold(name, true);
// name of active MIDI input
let input = format!("▎>{}", track.player.midi_inputs.get(0)
.map(|port|port.short_name())
.transpose()?
.unwrap_or("(none)".into()));
// beats elapsed // beats elapsed
let elapsed = if let Some((_, Some(phrase))) = player.phrase.as_ref() { let elapsed = if let Some((_, Some(phrase))) = player.phrase.as_ref() {
let length = phrase.read().unwrap().length; let length = phrase.read().unwrap().length;
@ -193,33 +183,36 @@ impl<'a> Content for VerticalArranger<'a, Tui> {
String::from("") String::from("")
}; };
// beats until switchover // beats until switchover
let until_next = player.next_phrase.as_ref() let until_next = player.next_phrase.as_ref().map(|(t, _)|{
.map(|(t, _)|{ let target = t.pulse.get();
let target = t.pulse.get(); let current = clock.current.pulse.get();
let current = clock.current.pulse.get(); if target > current {
if target > current { let remaining = target - current;
let remaining = target - current; format!("▎-{:>}", clock.timebase().format_beats_0_short(remaining))
format!("▎-{:>}", clock.timebase().format_beats_0_short(remaining)) } else {
} else { String::new()
String::new() }
} }).unwrap_or(String::from(""));
}) // name of active MIDI input
.unwrap_or(String::from("")); let input = format!("▎>{}", track.player.midi_inputs.get(0)
.map(|port|port.short_name())
.transpose()?
.unwrap_or("(none)".into()));
// name of active MIDI output // name of active MIDI output
let output = format!("▎<{}", track.player.midi_outputs.get(0) let output = format!("▎<{}", track.player.midi_outputs.get(0)
.map(|port|port.short_name()) .map(|port|port.short_name())
.transpose()? .transpose()?
.unwrap_or("(none)".into())); .unwrap_or("(none)".into()));
col!(name, /*input, output,*/ until_next, elapsed) col!(name, /*input, output,*/ until_next, elapsed)
.min_xy(w as u16, track_title_h) .min_xy(w as u16, header_h)
.bg(track.color.rgb) .bg(track.color.rgb)
.push_x(scene_title_w) .push_x(scenes_w)
}); });
// scene titles // scene titles
let scene_name = |scene, playing: bool, height|row!( let scene_name = |scene, playing: bool, height|row!(
if playing { "" } else { " " }, if playing { "" } else { " " },
TuiStyle::bold((scene as &Scene).name.read().unwrap().as_str(), true), TuiStyle::bold((scene as &Scene).name.read().unwrap().as_str(), true),
).fixed_xy(scene_title_w, height); ).fixed_xy(scenes_w, height);
// scene clips // scene clips
let scene_clip = |scene, track: usize, w: u16, h: u16|Layers::new(move |add|{ let scene_clip = |scene, track: usize, w: u16, h: u16|Layers::new(move |add|{
let mut bg = clip_bg; let mut bg = clip_bg;
@ -256,7 +249,7 @@ impl<'a> Content for VerticalArranger<'a, Tui> {
}) })
}).fixed_y(height) }).fixed_y(height)
} }
).fixed_y((self.0.size.h() as u16).saturating_sub(track_title_h)); ).fixed_y((self.0.size.h() as u16).saturating_sub(header_h));
// full grid with header and footer // full grid with header and footer
add(&col!(header, content))?; add(&col!(header, content))?;
// cursor // cursor
@ -265,16 +258,16 @@ impl<'a> Content for VerticalArranger<'a, Tui> {
let focused = state.focused; let focused = state.focused;
let selected = state.selected; let selected = state.selected;
let get_track_area = |t: usize| [ let get_track_area = |t: usize| [
scene_title_w + area.x() + cols[t].1 as u16, area.y(), scenes_w + area.x() + cols[t].1 as u16, area.y(),
cols[t].0 as u16, area.h(), cols[t].0 as u16, area.h(),
]; ];
let get_scene_area = |s: usize| [ let get_scene_area = |s: usize| [
area.x(), track_title_h + area.y() + (rows[s].1 / PPQ) as u16, area.x(), header_h + area.y() + (rows[s].1 / PPQ) as u16,
area.w(), (rows[s].0 / PPQ) as u16 area.w(), (rows[s].0 / PPQ) as u16
]; ];
let get_clip_area = |t: usize, s: usize| [ let get_clip_area = |t: usize, s: usize| [
scene_title_w + area.x() + cols[t].1 as u16, scenes_w + area.x() + cols[t].1 as u16,
track_title_h + area.y() + (rows[s].1/PPQ) as u16, header_h + area.y() + (rows[s].1/PPQ) as u16,
cols[t].0 as u16, cols[t].0 as u16,
(rows[s].0 / PPQ) as u16 (rows[s].0 / PPQ) as u16
]; ];
@ -302,9 +295,9 @@ impl<'a> Content for VerticalArranger<'a, Tui> {
} }
Ok(if focused { Ok(if focused {
to.render_in(if let Some(clip_area) = clip_area { clip_area } to.render_in(if let Some(clip_area) = clip_area { clip_area }
else if let Some(track_area) = track_area { track_area.clip_h(track_title_h) } else if let Some(track_area) = track_area { track_area.clip_h(header_h) }
else if let Some(scene_area) = scene_area { scene_area.clip_w(scene_title_w) } else if let Some(scene_area) = scene_area { scene_area.clip_w(scenes_w) }
else { area.clip_w(scene_title_w).clip_h(track_title_h) }, &CORNERS)? else { area.clip_w(scenes_w).clip_h(header_h) }, &CORNERS)?
}) })
})) }))
}).bg(bg.rgb);//.grow_y(1);//.border(border); }).bg(bg.rgb);//.grow_y(1);//.border(border);