fix MIDI triggers where region start/end are not the source start/end

This commit is contained in:
Paul Davis
2024-11-22 09:29:49 -07:00
parent 4e55570934
commit a162250682
2 changed files with 41 additions and 26 deletions

View File

@@ -703,6 +703,7 @@ class LIBARDOUR_API MIDITrigger : public Trigger {
int load_data (std::shared_ptr<MidiRegion>);
void compute_and_set_length ();
void _startup (BufferSet&, pframes_t dest_offset, Temporal::BBT_Offset const &);
void setup_event_indices ();
};
class LIBARDOUR_API TriggerBoxThread

View File

@@ -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<uint32_t>::min();
last_event_index = std::numeric_limits<uint32_t>::max();
for (uint32_t n = 0; n < ort->size(); ++n) {
if (first_event_index == std::numeric_limits<uint32_t>::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<uint32_t>::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<uint32_t>::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<uint32_t>::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<uint32_t>::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<Region> 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