From ed926b94442f20aee68b181b7542978a60534e10 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sun, 11 May 2025 19:17:55 +0300 Subject: [PATCH 1/7] view: expose scene iterator types --- crates/app/src/view.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/app/src/view.rs b/crates/app/src/view.rs index 21743eb7..c6b55c84 100644 --- a/crates/app/src/view.rs +++ b/crates/app/src/view.rs @@ -571,9 +571,13 @@ impl<'a> ArrangerView<'a> { } -trait ScenesColors<'a> = Iterator>; +/// Iterator over scenes with their sizes and colors. +pub(crate) trait ScenesColors<'a> = + Iterator>; -type SceneWithColor<'a> = (usize, &'a Scene, usize, usize, Option); +/// A scene with size and color. +pub(crate) type SceneWithColor<'a> = + (usize, &'a Scene, usize, usize, Option); /// Define a type alias for iterators of sized items (columns). macro_rules! def_sizes_iter { From d647fc68e942300c6ba0109633df32ad4fe87581 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sun, 11 May 2025 19:18:19 +0300 Subject: [PATCH 2/7] just: connect to all firefox jack outputs --- Justfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Justfile b/Justfile index f86ae529..5ecece41 100644 --- a/Justfile +++ b/Justfile @@ -6,7 +6,7 @@ midi-in := "-i 'Midi-Bridge:.*nanoKEY.*:.*capture.*'" midi-out := "-o 'Midi-Bridge:.*playback.*'" audio-in := "-l 'Komplete Audio 6 Pro:capture_AUX1' -r 'Komplete Audio 6 Pro:capture_AUX1'" audio-out := "-L 'Komplete Audio 6 Pro:playback_AUX1' -R 'Komplete Audio 6 Pro:playback_AUX1'" -firefox-in := "-l 'Firefox:output_FL' -r 'Firefox:output_FR'" +firefox-in := "-l 'Firefox:output_FL*' -r 'Firefox:output_FR*'" covfig := "CARGO_INCREMENTAL=0 RUSTFLAGS='-Cinstrument-coverage' RUSTDOCFLAGS='-Cinstrument-coverage' LLVM_PROFILE_FILE='cov/cargo-test-%p-%m.profraw'" grcov-binary := "--binary-path ./target/coverage/deps/" grcov-ignore := "--ignore-not-existing --ignore '../*' --ignore \"/*\" --ignore 'target/*'" @@ -71,6 +71,8 @@ groovebox: groovebox-ext: reset {{debug}} {{name}} {{bpm}} {{midi-in}} {{midi-out}} {{audio-in}} {{audio-out}} groovebox +groovebox-browser: + {{debug}} {{name}} {{bpm}} {{audio-in}} groovebox groovebox-release: {{release}} {{name}} {{bpm}} groovebox groovebox-release-ext: From d1be569b487ebbd19eb6851f3c227d43d11c8623 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sun, 11 May 2025 19:19:14 +0300 Subject: [PATCH 3/7] editor: add fine time step and overflow --- config/keys_editor.edn | 2 ++ crates/device/src/editor/editor_api.rs | 17 +++++++++++++++-- crates/device/src/editor/editor_model.rs | 2 +- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/config/keys_editor.edn b/config/keys_editor.edn index 64523ac7..a99ec7e5 100644 --- a/config/keys_editor.edn +++ b/config/keys_editor.edn @@ -1,5 +1,7 @@ (@left editor set-time-pos :time-pos-prev) +(@shift-left editor set-time-pos :time-pos-prev-fine) (@right editor set-time-pos :time-pos-next) +(@shift-right editor set-time-pos :time-pos-next-fine) (@equal editor set-time-zoom :time-zoom-prev) (@minus editor set-time-zoom :time-zoom-next) diff --git a/crates/device/src/editor/editor_api.rs b/crates/device/src/editor/editor_api.rs index 85748cae..3ef47b0b 100644 --- a/crates/device/src/editor/editor_api.rs +++ b/crates/device/src/editor/editor_api.rs @@ -5,6 +5,10 @@ use crate::*; todo!() } + fn clip_length (&self) -> usize { + self.clip().as_ref().map(|p|p.read().unwrap().length).unwrap_or(1) + } + fn note_length (&self) -> usize { self.get_note_len() } @@ -49,10 +53,19 @@ use crate::*; self.get_time_pos() } fn time_pos_next (&self) -> usize { - self.get_time_pos() + self.get_note_len() + (self.get_time_pos() + self.get_note_len()) % self.clip_length() + } + fn time_pos_next_fine (&self) -> usize { + (self.get_time_pos() + 1) % self.clip_length() } fn time_pos_prev (&self) -> usize { - self.get_time_pos().saturating_sub(self.get_note_len()) + let step = self.get_note_len(); + self.get_time_pos().overflowing_sub(step) + .0.min(self.clip_length().saturating_sub(step)) + } + fn time_pos_prev_fine (&self) -> usize { + self.get_time_pos().overflowing_sub(1) + .0.min(self.clip_length().saturating_sub(1)) } fn time_zoom (&self) -> usize { diff --git a/crates/device/src/editor/editor_model.rs b/crates/device/src/editor/editor_model.rs index 90d6d2ee..2f533490 100644 --- a/crates/device/src/editor/editor_model.rs +++ b/crates/device/src/editor/editor_model.rs @@ -61,7 +61,7 @@ impl MidiEditor { clip.notes[note_end].push(note_off); } if advance { - self.set_time_pos(note_end + 1); + self.set_time_pos((note_end + 1) % clip.length); } redraw = true; } From decbb177f0ca513556526592582e5798776fabdc Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sun, 11 May 2025 19:20:44 +0300 Subject: [PATCH 4/7] editor: move status bars to editor_view --- crates/device/src/editor/editor_model.rs | 27 --------------------- crates/device/src/editor/editor_view.rs | 31 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/crates/device/src/editor/editor_model.rs b/crates/device/src/editor/editor_model.rs index 2f533490..648e70c5 100644 --- a/crates/device/src/editor/editor_model.rs +++ b/crates/device/src/editor/editor_model.rs @@ -69,33 +69,6 @@ impl MidiEditor { self.mode.redraw(); } } - - pub fn clip_status (&self) -> impl Content + '_ { - let (color, name, length, looped) = if let Some(clip) = self.clip().as_ref().map(|p|p.read().unwrap()) { - (clip.color, clip.name.clone(), clip.length, clip.looped) - } else { (ItemTheme::G[64], String::new().into(), 0, false) }; - Bsp::e( - FieldH(color, "Edit", format!("{name} ({length})")), - FieldH(color, "Loop", looped.to_string()) - ) - } - - pub fn edit_status (&self) -> impl Content + '_ { - let (color, length) = if let Some(clip) = self.clip().as_ref().map(|p|p.read().unwrap()) { - (clip.color, clip.length) - } else { (ItemTheme::G[64], 0) }; - let time_pos = self.get_time_pos(); - let time_zoom = self.get_time_zoom(); - let time_lock = if self.get_time_lock() { "[lock]" } else { " " }; - let note_pos = self.get_note_pos(); - let note_name = format!("{:4}", Note::pitch_to_name(note_pos)); - let note_pos = format!("{:>3}", note_pos); - let note_len = format!("{:>4}", self.get_note_len()); - Bsp::e( - FieldH(color, "Time", format!("{length}/{time_zoom}+{time_pos} {time_lock}")), - FieldH(color, "Note", format!("{note_name} {note_pos} {note_len}")), - ) - } } impl TimeRange for MidiEditor { diff --git a/crates/device/src/editor/editor_view.rs b/crates/device/src/editor/editor_view.rs index 9a7e4f48..7828d416 100644 --- a/crates/device/src/editor/editor_view.rs +++ b/crates/device/src/editor/editor_view.rs @@ -7,3 +7,34 @@ content!(TuiOut: |self: MidiEditor| { //self.autozoom(); self.size.of(&self.mode) }); + +impl MidiEditor { + + pub fn clip_status (&self) -> impl Content + '_ { + let (color, name, length, looped) = if let Some(clip) = self.clip().as_ref().map(|p|p.read().unwrap()) { + (clip.color, clip.name.clone(), clip.length, clip.looped) + } else { (ItemTheme::G[64], String::new().into(), 0, false) }; + Bsp::e( + FieldH(color, "Edit", format!("{name} ({length})")), + FieldH(color, "Loop", looped.to_string()) + ) + } + + pub fn edit_status (&self) -> impl Content + '_ { + let (color, length) = if let Some(clip) = self.clip().as_ref().map(|p|p.read().unwrap()) { + (clip.color, clip.length) + } else { (ItemTheme::G[64], 0) }; + let time_pos = self.get_time_pos(); + let time_zoom = self.get_time_zoom(); + let time_lock = if self.get_time_lock() { "[lock]" } else { " " }; + let note_pos = self.get_note_pos(); + let note_name = format!("{:4}", Note::pitch_to_name(note_pos)); + let note_pos = format!("{:>3}", note_pos); + let note_len = format!("{:>4}", self.get_note_len()); + Bsp::e( + FieldH(color, "Time", format!("{length}/{time_zoom}+{time_pos} {time_lock}")), + FieldH(color, "Note", format!("{note_name} {note_pos} {note_len}")), + ) + } + +} From ea48dd6fa1d1e5907458a32ab70ba6e635089b58 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sun, 11 May 2025 19:20:58 +0300 Subject: [PATCH 5/7] sampler: wip: add play_sample and stop_sample --- config/keys_sampler.edn | 2 ++ crates/device/src/sampler/sampler_api.rs | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/config/keys_sampler.edn b/config/keys_sampler.edn index 036342a0..0e8aa127 100644 --- a/config/keys_sampler.edn +++ b/config/keys_sampler.edn @@ -4,3 +4,5 @@ (@right sampler select :sample-to-right) (@r sampler record-toggle :sample-selected) (@shift-R sampler record-cancel) +(@p sampler play-sample :sample-selected) +(@P sampler stop-sample :sample-selected) diff --git a/crates/device/src/sampler/sampler_api.rs b/crates/device/src/sampler/sampler_api.rs index f490350e..514ccf5f 100644 --- a/crates/device/src/sampler/sampler_api.rs +++ b/crates/device/src/sampler/sampler_api.rs @@ -81,6 +81,16 @@ impl SamplerCommand { sampler.recording = None; Ok(None) } + fn play_sample (sampler: &mut Sampler, pitch: usize) -> Perhaps { + if let Some(ref sample) = sampler.mapped[pitch] { + sampler.voices.write().unwrap().push(Sample::play(sample, 0, &u7::from(128))); + } + Ok(None) + } + fn stop_sample (sampler: &mut Sampler, pitch: usize) -> Perhaps { + todo!(); + Ok(None) + } //fn select (&self, state: &mut Sampler, i: usize) -> Option { //Self::Select(state.set_note_pos(i)) //} From e81ae58ab51776e24cd5b26eb509cfe45f43295a Mon Sep 17 00:00:00 2001 From: unspeaker Date: Mon, 12 May 2025 01:16:11 +0300 Subject: [PATCH 6/7] fix: midi_froms -> midi_tos --- crates/app/src/model/track.rs | 4 +--- crates/cli/tek.rs | 14 ++++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/app/src/model/track.rs b/crates/app/src/model/track.rs index 959238d8..15625395 100644 --- a/crates/app/src/model/track.rs +++ b/crates/app/src/model/track.rs @@ -58,9 +58,7 @@ impl Track { audio_from: &[&[PortConnect];2], audio_to: &[&[PortConnect];2], ) -> Usually { - let mut track = Self::new( - name, color, jack, clock, clip, midi_from, midi_to - )?; + let mut track = Self::new(name, color, jack, clock, clip, midi_from, midi_to)?; track.devices.push(Device::Sampler(Sampler::new( jack, &format!("{}/sampler", name.as_ref()), diff --git a/crates/cli/tek.rs b/crates/cli/tek.rs index 1e303f23..3f7fdfcb 100644 --- a/crates/cli/tek.rs +++ b/crates/cli/tek.rs @@ -128,11 +128,13 @@ impl Cli { midi_ins, midi_outs, midi_buf: match mode { - LaunchMode::Clock - | LaunchMode::Sampler => vec![], - LaunchMode::Sequencer - | LaunchMode::Groovebox - | LaunchMode::Arranger {..} => vec![vec![];65536], + LaunchMode::Clock | + LaunchMode::Sampler => + vec![], + LaunchMode::Sequencer | + LaunchMode::Groovebox | + LaunchMode::Arranger {..} => + vec![vec![];65536], _ => todo!("{mode:?}"), }, tracks: match mode { @@ -155,7 +157,7 @@ impl Cli { Some(&clock), clip.as_ref(), midi_froms.as_slice(), - midi_froms.as_slice(), + midi_tos.as_slice(), audio_froms, audio_tos, )? From 6f6078e25a8625373287c40d780d340895c51a32 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Mon, 12 May 2025 01:17:21 +0300 Subject: [PATCH 7/7] track: remove unused fields --- crates/app/src/model/track.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/crates/app/src/model/track.rs b/crates/app/src/model/track.rs index 15625395..a94e5b0f 100644 --- a/crates/app/src/model/track.rs +++ b/crates/app/src/model/track.rs @@ -2,19 +2,15 @@ use crate::*; #[derive(Debug, Default)] pub struct Track { /// Name of track - pub name: Arc, - /// Preferred width of track column - pub width: usize, + pub name: Arc, /// Identifying color of track - pub color: ItemTheme, + pub color: ItemTheme, + /// Preferred width of track column + pub width: usize, /// MIDI sequencer state - pub sequencer: Sequencer, + pub sequencer: Sequencer, /// Device chain - pub devices: Vec, - /// Inputs of 1st device - pub audio_ins: Vec, - /// Outputs of last device - pub audio_outs: Vec, + pub devices: Vec, } has_clock!(|self: Track|self.sequencer.clock);