Step-edit: improve overlapping note handling

* no need to shift notes during normal edit
* prevent duplicate (overlapping) chord notes
This commit is contained in:
Robin Gareus 2025-03-04 17:07:16 +01:00
parent e35b9f8a3e
commit 34a4eea0d5
No known key found for this signature in database
GPG key ID: A090BCE02CF57F04
2 changed files with 31 additions and 26 deletions

View file

@ -66,9 +66,9 @@ StepEditor::start_step_editing ()
_step_edit_chord_duration = Temporal::Beats();
step_edit_region.reset ();
step_edit_region_view = 0;
last_added_pitch = -1;
last_added_end = Temporal::Beats();
_last_added_beat = Temporal::Beats();
_tracker.reset ();
_chord_tracker.reset ();
resync_step_edit_position ();
prepare_step_edit_region ();
@ -212,10 +212,7 @@ StepEditor::check_step_edit ()
/* note-off w/chord .. move to next beat */
if ((buf[0] & 0xf0) == MIDI_CMD_NOTE_OFF && size == 3 && _tracker.empty ()) {
if (step_edit_region_view && _step_edit_within_chord) {
step_edit_beat_pos += _step_edit_chord_duration;
step_edit_region_view->move_step_edit_cursor (step_edit_beat_pos);
}
step_to_next_chord ();
}
}
delete [] buf;
@ -303,20 +300,18 @@ StepEditor::step_add_note (uint8_t channel, uint8_t pitch, uint8_t velocity, Tem
Temporal::Beats at = step_edit_beat_pos;
Temporal::Beats len = beat_duration;
if ((last_added_pitch >= 0) && (pitch == last_added_pitch) && (last_added_end == step_edit_beat_pos)) {
/* avoid any apparent note overlap - move the start of this note
up by 1 tick from where the last note ended
*/
at += Temporal::Beats::ticks(1);
len -= Temporal::Beats::ticks(1);
if (_last_added_beat != step_edit_beat_pos) {
_chord_tracker.reset ();
_last_added_beat = step_edit_beat_pos;
}
step_edit_region_view->step_add_note (channel, pitch, velocity, at, len);
if (!_step_edit_within_chord || !_chord_tracker.active (pitch, channel)) {
step_edit_region_view->step_add_note (channel, pitch, velocity, at, len);
}
last_added_pitch = pitch;
last_added_end = at+len;
if (_step_edit_within_chord) {
_chord_tracker.add (pitch, channel);
}
if (_step_edit_triplet_countdown > 0) {
_step_edit_triplet_countdown--;
@ -330,7 +325,6 @@ StepEditor::step_add_note (uint8_t channel, uint8_t pitch, uint8_t velocity, Tem
step_edit_beat_pos += beat_duration;
step_edit_region_view->move_step_edit_cursor (step_edit_beat_pos);
} else {
step_edit_beat_pos += Temporal::Beats::ticks(1); // tiny, but no longer overlapping
_step_edit_chord_duration = max (_step_edit_chord_duration, beat_duration);
}
@ -339,6 +333,17 @@ StepEditor::step_add_note (uint8_t channel, uint8_t pitch, uint8_t velocity, Tem
return 0;
}
void
StepEditor::step_to_next_chord ()
{
if (!step_edit_region_view || !_step_edit_within_chord) {
return;
}
step_edit_beat_pos += _step_edit_chord_duration;
step_edit_region_view->move_step_edit_cursor (step_edit_beat_pos);
_chord_tracker.reset ();
}
void
StepEditor::set_step_edit_cursor_width (Temporal::Beats beats)
{
@ -374,14 +379,13 @@ void
StepEditor::step_edit_toggle_chord ()
{
if (_step_edit_within_chord) {
step_to_next_chord ();
_step_edit_within_chord = false;
if (step_edit_region_view) {
step_edit_beat_pos += _step_edit_chord_duration;
step_edit_region_view->move_step_edit_cursor (step_edit_beat_pos);
}
_step_edit_chord_duration = Temporal::Beats();
} else {
_step_edit_triplet_countdown = 0;
_step_edit_within_chord = true;
_chord_tracker.reset ();
}
}

View file

@ -70,6 +70,7 @@ public:
int step_add_program_change (uint8_t channel, uint8_t program);
int step_add_note (uint8_t channel, uint8_t pitch, uint8_t velocity,
Temporal::Beats beat_duration);
void step_to_next_chord ();
void step_edit_sustain (Temporal::Beats beats);
bool step_edit_within_triplet () const;
void step_edit_toggle_triplet ();
@ -95,11 +96,11 @@ private:
Temporal::Beats _step_edit_chord_duration;
PBD::ScopedConnection step_edit_region_connection;
PublicEditor& _editor;
std::shared_ptr<ARDOUR::MidiTrack> _track;
std::shared_ptr<ARDOUR::MidiTrack> _track;
MidiTimeAxisView& _mtv;
int8_t last_added_pitch;
Temporal::Beats last_added_end;
ARDOUR::MidiNoteTracker _tracker;
Temporal::Beats _last_added_beat;
ARDOUR::MidiNoteTracker _tracker;
ARDOUR::MidiNoteTracker _chord_tracker;
sigc::connection delete_connection;
sigc::connection hide_connection;