alter where note resolution happens when a re-rendering is scheduled for a MIDI track

This commit is contained in:
Paul Davis
2019-10-17 17:32:56 -06:00
parent 2cf9ad8f8c
commit 0573e7cdf0
7 changed files with 28 additions and 47 deletions

View File

@@ -1084,8 +1084,6 @@ MidiRegionView::apply_diff (bool as_subcommand, bool was_copy)
}
}
midi_view()->midi_track()->midi_playlist()->region_edited (_region, _note_diff_command);
if (as_subcommand) {
_model->apply_command_as_subcommand (*trackview.session(), _note_diff_command);
} else {
@@ -1100,8 +1098,11 @@ MidiRegionView::apply_diff (bool as_subcommand, bool was_copy)
}
_marked_for_velocity.clear();
if (commit) {
trackview.editor().commit_reversible_command ();
/* XXX the GUI should NOT be responsible for causing this call tree */
midi_view()->midi_track()->region_edited (_region);
}
}

View File

@@ -157,6 +157,7 @@ private:
samplepos_t overwrite_sample;
mutable gint _pending_overwrite;
bool overwrite_queued;
bool run_must_resolve;
IOChange input_change_pending;
samplepos_t file_sample[DataType::num_types];

View File

@@ -100,15 +100,6 @@ public:
std::set<Evoral::Parameter> contained_automation();
/** Handle a region edit during read.
*
* This must be called before the command is applied to the model. Events
* are injected into the playlist output to compensate for edits to active
* notes and maintain coherent output and tracker state.
*/
void region_edited(boost::shared_ptr<Region> region,
const MidiModel::NoteDiffCommand* cmd);
/** Clear all note trackers. */
void reset_note_trackers ();

View File

@@ -137,6 +137,7 @@ public:
PBD::Signal0<void> InputActiveChanged;
void realtime_handle_transport_stopped ();
void region_edited (boost::shared_ptr<Region>);
protected:

View File

@@ -57,6 +57,7 @@ DiskReader::DiskReader (Session& s, string const & str, DiskIOProcessor::Flag f)
: DiskIOProcessor (s, str, f)
, overwrite_sample (0)
, overwrite_queued (false)
, run_must_resolve (false)
, _declick_amp (s.nominal_sample_rate ())
, _declick_offs (0)
{
@@ -254,6 +255,14 @@ DiskReader::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
sampleoffset_t disk_samples_to_consume;
MonitorState ms = _track->monitoring_state ();
if (run_must_resolve) {
boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (_track);
assert (mt);
cerr << _track->name() << " resolving " << _tracker.on() << " notes @ " << start_sample << endl;
resolve_tracker (mt->immediate_events(), start_sample);
run_must_resolve = false;
}
if (_active) {
if (!_pending_active) {
_active = false;
@@ -453,8 +462,6 @@ DiskReader::pending_overwrite () const {
return g_atomic_int_get (&_pending_overwrite) != 0;
}
PBD::Timing minsert;
void
DiskReader::set_pending_overwrite ()
{
@@ -468,12 +475,8 @@ DiskReader::set_pending_overwrite ()
(*chan)->rbuf->read_flush ();
}
boost::shared_ptr<MidiTrack> mt = boost::dynamic_pointer_cast<MidiTrack> (_track);
if (mt) {
resolve_tracker (mt->immediate_events(), _session.audible_sample());
}
g_atomic_int_set (&_pending_overwrite, 1);
run_must_resolve = true;
}
bool
@@ -522,12 +525,11 @@ DiskReader::overwrite_existing_buffers ()
if (_playlists[DataType::MIDI]) {
minsert.reset();
PBD::Timing minsert;
minsert.start();
midi_playlist()->render (_mbuf, 0);
minsert.update();
cerr << "Reading " << name() << " took " << minsert.elapsed() << " microseconds, final size = " << _mbuf.size() << endl;
_mbuf.dump (40);
//cerr << "Reading " << name() << " took " << minsert.elapsed() << " microseconds, final size = " << _mbuf.size() << endl;
}
g_atomic_int_set (&_pending_overwrite, 0);
@@ -1073,6 +1075,7 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, sample
samplepos_t nframes = ::llabs (end_sample - start_sample);
if (_mbuf.size() == 0) {
/* no data to read, so do nothing */
return;
}
@@ -1083,7 +1086,8 @@ DiskReader::get_midi_playback (MidiBuffer& dst, samplepos_t start_sample, sample
target = &scratch_bufs.get_midi (0);
}
if (ms & MonitoringDisk) {
if (!pending_overwrite() && (ms & MonitoringDisk)) {
/* disk data needed */
Location* loc = _loop_location;

View File

@@ -251,31 +251,6 @@ MidiPlaylist::read (Evoral::EventSink<samplepos_t>& dst,
return dur;
}
void
MidiPlaylist::region_edited(boost::shared_ptr<Region> region,
const MidiModel::NoteDiffCommand* cmd)
{
typedef MidiModel::NoteDiffCommand Command;
boost::shared_ptr<MidiRegion> mr = boost::dynamic_pointer_cast<MidiRegion>(region);
if (!mr || !_session.transport_rolling()) {
return;
}
/* Take write lock to prevent concurrency with read(). */
Playlist::RegionWriteLock lock(this);
NoteTrackers::iterator t = _note_trackers.find(mr.get());
if (t == _note_trackers.end()) {
return; /* Region is not currently active, nothing to do. */
}
/* Queue any necessary edit compensation events. */
t->second->fixer.prepare(
_session.tempo_map(), cmd, mr->position() - mr->start(),
_read_end, t->second->cursor.active_notes);
}
void
MidiPlaylist::reset_note_trackers ()
{

View File

@@ -871,3 +871,11 @@ MidiTrack::realtime_handle_transport_stopped ()
Route::realtime_handle_transport_stopped ();
_disk_reader->resolve_tracker (_immediate_events, Port::port_offset());
}
void
MidiTrack::region_edited(boost::shared_ptr<Region> region)
{
cerr << "MIDI region " << region->name() << " edited, queue reload\n";
_session.request_overwrite_buffer (boost::dynamic_pointer_cast<Track> (shared_from_this()));
}