more changes to get MIDI clip editing working

MIDITrigger now has a direct reference to a MidiModel, and uses
that as the basis for discovering what state has changed and needs
updated after an edit operation pushes a new state to the trigger
This commit is contained in:
Paul Davis
2024-06-26 21:31:34 -06:00
parent 7bf464795a
commit 62d36832c6
2 changed files with 75 additions and 9 deletions

View File

@@ -647,6 +647,12 @@ class LIBARDOUR_API MIDITrigger : public Trigger {
Temporal::BBT_Offset _start_offset;
Temporal::BBT_Offset _legato_offset;
std::shared_ptr<MidiModel> _model;
Temporal::Beats loop_start;
Temporal::Beats loop_end;
uint32_t first_event_index;
uint32_t last_event_index;
typedef RTMidiBufferBase<Temporal::Beats,Temporal::Beats> RTMidiBufferBeats;
std::atomic<RTMidiBufferBeats*> rt_midibuffer;

View File

@@ -1288,11 +1288,47 @@ MIDITrigger::check_edit_swap (timepos_t const & time, bool playing, BufferSet& b
const timepos_t region_start_time = _region->start();
const Temporal::Beats region_start = region_start_time.beats();
pending->track_state (transition_beats + (time.beats() - region_start), post_edit_state);
// _box.tracker->resolve_diff (post_edit_state, mbuf, time.samples());
_box.tracker->resolve_diff (post_edit_state, mbuf, time.samples());
// }
std::cerr << "OLD\n";
RTMidiBufferBeats* ort = rt_midibuffer.load();
if (ort) {
ort->dump (99);
}
old_rt_midibuffer = rt_midibuffer.exchange (pending);
std::cerr << "Swapped in new pending RT MB\n";
std::cerr << "old after exch " << old_rt_midibuffer << std::endl;
if (iter < rt_midibuffer.load()->size()) {
/* shutdown */
}
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;
}
}
}
std::cerr << "Swapped in new pending RT MB, events " << first_event_index << " .. " << last_event_index << "\n";
rt_midibuffer.load()->dump (99);
pending_rt_midibuffer = nullptr;
}
@@ -2695,13 +2731,19 @@ MIDITrigger::set_region_in_worker_thread (std::shared_ptr<Region> r)
_follow_length = Temporal::BBT_Offset (0, data_length.get_beats(), 0);
set_length (mr->length());
pending_rt_midibuffer = new RTMidiBufferBeats;
_model = mr->model();
loop_start = r->start ().beats();
loop_end = r->end ().beats();
RTMidiBufferBeats* rtmb = new RTMidiBufferBeats;
{
Source::ReaderLock lm (mr->midi_source()->mutex());
mr->midi_source()->render (lm, *pending_rt_midibuffer);
mr->midi_source()->render (lm, *rtmb);
}
pending_rt_midibuffer = rtmb;
estimate_midi_patches ();
/* we've changed some of our internal values; we need to update our queued UIState or they will be lost when UIState is applied */
@@ -2723,7 +2765,7 @@ MIDITrigger::retrigger ()
/* XXX need to deal with bar offsets */
// const Temporal::BBT_Offset o = _start_offset + _legato_offset;
iter = 0;
iter = first_event_index;
_legato_offset = Temporal::BBT_Offset ();
last_event_beats = Temporal::Beats();
last_event_samples = 0;
@@ -2742,7 +2784,7 @@ MIDITrigger::tempo_map_changed ()
* on an active trigger.
*/
iter = 0;
iter = first_event_index;
Temporal::TempoMap::SharedPtr tmap (Temporal::TempoMap::use());
const timepos_t region_start_time = _region->start();
const Temporal::Beats region_start = region_start_time.beats();
@@ -2782,9 +2824,22 @@ MIDITrigger::tempo_map_changed ()
void
MIDITrigger::edited ()
{
// RTMidiBufferBase<Beats,Beats>* rtmb (new RTMidiBufferBase<Beats,Beats>);
MidiModel::ReadLock rl (model->read_lock());
/* render, then set pending rt */
RTMidiBufferBeats * rtmb (new RTMidiBufferBeats);
std::shared_ptr<MidiRegion> mr = std::dynamic_pointer_cast<MidiRegion> (_region);
_model->render (_model->read_lock(), *rtmb);
/* Clean up a previous RT midi buffer swap */
RTMidiBufferBeats* old = old_rt_midibuffer.load();
if (old) {
delete old;
old_rt_midibuffer = nullptr;
}
/* And set it. RT thread will find this and do what needs to be done */
pending_rt_midibuffer = rtmb;
}
template<bool in_process_context>
@@ -2846,6 +2901,11 @@ MIDITrigger::midi_run (BufferSet& bufs, samplepos_t start_sample, samplepos_t en
break;
}
if (iter >= last_event_index) {
iter = rtmb->size();
break;
}
if (maybe_last_event_timeline_beats > final_beat) {
iter = rtmb->size();
break;