struct Track; load Sampler in Launcher

This commit is contained in:
🪞👃🪞 2024-06-28 00:09:53 +03:00
parent 1038e24ceb
commit 685c49cfd9
6 changed files with 150 additions and 122 deletions

View file

@ -9,8 +9,7 @@ pub struct Launcher {
overdub: bool,
position: usize,
cursor: (usize, usize),
pub tracks: Vec<DynamicDevice<Sequencer>>,
pub chains: Vec<DynamicDevice<Chain>>,
pub tracks: Vec<Track>,
scenes: Vec<Scene>,
show_help: bool,
view: LauncherView,
@ -70,7 +69,7 @@ impl Launcher {
)?;
}
}
let chain: &DynamicDevice<Chain> = &state.chains[i];
let chain: &DynamicDevice<Chain> = &state.tracks[i].chain;
for midi_out in sequencer.midi_outs()?.iter() {
for midi_in in chain.midi_ins()?.iter() {
client.connect_ports_by_name(&midi_out, &midi_in)?;
@ -78,7 +77,7 @@ impl Launcher {
}
for (j, port) in chain.audio_outs()?.iter().enumerate() {
for audio_out in audio_outs[j % audio_outs.len()].iter() {
client.connect_ports_by_name(&port, &audio_out);
client.connect_ports_by_name(&port, &audio_out)?;
}
}
}
@ -114,43 +113,18 @@ impl Launcher {
Scene::new(&"Scene#08", &[None, None, None, None]),
],
tracks: vec![
Sequencer::new("Drum", &timebase)?,
Sequencer::new("Bass", &timebase)?,
Sequencer::new("Pads", &timebase)?,
Sequencer::new("Lead", &timebase)?,
],
chains: vec![
Chain::new("Chain#0000", vec![
Plugin::lv2(
"Plugin#000",
"file:///home/user/.lv2/ChowKick.lv2",
&[1, 1, 0, 2]
)?.boxed(),
Track::new("Samples", &timebase, vec![
Sampler::new("Samples")?.boxed(),
])?,
Chain::new("Chain#0000", vec![
Plugin::lv2(
"Plugin#001",
"file:///home/user/.lv2/Helm.lv2",
&[1, 0, 0, 2]
)?.boxed(),
])?,
Chain::new("Chain#0000", vec![
Plugin::lv2(
"Plugin#002",
"file:///home/user/.lv2/Helm.lv2",
&[1, 0, 0, 2]
)?.boxed(),
])?,
Chain::new("Chain#0000", vec![
Plugin::lv2(
"Plugin#003",
"file:///home/user/.lv2/Odin2.lv2",
&[1, 0, 0, 2]
)?.boxed(),
Track::new("Kick", &timebase, vec![
//Plugin::lv2("Kick/ChowKick", "file:///home/user/.lv2/ChowKick.lv2", &[1, 1, 0, 2])?.boxed(),
])?,
//Track::new("Bass", &timebase, vec![
//Plugin::lv2("Bass/Helm", "file:///home/user/.lv2/Helm.lv2", &[1, 0, 0, 2])?.boxed(),
//])?,
//Track::new("Pads", &timebase, vec![
//Plugin::lv2("Pads/Odin2", "file:///home/user/.lv2/Odin2.lv2", &[1, 0, 0, 2])?.boxed(),
//])?,
],
timebase,
show_help: true
@ -196,6 +170,20 @@ impl Launcher {
self.cursor.1 + 1
}
}
fn active_track (&self) -> Option<&Track> {
if self.cursor.0 >= 1 {
self.tracks.get(self.cursor.0 as usize - 1 as usize)
} else {
None
}
}
fn active_sequencer <'a> (&'a self) -> Option<std::sync::MutexGuard<Sequencer>> {
self.active_track().map(|t|t.sequencer.state())
}
fn active_chain <'a> (&'a self) -> Option<std::sync::MutexGuard<Chain>> {
self.active_track().map(|t|t.chain.state())
}
}
impl PortList for Launcher {}
pub fn process (state: &mut Launcher, _: &Client, _: &ProcessScope) -> Control {
@ -228,8 +216,15 @@ pub fn render (state: &Launcher, buf: &mut Buffer, area: Rect) -> Usually<Rect>
draw_crossings(state, buf, x + w - 2, y + 1);
draw_box(buf, Rect { x, y: y + 1, width, height: height - 1 });
let style = Some(Style::default().green().dim());
let chain = &*state.chains[0].state();
let (_, plugins) = crate::device::chain::draw_as_row(chain, buf, chain_area, style)?;
let chain = state.active_chain();
let plugins = if let Some(chain) = &chain {
let (_, plugins) = crate::device::chain::draw_as_row(
&*chain, buf, chain_area, style
)?;
plugins
} else {
vec![]
};
if state.view == LauncherView::Tracks {
draw_box_styled(buf, track_area, style);
@ -242,10 +237,14 @@ pub fn render (state: &Launcher, buf: &mut Buffer, area: Rect) -> Usually<Rect>
if state.view == LauncherView::Chains {
draw_box_styled(buf, Rect { height: 18, ..chain_area }, style);
}
draw_highlight(state, buf, &Some(plugins[chain.focus]), match state.view {
LauncherView::Chains => Style::default().green().not_dim(),
_ => Style::default().green().dim()
});
if let Some(chain) = &chain {
if let Some(plugin) = plugins.get(chain.focus) {
draw_highlight(state, buf, &Some(*plugin), match state.view {
LauncherView::Chains => Style::default().green().not_dim(),
_ => Style::default().green().dim()
});
}
}
if state.view == LauncherView::Sequencer {
draw_box_styled(buf, seq_area, style);
@ -303,7 +302,7 @@ fn draw_tracks (
let mut w = 15;
let mut highlight = None;
for (i, track) in state.tracks.iter().enumerate() {
let track = track.state();
let track = track.sequencer.state();
draw_crossings(state, buf, x + w - 2, y);
let width = draw_track(state, buf, x + w, y, i as u16, &track);
if i + 1 == state.col() {
@ -333,7 +332,7 @@ fn draw_track (
} else {
Style::default()
};
for (scene_index, scene) in state.scenes.iter().enumerate() {
for (_, scene) in state.scenes.iter().enumerate() {
if let Some(Some(sequence_index)) = scene.clips.get(i as usize) {
if let Some(sequence) = track.sequences.get(*sequence_index) {
width = width.max(sequence.name.len() as u16 + 5);
@ -376,18 +375,18 @@ fn draw_crossings (state: &Launcher, buf: &mut Buffer, x: u16, y: u16) {
fn draw_sequencer (
state: &Launcher, buf: &mut Buffer, x: u16, y: u16, width: u16, height: u16
) -> Usually<()> {
if let Some(sequencer) = state.tracks.get(state.col().saturating_sub(1)) {
if let Some(track) = state.tracks.get(state.col().saturating_sub(1)) {
//crate::device::sequencer::horizontal::footer(
//&sequencer.state(), buf, 0, y, width, 0
//);
crate::device::sequencer::horizontal::keys(
&sequencer.state(), buf, Rect { x, y: y + 1, width, height }
&track.sequencer.state(), buf, Rect { x, y: y + 1, width, height }
)?;
crate::device::sequencer::horizontal::lanes(
&sequencer.state(), buf, x, y + 1, width,
&track.sequencer.state(), buf, x, y + 1, width,
);
crate::device::sequencer::horizontal::cursor(
&sequencer.state(), buf, x, y + 1, match state.view {
&track.sequencer.state(), buf, x, y + 1, match state.view {
LauncherView::Sequencer => Style::default().green().not_dim(),
_ => Style::default().green().dim(),
}
@ -410,8 +409,8 @@ pub fn handle (state: &mut Launcher, event: &AppEvent) -> Usually<bool> {
},
LauncherView::Sequencer => {
let i = state.col().saturating_sub(1);
if let Some(sequencer) = state.tracks.get_mut(i) {
crate::device::sequencer::handle(&mut *sequencer.state(), event)?
if let Some(track) = state.tracks.get_mut(i) {
crate::device::sequencer::handle(&mut *track.sequencer.state(), event)?
} else {
true
}
@ -486,7 +485,7 @@ fn clip_next (state: &mut Launcher) -> Usually<bool> {
let scene = &mut state.scenes[scene_id];
scene.clips[clip_id] = match scene.clips[clip_id] {
None => Some(0),
Some(i) => if i >= state.tracks[clip_id].state().sequences.len().saturating_sub(1) {
Some(i) => if i >= state.tracks[clip_id].sequencer.state().sequences.len().saturating_sub(1) {
None
} else {
Some(i + 1)
@ -501,7 +500,7 @@ fn clip_prev (state: &mut Launcher) -> Usually<bool> {
let clip_id = state.cursor.0 - 1;
let scene = &mut state.scenes[scene_id];
scene.clips[clip_id] = match scene.clips[clip_id] {
None => Some(state.tracks[clip_id].state().sequences.len().saturating_sub(1)),
None => Some(state.tracks[clip_id].sequencer.state().sequences.len().saturating_sub(1)),
Some(i) => if i == 0 {
None
} else {
@ -530,22 +529,22 @@ fn play_start (_: &mut Launcher) -> Usually<bool> {
}
fn record_toggle (s: &mut Launcher) -> Usually<bool> {
s.recording = !s.recording;
for sequencer in s.tracks.iter() {
sequencer.state().recording = s.recording;
for track in s.tracks.iter() {
track.sequencer.state().recording = s.recording;
}
Ok(true)
}
fn overdub_toggle (s: &mut Launcher) -> Usually<bool> {
s.overdub = !s.overdub;
for sequencer in s.tracks.iter() {
sequencer.state().overdub = s.overdub;
for track in s.tracks.iter() {
track.sequencer.state().overdub = s.overdub;
}
Ok(true)
}
fn monitor_toggle (s: &mut Launcher) -> Usually<bool> {
s.monitoring = !s.monitoring;
for sequencer in s.tracks.iter() {
sequencer.state().monitoring = s.monitoring;
for track in s.tracks.iter() {
track.sequencer.state().monitoring = s.monitoring;
}
Ok(true)
}