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
This commit is contained in:
parent
438bd7a720
commit
f95e94bc29
|
@ -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-channels| c|Edit Note Channels
|
||||||
@notes|Notes/edit-velocities| v|Edit Note Velocities
|
@notes|Notes/edit-velocities| v|Edit Note Velocities
|
||||||
@notes|Notes/split-notes-grid| <@PRIMARY@>e|Split Notes By Grid
|
@notes|Notes/split-notes-grid| <@PRIMARY@>e|Split Notes By Grid
|
||||||
@notes|Notes/join-notes| <@PRIMARY@>j|Join Notes
|
@notes|Notes/join-notes| j|Join Notes
|
||||||
@notes|Notes/split-notes-more| <@PRIMARY@>Up|Split Notes More Finely
|
@notes|Notes/split-notes-more| s|Split Notes More Finely
|
||||||
@notes|Notes/split-notes-less| <@PRIMARY@>Down|Split Notes Less 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-up-octave| <@SECONDARY@>Up|Transpose up (1 octave)
|
||||||
@notes|Notes/transpose-down-octave| <@SECONDARY@>Down|Transpose down (1 octave)
|
@notes|Notes/transpose-down-octave| <@SECONDARY@>Down|Transpose down (1 octave)
|
||||||
|
|
|
@ -2248,6 +2248,7 @@ MidiRegionView::clear_selection ()
|
||||||
{
|
{
|
||||||
clear_note_selection ();
|
clear_note_selection ();
|
||||||
_mouse_state = None;
|
_mouse_state = None;
|
||||||
|
end_note_splitting ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -4777,6 +4778,7 @@ MidiRegionView::sync_velocity_drag (double factor)
|
||||||
void
|
void
|
||||||
MidiRegionView::start_note_splitting ()
|
MidiRegionView::start_note_splitting ()
|
||||||
{
|
{
|
||||||
|
note_splitting = true;
|
||||||
split_info.clear ();
|
split_info.clear ();
|
||||||
|
|
||||||
for (auto & s : _selection) {
|
for (auto & s : _selection) {
|
||||||
|
@ -4789,12 +4791,15 @@ MidiRegionView::start_note_splitting ()
|
||||||
base->velocity(),
|
base->velocity(),
|
||||||
base->off_velocity()));
|
base->off_velocity()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
split_tuple = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MidiRegionView::end_note_splitting ()
|
MidiRegionView::end_note_splitting ()
|
||||||
{
|
{
|
||||||
split_info.clear ();
|
split_info.clear ();
|
||||||
|
note_splitting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -4859,7 +4864,7 @@ MidiRegionView::split_notes_less ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (split_tuple <= 2) {
|
if (split_tuple < 2) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4880,6 +4885,53 @@ MidiRegionView::split_notes_less ()
|
||||||
void
|
void
|
||||||
MidiRegionView::join_notes ()
|
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<Temporal::Beats,Temporal::Beats> 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<Temporal::Beats>::max();
|
||||||
|
cnt[n] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto & s : _selection) {
|
||||||
|
|
||||||
|
std::shared_ptr<NoteType> 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<NoteType> 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
|
void
|
||||||
|
|
Loading…
Reference in New Issue