mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
reenable mixer crate
This commit is contained in:
parent
792dab9714
commit
2f189c6d7e
7 changed files with 51 additions and 79 deletions
10
Justfile
10
Justfile
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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(())
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue