diff --git a/libs/ardour/ardour/triggerbox.h b/libs/ardour/ardour/triggerbox.h index c3d9b2fc5a..e5f6358909 100644 --- a/libs/ardour/ardour/triggerbox.h +++ b/libs/ardour/ardour/triggerbox.h @@ -703,6 +703,7 @@ class LIBARDOUR_API MIDITrigger : public Trigger { int load_data (std::shared_ptr); void compute_and_set_length (); void _startup (BufferSet&, pframes_t dest_offset, Temporal::BBT_Offset const &); + void setup_event_indices (); }; class LIBARDOUR_API TriggerBoxThread diff --git a/libs/ardour/triggerbox.cc b/libs/ardour/triggerbox.cc index f8ace31353..bdaf2118be 100644 --- a/libs/ardour/triggerbox.cc +++ b/libs/ardour/triggerbox.cc @@ -2401,33 +2401,46 @@ MIDITrigger::check_edit_swap (timepos_t const & time, bool playing, BufferSet& b /* shutdown */ } - RTMidiBufferBeats* ort = rt_midibuffer.load (); - - first_event_index = std::numeric_limits::min(); - last_event_index = std::numeric_limits::max(); - - for (uint32_t n = 0; n < ort->size(); ++n) { - if (first_event_index == std::numeric_limits::min()) { - if ((*ort)[n].timestamp <= loop_start) { - first_event_index = n; - } else { - break; - } - } - } - - for (uint32_t n = 0; n < ort->size(); ++n) { - if (last_event_index == std::numeric_limits::max()) { - if ((*ort)[n].timestamp >= loop_end) { - last_event_index = n; /* exclusive end */ - break; - } - } - } + setup_event_indices (); pending_rt_midibuffer = nullptr; } +void +MIDITrigger::setup_event_indices () +{ + RTMidiBufferBeats* rt = rt_midibuffer.load (); + + assert (rt->size() > 0); + + if (rt->size() == 1) { + first_event_index = 0; + last_event_index = 1; + return; + } + + first_event_index = 0; + last_event_index = std::numeric_limits::max(); + + for (uint32_t n = 0; n < rt->size(); ++n) { + if ((first_event_index == 0) && ((*rt)[n].timestamp >= loop_start)) { + /* first one at or after the loop start */ + first_event_index = n; + } + + if ((last_event_index == std::numeric_limits::max()) && ((*rt)[n].timestamp > loop_end)) { + /* first one at or after the loop end */ + last_event_index = n; /* exclusive end */ + } + } + + if (last_event_index == std::numeric_limits::max()) { + last_event_index = rt->size(); + } + + DEBUG_TRACE (DEBUG::Triggers, "%1/%2 first index %3 last index %4 of %5\n", _box.order(), index(), first_event_index, last_event_index, rt->size()); +} + void MIDITrigger::arm () { @@ -2465,10 +2478,10 @@ MIDITrigger::captured (SlotArmInfo& ai, BufferSet& bufs) _follow_length = Temporal::BBT_Offset (0, data_length.get_beats(), 0); set_length (timecnt_t (data_length)); iter = 0; - first_event_index = 0; - last_event_index = ai.midi_buf->size(); _follow_action0 = FollowAction::Again; + setup_event_indices (); + /* Mark ai.midi_buf as null so that it is not deleted */ ai.midi_buf = nullptr; delete &ai; @@ -3002,7 +3015,7 @@ MIDITrigger::set_region_in_worker_thread (std::shared_ptr r) _model = mr->model(); _model->ContentsChanged.connect_same_thread (content_connection, std::bind (&MIDITrigger::model_contents_changed, this)); loop_start = r->start ().beats(); - loop_end = r->length ().beats(); + loop_end = r->end ().beats(); data_length = loop_end - loop_start; @@ -3160,6 +3173,7 @@ MIDITrigger::midi_run (BufferSet& bufs, samplepos_t start_sample, samplepos_t en RTMidiBufferBeats::Item const & item ((*rtmb)[iter]); std::cerr << "Looking at event #" << iter << " @ " << item.timestamp << " transition was " << transition_beats << " rs " << region_start << std::endl; + /* Event times are in beats, relative to start of source * file. We need to conv+ert to region-relative time, and then * a session timeline time, which is defined by the time at