mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
transport master
This commit is contained in:
parent
185c6b5b34
commit
be2c2df92b
4 changed files with 85 additions and 62 deletions
|
|
@ -16,3 +16,4 @@ midly = "0.5"
|
||||||
vst = "0.4.0"
|
vst = "0.4.0"
|
||||||
#vst3 = "0.1.0"
|
#vst3 = "0.1.0"
|
||||||
livi = "0.7.4"
|
livi = "0.7.4"
|
||||||
|
#atomic_enum = "0.3.0"
|
||||||
|
|
|
||||||
|
|
@ -44,21 +44,21 @@ pub fn render (state: &Plugin, buf: &mut Buffer, Rect { x, y, .. }: Rect)
|
||||||
let style = Style::default().gray();
|
let style = Style::default().gray();
|
||||||
buf.set_string(x + 1, y + 1, &format!(" {}", state.name), style.white().bold());
|
buf.set_string(x + 1, y + 1, &format!(" {}", state.name), style.white().bold());
|
||||||
buf.set_string(x + 13, y + 1, &format!("│ ...{}...", &HELM[13..30]), style.not_dim());
|
buf.set_string(x + 13, y + 1, &format!("│ ...{}...", &HELM[13..30]), style.not_dim());
|
||||||
buf.set_string(x + 0, y + 2, &format!("├--------------------------------------┤"), style.dim());
|
buf.set_string(x + 0, y + 2, &format!("├------------------------------------------------┤"), style.dim());
|
||||||
match &state.plugin {
|
match &state.plugin {
|
||||||
Some(PluginKind::LV2(ports, instance)) => {
|
Some(PluginKind::LV2(ports, instance)) => {
|
||||||
let mut height = 3;
|
let mut height = 3;
|
||||||
for (i, port) in ports.iter().skip(state.parameter_offset).enumerate() {
|
for (i, port) in ports.iter().skip(state.parameter_offset).enumerate() {
|
||||||
if i >= 10 {
|
if i >= 20 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
buf.set_string(x + 2, y + 3 + i as u16, &format!("{:20} = {:03}",
|
buf.set_string(x + 2, y + 3 + i as u16, &format!("{:30} = {:03}",
|
||||||
port.name,
|
port.name,
|
||||||
port.default_value
|
port.default_value
|
||||||
), Style::default());
|
), Style::default());
|
||||||
height = height + 1;
|
height = height + 1;
|
||||||
}
|
}
|
||||||
Ok(draw_box(buf, Rect { x, y, width: 40, height: height.max(10) }))
|
Ok(draw_box(buf, Rect { x, y, width: 50, height: height.max(20) }))
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
buf.set_string(x + 1, y + 3, &format!(" Parameter 1 0.0"), style);
|
buf.set_string(x + 1, y + 3, &format!(" Parameter 1 0.0"), style);
|
||||||
|
|
|
||||||
|
|
@ -88,17 +88,18 @@ impl Sequencer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
|
fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
|
||||||
process_out(self, scope);
|
let transport = self.transport.query().unwrap();
|
||||||
process_in(self, scope);
|
process_out(self, scope, &transport);
|
||||||
|
process_in(self, scope, &transport);
|
||||||
Control::Continue
|
Control::Continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_in (s: &mut Sequencer, scope: &ProcessScope) {
|
fn process_in (s: &mut Sequencer, scope: &ProcessScope, transport: &::jack::TransportStatePosition) {
|
||||||
if !s.recording {
|
if !s.recording {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let pos = s.transport.query().unwrap().pos;
|
let pos = &transport.pos;
|
||||||
let usecs = s.timebase.frame_to_usec(pos.frame() as usize);
|
let usecs = s.timebase.frame_to_usec(pos.frame() as usize);
|
||||||
let steps = usecs / s.timebase.usec_per_step(s.resolution as usize);
|
let steps = usecs / s.timebase.usec_per_step(s.resolution as usize);
|
||||||
let step = steps % s.steps;
|
let step = steps % s.steps;
|
||||||
|
|
@ -139,11 +140,10 @@ fn process_in (s: &mut Sequencer, scope: &ProcessScope) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_out (s: &mut Sequencer, scope: &ProcessScope) {
|
fn process_out (s: &mut Sequencer, scope: &ProcessScope, transport: &::jack::TransportStatePosition) {
|
||||||
if !s.playing {
|
if !s.playing {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let transport = s.transport.query().unwrap();
|
|
||||||
if transport.state != ::jack::TransportState::Rolling {
|
if transport.state != ::jack::TransportState::Rolling {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -196,7 +196,7 @@ fn render (s: &Sequencer, buf: &mut Buffer, mut area: Rect) -> Usually<Rect> {
|
||||||
SequencerView::Horizontal => draw_horizontal(s, buf, Rect {
|
SequencerView::Horizontal => draw_horizontal(s, buf, Rect {
|
||||||
x,
|
x,
|
||||||
y: y + header.height,
|
y: y + header.height,
|
||||||
width: 3 + time1 - time0,
|
width: area.width.max(3 + time1 - time0),
|
||||||
height: 3 + note1 - note0,
|
height: 3 + note1 - note0,
|
||||||
})?,
|
})?,
|
||||||
};
|
};
|
||||||
|
|
@ -217,7 +217,12 @@ fn draw_header (s: &Sequencer, buf: &mut Buffer, area: Rect, beat: usize) -> Usu
|
||||||
let style = Style::default().gray();
|
let style = Style::default().gray();
|
||||||
let timer = format!("{rep}.{step:02} / {reps}.{steps}");
|
let timer = format!("{rep}.{step:02} / {reps}.{steps}");
|
||||||
buf.set_string(x + width - 2 - timer.len() as u16, y + 1, &timer, style.bold().not_dim());
|
buf.set_string(x + width - 2 - timer.len() as u16, y + 1, &timer, style.bold().not_dim());
|
||||||
buf.set_string(x + 2, y + 1, &format!("⏹ STOP"), style.not_dim().white().bold());
|
buf.set_string(x + 2, y + 1, &format!("⏹ STOP"), if s.playing {
|
||||||
|
style.dim().bold()
|
||||||
|
} else {
|
||||||
|
style.not_dim().white().bold()
|
||||||
|
});
|
||||||
|
buf.set_string(x, y + 2, format!("├{}┤", "-".repeat((area.width - 2).into())), style.dim());
|
||||||
//buf.set_string(x + 2, y + 2,
|
//buf.set_string(x + 2, y + 2,
|
||||||
//&format!("▶ PLAY"), if s.playing {
|
//&format!("▶ PLAY"), if s.playing {
|
||||||
//Style::default().green()
|
//Style::default().green()
|
||||||
|
|
@ -225,14 +230,20 @@ fn draw_header (s: &Sequencer, buf: &mut Buffer, area: Rect, beat: usize) -> Usu
|
||||||
//Style::default().dim()
|
//Style::default().dim()
|
||||||
//});
|
//});
|
||||||
buf.set_string(x + 10, y + 1,
|
buf.set_string(x + 10, y + 1,
|
||||||
&format!("⏺ REC"), if s.recording {
|
&format!("⏺ MON"), if s.monitoring {
|
||||||
Style::default().red()
|
Style::default().bold().green()
|
||||||
} else {
|
} else {
|
||||||
Style::default().bold().dim()
|
Style::default().bold().dim()
|
||||||
});
|
});
|
||||||
buf.set_string(x + 17, y + 1,
|
buf.set_string(x + 17, y + 1,
|
||||||
|
&format!("⏺ REC"), if s.recording {
|
||||||
|
Style::default().bold().red()
|
||||||
|
} else {
|
||||||
|
Style::default().bold().dim()
|
||||||
|
});
|
||||||
|
buf.set_string(x + 24, y + 1,
|
||||||
&format!("⏺ DUB"), if s.overdub {
|
&format!("⏺ DUB"), if s.overdub {
|
||||||
Style::default().yellow()
|
Style::default().bold().yellow()
|
||||||
} else {
|
} else {
|
||||||
Style::default().bold().dim()
|
Style::default().bold().dim()
|
||||||
});
|
});
|
||||||
|
|
@ -243,14 +254,17 @@ fn draw_header (s: &Sequencer, buf: &mut Buffer, area: Rect, beat: usize) -> Usu
|
||||||
fn draw_clips (s: &Sequencer, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
fn draw_clips (s: &Sequencer, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
let Rect { x, y, .. } = area;
|
let Rect { x, y, .. } = area;
|
||||||
let style = Style::default().gray();
|
let style = Style::default().gray();
|
||||||
buf.set_string(x + 2, y + 3, &format!("▶ {}", &s.name), style.not_dim().bold());
|
for i in 0..8 {
|
||||||
buf.set_string(x + 2, y + 5, &format!("⏺ {}", &s.name), style.dim());
|
buf.set_string(x + 2, y + 3 + i*2, &format!("▶ {}", &s.name), if i as usize == s.sequence {
|
||||||
buf.set_string(x + 2, y + 7, &format!("⏺ {}", &s.name), style.dim());
|
if s.playing {
|
||||||
buf.set_string(x + 2, y + 9, &format!("⏺ {}", &s.name), style.dim());
|
style.white().bold()
|
||||||
buf.set_string(x + 2, y + 11, &format!("⏺ {}", &s.name), style.dim());
|
} else {
|
||||||
buf.set_string(x + 2, y + 13, &format!("⏺ {}", &s.name), style.dim());
|
style.not_dim().bold()
|
||||||
buf.set_string(x + 2, y + 15, &format!("⏺ {}", &s.name), style.dim());
|
}
|
||||||
buf.set_string(x + 2, y + 17, &format!("⏺ {}", &s.name), style.dim());
|
} else {
|
||||||
|
style.dim()
|
||||||
|
});
|
||||||
|
}
|
||||||
Ok(Rect { x, y, width: 14, height: 14 })
|
Ok(Rect { x, y, width: 14, height: 14 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -350,7 +364,7 @@ fn draw_vertical (s: &Sequencer, buf: &mut Buffer, mut area: Rect, beat: usize)
|
||||||
if s.time_cursor % 2 == 0 { "▀" } else { "▄" },
|
if s.time_cursor % 2 == 0 { "▀" } else { "▄" },
|
||||||
Style::default()
|
Style::default()
|
||||||
);
|
);
|
||||||
Ok(Rect { x, y, width: area.width, height: height + 3 })
|
Ok(Rect { x, y, width: area.width, height: height + 1 })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn contains_note_on (sequence: &Sequence, k: ::midly::num::u7, start: u32, end: u32) -> bool {
|
fn contains_note_on (sequence: &Sequence, k: ::midly::num::u7, start: u32, end: u32) -> bool {
|
||||||
|
|
@ -412,7 +426,7 @@ fn draw_keys_horizontal (s: &Sequencer, buf: &mut Buffer, mut area: Rect) -> Usu
|
||||||
|
|
||||||
fn draw_horizontal (s: &Sequencer, buf: &mut Buffer, mut area: Rect) -> Usually<Rect> {
|
fn draw_horizontal (s: &Sequencer, buf: &mut Buffer, mut area: Rect) -> Usually<Rect> {
|
||||||
area.x = area.x + 13;
|
area.x = area.x + 13;
|
||||||
let Rect { x, y, .. } = area;
|
let Rect { x, y, width, .. } = area;
|
||||||
let (time0, time1) = s.time_axis;
|
let (time0, time1) = s.time_axis;
|
||||||
let (note0, note1) = s.note_axis;
|
let (note0, note1) = s.note_axis;
|
||||||
let bw = Style::default().dim();
|
let bw = Style::default().dim();
|
||||||
|
|
@ -428,8 +442,10 @@ fn draw_horizontal (s: &Sequencer, buf: &mut Buffer, mut area: Rect) -> Usually<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let height = 32.max(note1 - note0) / 2;
|
let height = 32.max(note1 - note0) / 2;
|
||||||
buf.set_string(x + 2, y + height, format!(
|
buf.set_string(x - 13, y + height, format!("├{}┤", "-".repeat((width - 2).into())),
|
||||||
" Q 1/{} | N {} ({}-{}) | T {} ({}-{})",
|
Style::default().dim());
|
||||||
|
buf.set_string(x - 11, y + height + 1, format!(
|
||||||
|
"Sync 4/4 Quantize 1/{} Notes {} ({}-{}) Time {} ({}-{})",
|
||||||
4 * s.resolution,
|
4 * s.resolution,
|
||||||
s.note_axis.0 + s.note_cursor,
|
s.note_axis.0 + s.note_cursor,
|
||||||
s.note_axis.0,
|
s.note_axis.0,
|
||||||
|
|
@ -437,7 +453,7 @@ fn draw_horizontal (s: &Sequencer, buf: &mut Buffer, mut area: Rect) -> Usually<
|
||||||
s.time_axis.0 + s.time_cursor + 1,
|
s.time_axis.0 + s.time_cursor + 1,
|
||||||
s.time_axis.0 + 1,
|
s.time_axis.0 + 1,
|
||||||
s.time_axis.1,
|
s.time_axis.1,
|
||||||
), Style::default().dim());
|
), Style::default().not_dim());
|
||||||
buf.set_string(
|
buf.set_string(
|
||||||
x + 6 + s.time_cursor,
|
x + 6 + s.time_cursor,
|
||||||
y + s.note_cursor / 2,
|
y + s.note_cursor / 2,
|
||||||
|
|
@ -448,7 +464,7 @@ fn draw_horizontal (s: &Sequencer, buf: &mut Buffer, mut area: Rect) -> Usually<
|
||||||
x: x - 13,
|
x: x - 13,
|
||||||
y,
|
y,
|
||||||
width: time1 - time0 + 19,
|
width: time1 - time0 + 19,
|
||||||
height: height + 2
|
height: height + 3
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -457,37 +473,37 @@ pub fn handle (s: &mut Sequencer, event: &AppEvent) -> Usually<bool> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const KEYMAP: &'static [KeyBinding<Sequencer>] = keymap!(Sequencer {
|
pub const KEYMAP: &'static [KeyBinding<Sequencer>] = keymap!(Sequencer {
|
||||||
[Up, NONE, "cursor_up", "move cursor up", cursor_up],
|
[Up, NONE, "cursor_up", "move cursor up", cursor_up],
|
||||||
[Down, NONE, "cursor_down", "move cursor down", cursor_down],
|
[Down, NONE, "cursor_down", "move cursor down", cursor_down],
|
||||||
[Left, NONE, "cursor_left", "move cursor left", cursor_left],
|
[Left, NONE, "cursor_left", "move cursor left", cursor_left],
|
||||||
[Right, NONE, "cursor_right", "move cursor right", cursor_right],
|
[Right, NONE, "cursor_right", "move cursor right", cursor_right],
|
||||||
[Char(']'), NONE, "cursor_inc", "increase note duration", cursor_duration_inc],
|
[Char(']'), NONE, "cursor_inc", "increase note duration", cursor_duration_inc],
|
||||||
[Char('['), NONE, "cursor_dec", "decrease note duration", cursor_duration_dec],
|
[Char('['), NONE, "cursor_dec", "decrease note duration", cursor_duration_dec],
|
||||||
[Char('`'), NONE, "mode_next", "Next view mode", mode_next],
|
[Char('`'), NONE, "mode_next", "Next view mode", mode_next],
|
||||||
[Char('+'), NONE, "zoom_in", "Zoom in", nop],
|
[Char('+'), NONE, "zoom_in", "Zoom in", nop],
|
||||||
[Char('-'), NONE, "zoom_out", "Zoom out", nop],
|
[Char('-'), NONE, "zoom_out", "Zoom out", nop],
|
||||||
[Char('a'), NONE, "note_add", "Add note", note_add],
|
[Char('a'), NONE, "note_add", "Add note", note_add],
|
||||||
[Char('d'), NONE, "note_del", "Delete note", note_del],
|
[Char('z'), NONE, "note_del", "Delete note", note_del],
|
||||||
[CapsLock, NONE, "advance", "Toggle auto advance", nop],
|
[CapsLock, NONE, "advance", "Toggle auto advance", nop],
|
||||||
[Char('w'), NONE, "rest", "Advance by note duration", nop],
|
[Char('w'), NONE, "rest", "Advance by note duration", nop],
|
||||||
[Char('r'), NONE, "record", "Toggle recodring", toggle_record],
|
[Char('r'), NONE, "toggle_record", "Toggle recording", toggle_record],
|
||||||
[Char('o'), NONE, "overdub", "Toggle overdub", toggle_overdub],
|
[Char('d'), NONE, "toggle_overdub", "Toggle overdub", toggle_overdub],
|
||||||
[Char('p'), NONE, "play", "Toggle play/pause", toggle_play],
|
[Char(' '), NONE, "toggle_play", "Toggle play/pause", toggle_play],
|
||||||
[Char('s'), NONE, "stop", "Stop and rewind", stop_and_rewind],
|
[Char('s'), NONE, "stop_and_rewind", "Stop and rewind", stop_and_rewind],
|
||||||
[Char('q'), NONE, "quantize_next", "Next quantize value", quantize_next],
|
[Char('q'), NONE, "quantize_next", "Next quantize value", quantize_next],
|
||||||
[Char('Q'), SHIFT, "quantize_prev", "Previous quantize value", quantize_prev],
|
[Char('Q'), SHIFT, "quantize_prev", "Previous quantize value", quantize_prev],
|
||||||
[Char('n'), NONE, "note_axis", "Focus note axis", nop],
|
[Char('n'), NONE, "note_axis", "Focus note axis", nop],
|
||||||
[Char('t'), NONE, "time_axis", "Focus time axis", nop],
|
[Char('t'), NONE, "time_axis", "Focus time axis", nop],
|
||||||
[Char('v'), NONE, "variations", "Focus variation selector", nop],
|
[Char('v'), NONE, "variations", "Focus variation selector", nop],
|
||||||
[Char('s'), SHIFT, "sync", "Focus sync selector", nop],
|
[Char('s'), SHIFT, "sync", "Focus sync selector", nop],
|
||||||
[Char('1'), NONE, "focus_1", "Sequence 1", focus_seq(0)],
|
[Char('1'), NONE, "seq_1", "Sequence 1", focus_seq(0)],
|
||||||
[Char('2'), NONE, "focus_1", "Sequence 1", focus_seq(1)],
|
[Char('2'), NONE, "seq_2", "Sequence 2", focus_seq(1)],
|
||||||
[Char('3'), NONE, "focus_1", "Sequence 1", focus_seq(2)],
|
[Char('3'), NONE, "seq_3", "Sequence 3", focus_seq(2)],
|
||||||
[Char('4'), NONE, "focus_1", "Sequence 1", focus_seq(3)],
|
[Char('4'), NONE, "seq_4", "Sequence 4", focus_seq(3)],
|
||||||
[Char('5'), NONE, "focus_1", "Sequence 1", focus_seq(4)],
|
[Char('5'), NONE, "seq_5", "Sequence 5", focus_seq(4)],
|
||||||
[Char('6'), NONE, "focus_1", "Sequence 1", focus_seq(5)],
|
[Char('6'), NONE, "seq_6", "Sequence 6", focus_seq(5)],
|
||||||
[Char('7'), NONE, "focus_1", "Sequence 1", focus_seq(6)],
|
[Char('7'), NONE, "seq_7", "Sequence 7", focus_seq(6)],
|
||||||
[Char('8'), NONE, "focus_1", "Sequence 1", focus_seq(7)],
|
[Char('8'), NONE, "seq_8", "Sequence 8", focus_seq(7)],
|
||||||
});
|
});
|
||||||
|
|
||||||
const fn focus_seq (i: usize) -> impl Fn(&mut Sequencer)->Usually<bool> {
|
const fn focus_seq (i: usize) -> impl Fn(&mut Sequencer)->Usually<bool> {
|
||||||
|
|
@ -605,6 +621,12 @@ fn stop_and_rewind (s: &mut Sequencer) -> Usually<bool> {
|
||||||
}
|
}
|
||||||
fn toggle_play (s: &mut Sequencer) -> Usually<bool> {
|
fn toggle_play (s: &mut Sequencer) -> Usually<bool> {
|
||||||
s.playing = !s.playing;
|
s.playing = !s.playing;
|
||||||
|
if s.playing {
|
||||||
|
s.transport.start()?;
|
||||||
|
} else {
|
||||||
|
s.transport.stop()?;
|
||||||
|
s.transport.locate(0)?;
|
||||||
|
}
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
fn toggle_record (s: &mut Sequencer) -> Usually<bool> {
|
fn toggle_record (s: &mut Sequencer) -> Usually<bool> {
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ pub fn draw_box_styled (buffer: &mut Buffer, area: Rect, style: Option<Style>) -
|
||||||
let bottom = format!("╰{}╯", "─".repeat((area.width - 2).into()));
|
let bottom = format!("╰{}╯", "─".repeat((area.width - 2).into()));
|
||||||
buffer.set_string(area.x, area.y, top, style);
|
buffer.set_string(area.x, area.y, top, style);
|
||||||
for y in (area.y + 1)..(area.y + area.height - 1) {
|
for y in (area.y + 1)..(area.y + area.height - 1) {
|
||||||
buffer.set_string(area.x, y, format!("┇"), style);
|
buffer.set_string(area.x, y, format!("│"), style);
|
||||||
buffer.set_string(area.x + area.width - 1, y, format!("┇"), style);
|
buffer.set_string(area.x + area.width - 1, y, format!("│"), style);
|
||||||
}
|
}
|
||||||
buffer.set_string(area.x, area.y + area.height - 1, bottom, style);
|
buffer.set_string(area.x, area.y + area.height - 1, bottom, style);
|
||||||
area
|
area
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue