diff options
-rw-r--r-- | libs/ardour/automatable.cc | 7 | ||||
-rw-r--r-- | libs/ardour/automation_list.cc | 15 |
2 files changed, 19 insertions, 3 deletions
diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc index 100e7ddb3c..392938fde2 100644 --- a/libs/ardour/automatable.cc +++ b/libs/ardour/automatable.cc @@ -417,6 +417,13 @@ Automatable::transport_stopped (framepos_t now) = boost::dynamic_pointer_cast<AutomationList>(c->list()); if (l) { + /* Stop any active touch gesture just before we mark the write pass + as finished. If we don't do this, the transport can end up stopped with + an AutomationList thinking that a touch is still in progress and, + when the transport is re-started, a touch will magically + be happening without it ever have being started in the usual way. + */ + l->stop_touch (true, now); l->write_pass_finished (now); if (l->automation_playback()) { diff --git a/libs/ardour/automation_list.cc b/libs/ardour/automation_list.cc index b76fa0bb4b..aaab84f2da 100644 --- a/libs/ardour/automation_list.cc +++ b/libs/ardour/automation_list.cc @@ -213,21 +213,30 @@ AutomationList::start_touch (double when) void AutomationList::stop_touch (bool mark, double when) { + if (g_atomic_int_get (&_touching) == 0) { + /* this touch has already been stopped (probably by Automatable::transport_stopped), + so we've nothing to do. + */ + return; + } + g_atomic_int_set (&_touching, 0); if (_state == Touch) { + + assert (!nascent.empty ()); + Glib::Mutex::Lock lm (ControlList::_lock); if (mark) { - nascent.back()->end_time = when; + + nascent.back()->end_time = when; } else { /* nascent info created in start touch but never used. just get rid of it. */ - assert (!nascent.empty ()); - NascentInfo* ninfo = nascent.back (); nascent.erase (nascent.begin()); delete ninfo; |