Skip to content

Commit

Permalink
WIP, note edit commands
Browse files Browse the repository at this point in the history
Made Lane::edit_events compile, but it looks overly complicated.
  • Loading branch information
PetrGlad committed Oct 9, 2023
1 parent 8fc1436 commit b43017b
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ pub fn main() {
.value_parser(clap::value_parser!(std::path::PathBuf)),
)
.arg(
clap::arg!(--"input-file" <VALUE>)
clap::arg!(--"midi-file" <VALUE>)
.value_parser(clap::value_parser!(std::path::PathBuf))
.default_value("yellow.mid"),
)
.get_matches();
let config = Config::load(arg_matches.get_one::<std::path::PathBuf>("config-file"));

let midi_file_path = arg_matches
.get_one::<std::path::PathBuf>("input-file")
.get_one::<std::path::PathBuf>("midi-file")
.unwrap();
println!("MIDI file name {:?}", midi_file_path);
let mut project = Project::new(midi_file_path);
Expand Down
7 changes: 6 additions & 1 deletion src/midi_vst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ pub struct Vst {
}

impl Vst {
pub fn init(plugin_path: &String, sample_rate: &SampleRate, buffer_size: &FrameCount, preset_id: i32 ) -> Vst {
pub fn init(
plugin_path: &String,
sample_rate: &SampleRate,
buffer_size: &FrameCount,
preset_id: i32,
) -> Vst {
let sample_rate_f = sample_rate.0 as f32;
let path = Path::new(plugin_path);
println!("Loading {}", path.to_str().unwrap());
Expand Down
82 changes: 79 additions & 3 deletions src/stave.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ impl Stave {
self.draw_time_selection(
&painter,
&Stave::NOTHING_ZONE,
&Color32::from_black_alpha(20),
&Color32::from_black_alpha(15),
);
let track = self.track.read().expect("Cannot read track.");
for i in 0..track.events.len() {
Expand Down Expand Up @@ -333,7 +333,12 @@ impl Stave {
}
}

const KEYBOARD_TIME_STEP: StaveTime = 10_000;

fn handle_commands(&mut self, response: &Response) {
// Need to see if duplication here can be reduced...

// Tape insert/remove
if response.ctx.input(|i| i.key_pressed(Key::Delete)) {
let mut track = self.track.write().expect("Cannot write to track.");
if let Some(time_selection) = &self.time_selection {
Expand All @@ -347,19 +352,90 @@ impl Stave {
track.tape_insert(&time_selection.into());
}
}

// Tail shift
if response
.ctx
.input(|i| i.modifiers.ctrl && i.modifiers.shift && i.key_pressed(Key::ArrowRight))
{
let mut track = self.track.write().expect("Cannot write to track.");
track.shift_tail(&(self.cursor_position as TransportTime), 20_000);
track.shift_tail(
&(self.cursor_position as TransportTime),
Stave::KEYBOARD_TIME_STEP,
);
}
if response
.ctx
.input(|i| i.modifiers.ctrl && i.modifiers.shift && i.key_pressed(Key::ArrowLeft))
{
let mut track = self.track.write().expect("Cannot write to track.");
track.shift_tail(&(self.cursor_position as TransportTime), -20_000);
track.shift_tail(
&(self.cursor_position as TransportTime),
-Stave::KEYBOARD_TIME_STEP,
);
}

// Note time moves
if response
.ctx
.input(|i| i.modifiers.alt && i.modifiers.shift && i.key_pressed(Key::ArrowRight))
{
let mut track = self.track.write().expect("Cannot write to track.");
track.shift_events(
&(|ev| self.note_selection.contains(ev)),
Stave::KEYBOARD_TIME_STEP,
);
}
if response
.ctx
.input(|i| i.modifiers.alt && i.modifiers.shift && i.key_pressed(Key::ArrowLeft))
{
let mut track = self.track.write().expect("Cannot write to track.");
track.shift_events(
&(|ev| self.note_selection.contains(ev)),
-Stave::KEYBOARD_TIME_STEP,
);
}

// Note edits
if response.ctx.input(|i| i.key_pressed(Key::H)) {
let mut track = self.track.write().expect("Cannot write to track.");
// TODO Shorten note
Lane::edit_events(
&mut track.events,
&(|ev| {
if self.note_selection.contains(ev) {
if let LaneEventType::Note(note) = &mut ev.event {
Some(note)
} else {
None
}
} else {
None
}
}),
&(|note| note.duration += 123), // TODO Implement
);
}
if response.ctx.input(|i| i.key_pressed(Key::L)) {
let mut track = self.track.write().expect("Cannot write to track.");
// TODO Extend note
}
if response.ctx.input(|i| i.key_pressed(Key::I)) {
let mut track = self.track.write().expect("Cannot write to track.");
// TODO Move note a half tone up
}
if response.ctx.input(|i| i.key_pressed(Key::K)) {
let mut track = self.track.write().expect("Cannot write to track.");
// TODO Move note a half tone down
}
if response.ctx.input(|i| i.key_pressed(Key::I)) {
let mut track = self.track.write().expect("Cannot write to track.");
// TODO Increase velocity
}
if response.ctx.input(|i| i.key_pressed(Key::K)) {
let mut track = self.track.write().expect("Cannot write to track.");
// TODO Decrease velocity
}
}

Expand Down
21 changes: 19 additions & 2 deletions src/track.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use midly::{MidiMessage, TrackEvent, TrackEventKind};

use crate::engine::TransportTime;
use crate::midi;
use crate::stave::Stave;

pub type Pitch = u8;
pub type ControllerId = u8;
Expand Down Expand Up @@ -162,17 +161,35 @@ impl Lane {
self.shift_events(&|ev| &ev.at > at, dt);
}

fn shift_events<Pred: Fn(&LaneEvent) -> bool>(&mut self, selector: &Pred, d: i64) {
pub fn shift_events<Pred: Fn(&LaneEvent) -> bool>(&mut self, selector: &Pred, d: i64) {
for ev in &mut self.events {
if selector(ev) {
ev.at = ev
.at
.checked_add_signed(d)
// Need to show some visual feedback and just cancel the operation instead.
.expect("Should not shift event into negative times.");
}
}
}

pub fn edit_events<
'a,
T: 'a,
Selector: Fn(&'a mut LaneEvent) -> Option<&'a mut T>,
Action: Fn(&'a mut T),
>(
events: &'a mut Vec<LaneEvent>,
selector: &Selector,
action: &Action,
) {
for ev in events {
if let Some(x) = selector(ev) {
action(x);
}
}
}

pub fn delete_events(&mut self, event_ids: &HashSet<EventId>) {
self.version += 1;
self.events.retain(|ev| !event_ids.contains(&ev.id));
Expand Down

0 comments on commit b43017b

Please sign in to comment.