From c2eecac3b21a33a4dc590b36d0c80338437ce32b Mon Sep 17 00:00:00 2001 From: Franke Burgarino Date: Fri, 26 Sep 2025 16:26:15 -0500 Subject: [PATCH] Update strum logic Strumming now happens to notes that start at the same time, based on note value. Additionally, rather than moving notes, the start times get moved so that they end at the same time. Any notes that get cut down to nothing (or less) are given a length of one tick while maintaining the same end time. --- libs/ardour/strum.cc | 51 +++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/libs/ardour/strum.cc b/libs/ardour/strum.cc index 4bc8e3c48d..67c0e248b6 100644 --- a/libs/ardour/strum.cc +++ b/libs/ardour/strum.cc @@ -51,11 +51,20 @@ Strum::operator()(std::shared_ptr model, return cmd; } - // Sort notes by start time - std::sort(all_notes.begin(), all_notes.end(), - [](const NotePtr& a, const NotePtr& b) { - return a->time() < b->time(); - }); + bool forward = _forward; + + // Sort notes + std::sort(all_notes.begin(), all_notes.end(), [forward](const NotePtr& a, const NotePtr& b) { + if (a->time() == b->time()) { + if (forward) { + return a->note() < b->note(); + } else { + return a->note() > b->note(); + } + } else { + return a->time() < b->time(); + } + }); Temporal::Beats total_offset; Temporal::Beats offset; @@ -66,20 +75,28 @@ Strum::operator()(std::shared_ptr model, offset = Temporal::Beats::ticks(Temporal::ticks_per_beat / 32); } - if (_forward) { - for (std::vector::const_iterator i = all_notes.begin(); i != all_notes.end(); ++i) { - const NotePtr note = *i; - Temporal::Beats new_start = note->time() + total_offset; - cmd->change(note, MidiModel::NoteDiffCommand::StartTime, new_start); - total_offset += offset; + Temporal::Beats prev_time = all_notes.at(0)->time(); + + for (std::vector::const_iterator i = all_notes.begin(); i != all_notes.end(); ++i) { + const NotePtr note = *i; + std::cout << (*i)->note() << std::endl; + if ((*i)->time() != prev_time) { + total_offset = 0; } - } else { // backward - for (std::vector::const_reverse_iterator i = all_notes.rbegin(); i != all_notes.rend(); ++i) { - const NotePtr note = *i; - Temporal::Beats new_start = note->time() + total_offset; - cmd->change(note, MidiModel::NoteDiffCommand::StartTime, new_start); - total_offset += offset; + + Temporal::Beats new_start; + Temporal::Beats new_length = note->length() - total_offset; + if (new_length <= Temporal::Beats::ticks(0)) { + new_start = note->end_time() - Temporal::Beats::ticks(1); + new_length = Temporal::Beats::ticks(1); + } else { + new_start = note->time() + total_offset; } + + cmd->change(note, MidiModel::NoteDiffCommand::StartTime, new_start); + cmd->change(note, MidiModel::NoteDiffCommand::Length, new_length); + total_offset += offset; + prev_time = (*i)->time(); } return cmd;