alter where note resolution happens when a re-rendering is scheduled for a MIDI track
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
|
||||
@@ -137,6 +137,7 @@ public:
|
||||
PBD::Signal0<void> InputActiveChanged;
|
||||
|
||||
void realtime_handle_transport_stopped ();
|
||||
void region_edited (boost::shared_ptr<Region>);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 ()
|
||||
{
|
||||
|
||||
@@ -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()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user