From be2c2df92bc2913c18a6102b4edf2c10df919160 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Fri, 21 Jun 2024 13:32:20 +0300 Subject: [PATCH] transport master --- Cargo.toml | 1 + src/device/plugin.rs | 8 +-- src/device/sequencer.rs | 134 +++++++++++++++++++++++----------------- src/layout/container.rs | 4 +- 4 files changed, 85 insertions(+), 62 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index afbaef27..7d1df00c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,4 @@ midly = "0.5" vst = "0.4.0" #vst3 = "0.1.0" livi = "0.7.4" +#atomic_enum = "0.3.0" diff --git a/src/device/plugin.rs b/src/device/plugin.rs index fae54cab..21c07caf 100644 --- a/src/device/plugin.rs +++ b/src/device/plugin.rs @@ -44,21 +44,21 @@ pub fn render (state: &Plugin, buf: &mut Buffer, Rect { x, y, .. }: Rect) let style = Style::default().gray(); 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 + 0, y + 2, &format!("├--------------------------------------┤"), style.dim()); + buf.set_string(x + 0, y + 2, &format!("├------------------------------------------------┤"), style.dim()); match &state.plugin { Some(PluginKind::LV2(ports, instance)) => { let mut height = 3; for (i, port) in ports.iter().skip(state.parameter_offset).enumerate() { - if i >= 10 { + if i >= 20 { 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.default_value ), Style::default()); 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); diff --git a/src/device/sequencer.rs b/src/device/sequencer.rs index db6ae117..c70d6edd 100644 --- a/src/device/sequencer.rs +++ b/src/device/sequencer.rs @@ -88,17 +88,18 @@ impl Sequencer { } fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control { - process_out(self, scope); - process_in(self, scope); + let transport = self.transport.query().unwrap(); + process_out(self, scope, &transport); + process_in(self, scope, &transport); Control::Continue } } -fn process_in (s: &mut Sequencer, scope: &ProcessScope) { +fn process_in (s: &mut Sequencer, scope: &ProcessScope, transport: &::jack::TransportStatePosition) { if !s.recording { return } - let pos = s.transport.query().unwrap().pos; + let pos = &transport.pos; let usecs = s.timebase.frame_to_usec(pos.frame() as usize); let steps = usecs / s.timebase.usec_per_step(s.resolution as usize); 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 { return } - let transport = s.transport.query().unwrap(); if transport.state != ::jack::TransportState::Rolling { return } @@ -196,7 +196,7 @@ fn render (s: &Sequencer, buf: &mut Buffer, mut area: Rect) -> Usually { SequencerView::Horizontal => draw_horizontal(s, buf, Rect { x, y: y + header.height, - width: 3 + time1 - time0, + width: area.width.max(3 + time1 - time0), 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 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 + 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, //&format!("▶ PLAY"), if s.playing { //Style::default().green() @@ -225,14 +230,20 @@ fn draw_header (s: &Sequencer, buf: &mut Buffer, area: Rect, beat: usize) -> Usu //Style::default().dim() //}); buf.set_string(x + 10, y + 1, - &format!("⏺ REC"), if s.recording { - Style::default().red() + &format!("⏺ MON"), if s.monitoring { + Style::default().bold().green() } else { Style::default().bold().dim() }); 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 { - Style::default().yellow() + Style::default().bold().yellow() } else { 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 { let Rect { x, y, .. } = area; let style = Style::default().gray(); - buf.set_string(x + 2, y + 3, &format!("▶ {}", &s.name), style.not_dim().bold()); - buf.set_string(x + 2, y + 5, &format!("⏺ {}", &s.name), style.dim()); - buf.set_string(x + 2, y + 7, &format!("⏺ {}", &s.name), style.dim()); - buf.set_string(x + 2, y + 9, &format!("⏺ {}", &s.name), style.dim()); - buf.set_string(x + 2, y + 11, &format!("⏺ {}", &s.name), style.dim()); - buf.set_string(x + 2, y + 13, &format!("⏺ {}", &s.name), style.dim()); - buf.set_string(x + 2, y + 15, &format!("⏺ {}", &s.name), style.dim()); - buf.set_string(x + 2, y + 17, &format!("⏺ {}", &s.name), style.dim()); + for i in 0..8 { + buf.set_string(x + 2, y + 3 + i*2, &format!("▶ {}", &s.name), if i as usize == s.sequence { + if s.playing { + style.white().bold() + } else { + style.not_dim().bold() + } + } else { + style.dim() + }); + } 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 { "▄" }, 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 { @@ -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 { area.x = area.x + 13; - let Rect { x, y, .. } = area; + let Rect { x, y, width, .. } = area; let (time0, time1) = s.time_axis; let (note0, note1) = s.note_axis; 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; - buf.set_string(x + 2, y + height, format!( - " Q 1/{} | N {} ({}-{}) | T {} ({}-{})", + buf.set_string(x - 13, y + height, format!("├{}┤", "-".repeat((width - 2).into())), + Style::default().dim()); + buf.set_string(x - 11, y + height + 1, format!( + "Sync 4/4 Quantize 1/{} Notes {} ({}-{}) Time {} ({}-{})", 4 * s.resolution, s.note_axis.0 + s.note_cursor, 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 + 1, s.time_axis.1, - ), Style::default().dim()); + ), Style::default().not_dim()); buf.set_string( x + 6 + s.time_cursor, y + s.note_cursor / 2, @@ -448,7 +464,7 @@ fn draw_horizontal (s: &Sequencer, buf: &mut Buffer, mut area: Rect) -> Usually< x: x - 13, y, width: time1 - time0 + 19, - height: height + 2 + height: height + 3 }) } @@ -457,37 +473,37 @@ pub fn handle (s: &mut Sequencer, event: &AppEvent) -> Usually { } pub const KEYMAP: &'static [KeyBinding] = keymap!(Sequencer { - [Up, NONE, "cursor_up", "move cursor up", cursor_up], - [Down, NONE, "cursor_down", "move cursor down", cursor_down], - [Left, NONE, "cursor_left", "move cursor left", cursor_left], - [Right, NONE, "cursor_right", "move cursor right", cursor_right], - [Char(']'), NONE, "cursor_inc", "increase note duration", cursor_duration_inc], - [Char('['), NONE, "cursor_dec", "decrease note duration", cursor_duration_dec], - [Char('`'), NONE, "mode_next", "Next view mode", mode_next], - [Char('+'), NONE, "zoom_in", "Zoom in", nop], - [Char('-'), NONE, "zoom_out", "Zoom out", nop], - [Char('a'), NONE, "note_add", "Add note", note_add], - [Char('d'), NONE, "note_del", "Delete note", note_del], - [CapsLock, NONE, "advance", "Toggle auto advance", nop], - [Char('w'), NONE, "rest", "Advance by note duration", nop], - [Char('r'), NONE, "record", "Toggle recodring", toggle_record], - [Char('o'), NONE, "overdub", "Toggle overdub", toggle_overdub], - [Char('p'), NONE, "play", "Toggle play/pause", toggle_play], - [Char('s'), NONE, "stop", "Stop and rewind", stop_and_rewind], - [Char('q'), NONE, "quantize_next", "Next quantize value", quantize_next], - [Char('Q'), SHIFT, "quantize_prev", "Previous quantize value", quantize_prev], - [Char('n'), NONE, "note_axis", "Focus note axis", nop], - [Char('t'), NONE, "time_axis", "Focus time axis", nop], - [Char('v'), NONE, "variations", "Focus variation selector", nop], - [Char('s'), SHIFT, "sync", "Focus sync selector", nop], - [Char('1'), NONE, "focus_1", "Sequence 1", focus_seq(0)], - [Char('2'), NONE, "focus_1", "Sequence 1", focus_seq(1)], - [Char('3'), NONE, "focus_1", "Sequence 1", focus_seq(2)], - [Char('4'), NONE, "focus_1", "Sequence 1", focus_seq(3)], - [Char('5'), NONE, "focus_1", "Sequence 1", focus_seq(4)], - [Char('6'), NONE, "focus_1", "Sequence 1", focus_seq(5)], - [Char('7'), NONE, "focus_1", "Sequence 1", focus_seq(6)], - [Char('8'), NONE, "focus_1", "Sequence 1", focus_seq(7)], + [Up, NONE, "cursor_up", "move cursor up", cursor_up], + [Down, NONE, "cursor_down", "move cursor down", cursor_down], + [Left, NONE, "cursor_left", "move cursor left", cursor_left], + [Right, NONE, "cursor_right", "move cursor right", cursor_right], + [Char(']'), NONE, "cursor_inc", "increase note duration", cursor_duration_inc], + [Char('['), NONE, "cursor_dec", "decrease note duration", cursor_duration_dec], + [Char('`'), NONE, "mode_next", "Next view mode", mode_next], + [Char('+'), NONE, "zoom_in", "Zoom in", nop], + [Char('-'), NONE, "zoom_out", "Zoom out", nop], + [Char('a'), NONE, "note_add", "Add note", note_add], + [Char('z'), NONE, "note_del", "Delete note", note_del], + [CapsLock, NONE, "advance", "Toggle auto advance", nop], + [Char('w'), NONE, "rest", "Advance by note duration", nop], + [Char('r'), NONE, "toggle_record", "Toggle recording", toggle_record], + [Char('d'), NONE, "toggle_overdub", "Toggle overdub", toggle_overdub], + [Char(' '), NONE, "toggle_play", "Toggle play/pause", toggle_play], + [Char('s'), NONE, "stop_and_rewind", "Stop and rewind", stop_and_rewind], + [Char('q'), NONE, "quantize_next", "Next quantize value", quantize_next], + [Char('Q'), SHIFT, "quantize_prev", "Previous quantize value", quantize_prev], + [Char('n'), NONE, "note_axis", "Focus note axis", nop], + [Char('t'), NONE, "time_axis", "Focus time axis", nop], + [Char('v'), NONE, "variations", "Focus variation selector", nop], + [Char('s'), SHIFT, "sync", "Focus sync selector", nop], + [Char('1'), NONE, "seq_1", "Sequence 1", focus_seq(0)], + [Char('2'), NONE, "seq_2", "Sequence 2", focus_seq(1)], + [Char('3'), NONE, "seq_3", "Sequence 3", focus_seq(2)], + [Char('4'), NONE, "seq_4", "Sequence 4", focus_seq(3)], + [Char('5'), NONE, "seq_5", "Sequence 5", focus_seq(4)], + [Char('6'), NONE, "seq_6", "Sequence 6", focus_seq(5)], + [Char('7'), NONE, "seq_7", "Sequence 7", focus_seq(6)], + [Char('8'), NONE, "seq_8", "Sequence 8", focus_seq(7)], }); const fn focus_seq (i: usize) -> impl Fn(&mut Sequencer)->Usually { @@ -605,6 +621,12 @@ fn stop_and_rewind (s: &mut Sequencer) -> Usually { } fn toggle_play (s: &mut Sequencer) -> Usually { s.playing = !s.playing; + if s.playing { + s.transport.start()?; + } else { + s.transport.stop()?; + s.transport.locate(0)?; + } Ok(true) } fn toggle_record (s: &mut Sequencer) -> Usually { diff --git a/src/layout/container.rs b/src/layout/container.rs index 0a85e8d1..a4a49026 100644 --- a/src/layout/container.rs +++ b/src/layout/container.rs @@ -25,8 +25,8 @@ pub fn draw_box_styled (buffer: &mut Buffer, area: Rect, style: Option