From f95e94bc29aeac99b9893549648e5d4571cf6ec2 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 23 Nov 2023 22:41:39 -0700 Subject: [PATCH] note tupling tweaks, and note join added bindings moved to s/S and j, no need to use split-by-grid first split-by-grid still needs work for non-grid aligned notes --- gtk2_ardour/ardour.keys.in | 6 ++-- gtk2_ardour/midi_region_view.cc | 54 ++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/gtk2_ardour/ardour.keys.in b/gtk2_ardour/ardour.keys.in index e6591efa07..461e2943d6 100644 --- a/gtk2_ardour/ardour.keys.in +++ b/gtk2_ardour/ardour.keys.in @@ -471,9 +471,9 @@ This mode provides many different operations on both regions and control points, @notes|Notes/edit-channels| c|Edit Note Channels @notes|Notes/edit-velocities| v|Edit Note Velocities @notes|Notes/split-notes-grid| <@PRIMARY@>e|Split Notes By Grid -@notes|Notes/join-notes| <@PRIMARY@>j|Join Notes -@notes|Notes/split-notes-more| <@PRIMARY@>Up|Split Notes More Finely -@notes|Notes/split-notes-less| <@PRIMARY@>Down|Split Notes Less Finely +@notes|Notes/join-notes| j|Join Notes +@notes|Notes/split-notes-more| s|Split Notes More Finely +@notes|Notes/split-notes-less| <@TERTIARY@>s|Split Notes Less Finely @notes|Notes/transpose-up-octave| <@SECONDARY@>Up|Transpose up (1 octave) @notes|Notes/transpose-down-octave| <@SECONDARY@>Down|Transpose down (1 octave) diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 09ce36f256..80edccbb1f 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -2248,6 +2248,7 @@ MidiRegionView::clear_selection () { clear_note_selection (); _mouse_state = None; + end_note_splitting (); } void @@ -4777,6 +4778,7 @@ MidiRegionView::sync_velocity_drag (double factor) void MidiRegionView::start_note_splitting () { + note_splitting = true; split_info.clear (); for (auto & s : _selection) { @@ -4789,12 +4791,15 @@ MidiRegionView::start_note_splitting () base->velocity(), base->off_velocity())); } + + split_tuple = 1; } void MidiRegionView::end_note_splitting () { split_info.clear (); + note_splitting = false; } void @@ -4859,7 +4864,7 @@ MidiRegionView::split_notes_less () } } - if (split_tuple <= 2) { + if (split_tuple < 2) { return; } @@ -4880,6 +4885,53 @@ MidiRegionView::split_notes_less () void MidiRegionView::join_notes () { + /* Grab the selection, split it by pitch and find the earliest and + * latest contiguous segments of the same pitch + */ + + typedef std::pair StartAndEnd; + StartAndEnd starts_and_ends[127]; + uint32_t cnt[127]; + + for (size_t n = 0; n < 127; ++n) { + starts_and_ends[n].first = std::numeric_limits::max(); + cnt[n] = 0; + } + + for (auto & s : _selection) { + + std::shared_ptr base (s->note()); + StartAndEnd& se (starts_and_ends[base->note()]); + cnt[base->note()]++; + + if (base->time() < se.first) { + se.first = base->time(); + } + + if (base->end_time() > se.second) { + se.second = base->end_time(); + } + } + + start_note_diff_command (_("join notes")); + for (auto & s : _selection) { + /* Only remove pitches that occur more than once */ + if (cnt[s->note()->note()] > 1) { + note_diff_remove_note (s); + } + } + + for (size_t n = 0; n < 127; ++n) { + if (cnt[n] > 1 && starts_and_ends[n].second != Temporal::Beats()) { + Temporal::Beats b = starts_and_ends[n].second - starts_and_ends[n].first; + std::shared_ptr new_note (new NoteType (0, starts_and_ends[n].first, b, n, 64)); + note_diff_add_note (new_note, true, true); + } + } + + apply_note_diff (false); + + end_note_splitting (); } void