From a8aae56d92699e4545b5f8a69742f9a1c75ad238 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 1 Mar 2015 13:33:25 -0500 Subject: Handle edits while playing precisely. This avoids stuck notes if active notes are edited, but without stopping all active notes in the region on any edit as before. This implementation injects note ons in places that aren't actually note starts. Depending on how percussive the instrument is, this may not be desired. In the future, an option for this would be an improvement, but there are other places where "start notes in the middle" is a reasonable option. I think that should be handled universally if we're to do it at all, so not considering it a part of this fix for now. --- libs/ardour/midi_model.cc | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) (limited to 'libs/ardour/midi_model.cc') diff --git a/libs/ardour/midi_model.cc b/libs/ardour/midi_model.cc index 7e88569adc..de5000669c 100644 --- a/libs/ardour/midi_model.cc +++ b/libs/ardour/midi_model.cc @@ -1612,25 +1612,19 @@ MidiModel::find_sysex (gint sysex_id) MidiModel::WriteLock MidiModel::edit_lock() { - boost::shared_ptr ms = _midi_source.lock (); - assert (ms); - - Glib::Threads::Mutex::Lock* source_lock = new Glib::Threads::Mutex::Lock (ms->mutex()); - ms->invalidate(*source_lock); // Release cached iterator's read lock on model - return WriteLock(new WriteLockImpl(source_lock, _lock, _control_lock)); -} + boost::shared_ptr ms = _midi_source.lock(); + Glib::Threads::Mutex::Lock* source_lock = 0; -/** Lock just the model, the source lock must already be held. - * This should only be called from libardour/evoral places - */ -MidiModel::WriteLock -MidiModel::write_lock() -{ - boost::shared_ptr ms = _midi_source.lock (); - assert (ms); + if (ms) { + /* Take source lock and invalidate iterator to release its lock on model. + Add currently active notes to _active_notes so we can restore them + if playback resumes at the same point after the edit. */ + source_lock = new Glib::Threads::Mutex::Lock(ms->mutex()); + ms->invalidate(*source_lock, + ms->session().transport_rolling() ? &_active_notes : NULL); + } - assert (!ms->mutex().trylock ()); - return WriteLock(new WriteLockImpl(0, _lock, _control_lock)); + return WriteLock(new WriteLockImpl(source_lock, _lock, _control_lock)); } int -- cgit v1.2.3