mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
groovebox: reenable pool
This commit is contained in:
parent
872c2d94d6
commit
d7bbc2a412
6 changed files with 73 additions and 94 deletions
|
|
@ -10,7 +10,7 @@
|
||||||
(bsp/e :view-meters-input
|
(bsp/e :view-meters-input
|
||||||
(bsp/n :view-sample-info
|
(bsp/n :view-sample-info
|
||||||
(bsp/n (fixed/y 5 :view-sample-viewer)
|
(bsp/n (fixed/y 5 :view-sample-viewer)
|
||||||
(bsp/w (fixed/x :w-sidebar :view-pool)
|
(bsp/w :view-pool
|
||||||
(bsp/e :view-samples-keys
|
(bsp/e :view-samples-keys
|
||||||
(fill/y :view-editor)))))))))))
|
(fill/y :view-editor)))))))))))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,15 +171,15 @@ content!(TuiOut: |self: Message| match self { Self::FailedToAddDevice => "Failed
|
||||||
|
|
||||||
#[tengri_proc::expose]
|
#[tengri_proc::expose]
|
||||||
impl App {
|
impl App {
|
||||||
fn _todo_u16_stub (&self) -> u16 {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
fn _todo_isize_stub (&self) -> isize {
|
fn _todo_isize_stub (&self) -> isize {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
fn _todo_item_theme_stub (&self) -> ItemTheme {
|
fn _todo_item_theme_stub (&self) -> ItemTheme {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
fn w_sidebar (&self) -> u16 {
|
||||||
|
self.project.w_sidebar(self.editor.is_some())
|
||||||
|
}
|
||||||
fn focus_editor (&self) -> bool {
|
fn focus_editor (&self) -> bool {
|
||||||
self.is_editing()
|
self.is_editing()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,7 @@ impl App {
|
||||||
ArrangerView::new(&self.project, self.editor.as_ref())
|
ArrangerView::new(&self.project, self.editor.as_ref())
|
||||||
}
|
}
|
||||||
pub fn view_pool (&self) -> impl Content<TuiOut> + use<'_> {
|
pub fn view_pool (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
let is_editing = self.is_editing();
|
PoolView(&self.project.pool)
|
||||||
Fixed::x(self.project.w_sidebar(is_editing),
|
|
||||||
PoolView(is_editing, &self.project.pool))
|
|
||||||
}
|
}
|
||||||
pub fn view_samples_keys (&self) -> impl Content<TuiOut> + use<'_> {
|
pub fn view_samples_keys (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
self.project.sampler().map(|s|s.view_list(false, self.editor().unwrap()))
|
self.project.sampler().map(|s|s.view_list(false, self.editor().unwrap()))
|
||||||
|
|
|
||||||
|
|
@ -72,43 +72,24 @@ pub enum LaunchMode {
|
||||||
|
|
||||||
impl Cli {
|
impl Cli {
|
||||||
pub fn run (&self) -> Usually<()> {
|
pub fn run (&self) -> Usually<()> {
|
||||||
let name = self.name.as_ref().map_or("tek", |x|x.as_str());
|
let name = self.name.as_ref().map_or("tek", |x|x.as_str());
|
||||||
let mode = &self.mode;
|
let empty = &[] as &[&str];
|
||||||
let empty = &[] as &[&str];
|
let mut midi_ins = vec![];
|
||||||
let midi_froms = PortConnect::collect(&self.midi_from, empty, &self.midi_from_re);
|
let mut midi_outs = vec![];
|
||||||
let midi_tos = PortConnect::collect(&self.midi_to, empty, &self.midi_to_re);
|
let mut tracks = vec![];
|
||||||
let left_froms = PortConnect::collect(&self.left_from, empty, empty);
|
let mut scenes = vec![];
|
||||||
let left_tos = PortConnect::collect(&self.left_to, empty, empty);
|
let midi_froms = PortConnect::collect(&self.midi_from, empty, &self.midi_from_re);
|
||||||
let right_froms = PortConnect::collect(&self.right_from, empty, empty);
|
let midi_tos = PortConnect::collect(&self.midi_to, empty, &self.midi_to_re);
|
||||||
let right_tos = PortConnect::collect(&self.right_to, empty, empty);
|
let left_froms = PortConnect::collect(&self.left_from, empty, empty);
|
||||||
let audio_froms = &[left_froms.as_slice(), right_froms.as_slice()];
|
let left_tos = PortConnect::collect(&self.left_to, empty, empty);
|
||||||
let audio_tos = &[left_tos.as_slice(), right_tos.as_slice()];
|
let right_froms = PortConnect::collect(&self.right_from, empty, empty);
|
||||||
let clip = match mode {
|
let right_tos = PortConnect::collect(&self.right_to, empty, empty);
|
||||||
LaunchMode::Sequencer | LaunchMode::Groovebox =>
|
let audio_froms = &[left_froms.as_slice(), right_froms.as_slice()];
|
||||||
Some(Arc::new(RwLock::new(MidiClip::new(
|
let audio_tos = &[left_tos.as_slice(), right_tos.as_slice()];
|
||||||
"Clip", true, 384usize, None, Some(ItemColor::random().into())),
|
let clip = Arc::new(RwLock::new(MidiClip::new(
|
||||||
))),
|
"Clip", true, 384usize, None, Some(ItemColor::random().into())),
|
||||||
_ => None,
|
));
|
||||||
};
|
|
||||||
let scenes = vec![];
|
|
||||||
let mut tracks = vec![];
|
|
||||||
match mode {
|
|
||||||
LaunchMode::Sequencer => tracks.push(Track::new(
|
|
||||||
&name, None, jack,
|
|
||||||
Some(&clock), clip.as_ref(),
|
|
||||||
midi_froms.as_slice(), midi_tos.as_slice()
|
|
||||||
)?),
|
|
||||||
LaunchMode::Groovebox | LaunchMode::Sampler => tracks.push(Track::new_with_sampler(
|
|
||||||
&name, None, jack,
|
|
||||||
Some(&clock), clip.as_ref(),
|
|
||||||
midi_froms.as_slice(), midi_tos.as_slice(),
|
|
||||||
audio_froms, audio_tos,
|
|
||||||
)?),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
Tui::new()?.run(&Jack::new(name)?.run(|jack|{
|
Tui::new()?.run(&Jack::new(name)?.run(|jack|{
|
||||||
let mut midi_ins = vec![];
|
|
||||||
let mut midi_outs = vec![];
|
|
||||||
for (index, connect) in midi_froms.iter().enumerate() {
|
for (index, connect) in midi_froms.iter().enumerate() {
|
||||||
let port = JackMidiIn::new(jack, &format!("M/{index}"), &[connect.clone()])?;
|
let port = JackMidiIn::new(jack, &format!("M/{index}"), &[connect.clone()])?;
|
||||||
midi_ins.push(port);
|
midi_ins.push(port);
|
||||||
|
|
@ -117,53 +98,57 @@ impl Cli {
|
||||||
let port = JackMidiOut::new(jack, &format!("{index}/M"), &[connect.clone()])?;
|
let port = JackMidiOut::new(jack, &format!("{index}/M"), &[connect.clone()])?;
|
||||||
midi_outs.push(port);
|
midi_outs.push(port);
|
||||||
};
|
};
|
||||||
let config_path = match mode {
|
let config = Configuration::new(&match self.mode {
|
||||||
LaunchMode::Clock => "config/config_transport.edn",
|
LaunchMode::Clock => "config/config_transport.edn",
|
||||||
LaunchMode::Sequencer => "config/config_sequencer.edn",
|
LaunchMode::Sequencer => "config/config_sequencer.edn",
|
||||||
LaunchMode::Groovebox => "config/config_groovebox.edn",
|
LaunchMode::Groovebox => "config/config_groovebox.edn",
|
||||||
LaunchMode::Arranger { .. } => "config/config_arranger.edn",
|
LaunchMode::Arranger { .. } => "config/config_arranger.edn",
|
||||||
LaunchMode::Sampler => "config/config_sampler.edn",
|
LaunchMode::Sampler => "config/config_sampler.edn",
|
||||||
_ => todo!("{mode:?}"),
|
_ => todo!("{:?}", self.mode),
|
||||||
};
|
}, false)?;
|
||||||
let config = Configuration::new(&config_path, false)?;
|
let clock = Clock::new(jack, self.bpm)?;
|
||||||
let clock = Clock::new(jack, self.bpm)?;
|
match self.mode {
|
||||||
|
LaunchMode::Sequencer => tracks.push(Track::new(
|
||||||
|
&name, None, jack, Some(&clock), Some(&clip),
|
||||||
|
midi_froms.as_slice(), midi_tos.as_slice()
|
||||||
|
)?),
|
||||||
|
LaunchMode::Groovebox | LaunchMode::Sampler => tracks.push(Track::new_with_sampler(
|
||||||
|
&name, None, jack, Some(&clock), Some(&clip),
|
||||||
|
midi_froms.as_slice(), midi_tos.as_slice(), audio_froms, audio_tos,
|
||||||
|
)?),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
let mut app = App {
|
let mut app = App {
|
||||||
jack: jack.clone(),
|
jack: jack.clone(),
|
||||||
|
config,
|
||||||
color: ItemTheme::random(),
|
color: ItemTheme::random(),
|
||||||
pool: match mode {
|
editor: match self.mode {
|
||||||
LaunchMode::Sequencer | LaunchMode::Groovebox => clip.as_ref().map(Into::into),
|
LaunchMode::Sequencer | LaunchMode::Groovebox => Some((&clip).into()),
|
||||||
LaunchMode::Arranger { .. } => Some(Default::default()),
|
|
||||||
_ => None,
|
|
||||||
},
|
|
||||||
editor: match mode {
|
|
||||||
LaunchMode::Sequencer | LaunchMode::Groovebox => clip.as_ref().map(Into::into),
|
|
||||||
LaunchMode::Arranger { .. } => Some(Default::default()),
|
|
||||||
_ => None
|
_ => None
|
||||||
},
|
},
|
||||||
midi_ins,
|
project: Arrangement {
|
||||||
midi_outs,
|
name: Default::default(),
|
||||||
midi_buf: match mode {
|
color: ItemTheme::random(),
|
||||||
LaunchMode::Clock |
|
jack: jack.clone(),
|
||||||
LaunchMode::Sampler =>
|
clock,
|
||||||
vec![],
|
tracks,
|
||||||
LaunchMode::Sequencer |
|
scenes,
|
||||||
LaunchMode::Groovebox |
|
selection: Selection::TrackClip { track: 0, scene: 0 },
|
||||||
LaunchMode::Arranger {..} =>
|
midi_ins,
|
||||||
vec![vec![];65536],
|
midi_outs,
|
||||||
_ => todo!("{mode:?}"),
|
pool: match self.mode {
|
||||||
|
LaunchMode::Sequencer | LaunchMode::Groovebox => (&clip).into(),
|
||||||
|
_ => Default::default()
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
},
|
},
|
||||||
tracks,
|
|
||||||
scenes,
|
|
||||||
selected: Selection::TrackClip { track: 0, scene: 0 },
|
|
||||||
config,
|
|
||||||
clock,
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
if let &LaunchMode::Arranger { scenes, tracks, track_width, .. } = mode {
|
if let LaunchMode::Arranger { scenes, tracks, track_width, .. } = self.mode {
|
||||||
app.arranger = Default::default();
|
app.project.arranger = Default::default();
|
||||||
app.selected = Selection::TrackClip { track: 1, scene: 1 };
|
app.project.selection = Selection::TrackClip { track: 1, scene: 1 };
|
||||||
app.scenes_add(scenes)?;
|
app.project.scenes_add(scenes)?;
|
||||||
app.tracks_add(tracks, Some(track_width), &[], &[])?;
|
app.project.tracks_add(tracks, Some(track_width), &[], &[])?;
|
||||||
}
|
}
|
||||||
jack.sync_lead(self.sync_lead, |mut state|{
|
jack.sync_lead(self.sync_lead, |mut state|{
|
||||||
let clock = app.clock();
|
let clock = app.clock();
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,6 @@ pub struct Arrangement {
|
||||||
pub audio_ins: Vec<JackAudioIn>,
|
pub audio_ins: Vec<JackAudioIn>,
|
||||||
/// List of global audio outputs
|
/// List of global audio outputs
|
||||||
pub audio_outs: Vec<JackAudioOut>,
|
pub audio_outs: Vec<JackAudioOut>,
|
||||||
/// Buffer for writing a midi event
|
|
||||||
pub note_buf: Vec<u8>,
|
|
||||||
/// Buffer for writing a chunk of midi events
|
|
||||||
pub midi_buf: Vec<Vec<Vec<u8>>>,
|
|
||||||
/// Last track number (to avoid duplicate port names)
|
/// Last track number (to avoid duplicate port names)
|
||||||
pub track_last: usize,
|
pub track_last: usize,
|
||||||
/// List of tracks
|
/// List of tracks
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,31 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
pub struct PoolView<'a>(pub bool, pub &'a Pool);
|
pub struct PoolView<'a>(pub &'a Pool);
|
||||||
|
|
||||||
content!(TuiOut: |self: PoolView<'a>| {
|
content!(TuiOut: |self: PoolView<'a>| {
|
||||||
let Self(compact, model) = self;
|
let Self(pool) = self;
|
||||||
let Pool { clips, .. } = self.1;
|
|
||||||
//let color = self.1.clip().map(|c|c.read().unwrap().color).unwrap_or_else(||Tui::g(32).into());
|
//let color = self.1.clip().map(|c|c.read().unwrap().color).unwrap_or_else(||Tui::g(32).into());
|
||||||
let on_bg = |x|x;//Bsp::b(Repeat(" "), Tui::bg(color.darkest.rgb, x));
|
//let on_bg = |x|x;//Bsp::b(Repeat(" "), Tui::bg(color.darkest.rgb, x));
|
||||||
let border = |x|x;//Outer(Style::default().fg(color.dark.rgb).bg(color.darkest.rgb)).enclose(x);
|
//let border = |x|x;//Outer(Style::default().fg(color.dark.rgb).bg(color.darkest.rgb)).enclose(x);
|
||||||
let iter = | |model.clips().clone().into_iter();
|
let height = pool.clips.read().unwrap().len() as u16;
|
||||||
let height = clips.read().unwrap().len() as u16;
|
Fixed::x(20, Fill::y(Align::c(Map::new(
|
||||||
Tui::bg(Reset, Fixed::y(height, on_bg(border(Map::new(iter, move|clip: Arc<RwLock<MidiClip>>, i|{
|
||pool.clips().clone().into_iter(),
|
||||||
|
move|clip: Arc<RwLock<MidiClip>>, i: usize|{
|
||||||
let item_height = 1;
|
let item_height = 1;
|
||||||
let item_offset = i as u16 * item_height;
|
let item_offset = i as u16 * item_height;
|
||||||
let selected = i == model.clip_index();
|
let selected = i == pool.clip_index();
|
||||||
let MidiClip { ref name, color, length, .. } = *clip.read().unwrap();
|
let MidiClip { ref name, color, length, .. } = *clip.read().unwrap();
|
||||||
let bg = if selected { color.light.rgb } else { color.base.rgb };
|
let bg = if selected { color.light.rgb } else { color.base.rgb };
|
||||||
let fg = color.lightest.rgb;
|
let fg = color.lightest.rgb;
|
||||||
let name = if *compact { format!(" {i:>3}") } else { format!(" {i:>3} {name}") };
|
let name = if false { format!(" {i:>3}") } else { format!(" {i:>3} {name}") };
|
||||||
let length = if *compact { String::default() } else { format!("{length} ") };
|
let length = if false { String::default() } else { format!("{length} ") };
|
||||||
Fixed::y(1, map_south(item_offset, item_height, Tui::bg(bg, lay!(
|
Fixed::y(1, map_south(item_offset, item_height, Tui::bg(bg, lay!(
|
||||||
Fill::x(Align::w(Tui::fg(fg, Tui::bold(selected, name)))),
|
Fill::x(Align::w(Tui::fg(fg, Tui::bold(selected, name)))),
|
||||||
Fill::x(Align::e(Tui::fg(fg, Tui::bold(selected, length)))),
|
Fill::x(Align::e(Tui::fg(fg, Tui::bold(selected, length)))),
|
||||||
Fill::x(Align::w(When::new(selected, Tui::bold(true, Tui::fg(Tui::g(255), "▶"))))),
|
Fill::x(Align::w(When::new(selected, Tui::bold(true, Tui::fg(Tui::g(255), "▶"))))),
|
||||||
Fill::x(Align::e(When::new(selected, Tui::bold(true, Tui::fg(Tui::g(255), "◀"))))),
|
Fill::x(Align::e(When::new(selected, Tui::bold(true, Tui::fg(Tui::g(255), "◀"))))),
|
||||||
))))
|
))))
|
||||||
})))))
|
}))))
|
||||||
});
|
});
|
||||||
|
|
||||||
content!(TuiOut: |self: ClipLength| {
|
content!(TuiOut: |self: ClipLength| {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue