From 9781c1bacafb72a5540f66db2cc0b5e677e64374 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 9 Sep 2022 09:21:43 -0600 Subject: [PATCH] triggerbox: prevent downstream crashes if a tempo map or other change invalidates MidiTrigger iter The iterator into the model can become incorrect in the sense that it is no longer the correct next event to play. This can happen at least with a tempo map change, and possible under other conditions. Catch this when it happens, and act as if we reached the end of the trigger --- libs/ardour/triggerbox.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libs/ardour/triggerbox.cc b/libs/ardour/triggerbox.cc index 1e19a30120..dd935cb71c 100644 --- a/libs/ardour/triggerbox.cc +++ b/libs/ardour/triggerbox.cc @@ -2697,13 +2697,22 @@ MIDITrigger::midi_run (BufferSet& bufs, samplepos_t start_sample, samplepos_t en DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 tlrr %2 >= fb %3, so at end with %4\n", index(), maybe_last_event_timeline_beats, final_beat, event)); iter = model->end(); break; + } else if (maybe_last_event_timeline_beats < start_beats) { + /* something made iter incorrect, maybe tempo map + change. Pretend that we reached the end + */ + DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 tlrr %2 < sb %3, so at end with %4\n", index(), maybe_last_event_timeline_beats, start_beats, event)); + iter = model->end(); + break; } /* Now get samples */ const samplepos_t timeline_samples = tmap->sample_at (maybe_last_event_timeline_beats); - if (timeline_samples >= end_sample) { + if (timeline_samples >= end_sample || timeline_samples < start_sample) { + /* we should not get here but if we do, pretend we reached the end */ + iter = model->end(); break; } @@ -2720,6 +2729,7 @@ MIDITrigger::midi_run (BufferSet& bufs, samplepos_t start_sample, samplepos_t en */ samplepos_t buffer_samples = (timeline_samples - start_sample) + dest_offset; + assert (buffer_samples >= 0); Evoral::Event ev (Evoral::MIDI_EVENT, buffer_samples, event.size(), const_cast(event.buffer()), false);