From 04cba6eca0acd5bc1d264f52e68eb960abe7ef50 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Tue, 2 Apr 2013 16:10:51 -0400 Subject: [PATCH] fix (?) behaviour when punching into automation write mode while the transport is moving, hopefully without breaking anything else --- libs/ardour/automation_watch.cc | 6 +- libs/evoral/evoral/ControlList.hpp | 5 +- libs/evoral/src/ControlList.cpp | 134 +++++++++++++++-------------- 3 files changed, 79 insertions(+), 66 deletions(-) diff --git a/libs/ardour/automation_watch.cc b/libs/ardour/automation_watch.cc index 0fa98f2133..16e10c95f9 100644 --- a/libs/ardour/automation_watch.cc +++ b/libs/ardour/automation_watch.cc @@ -72,8 +72,10 @@ AutomationWatch::add_automation_watch (boost::shared_ptr ac) */ if (_session && _session->transport_rolling() && ac->alist()->automation_write()) { - DEBUG_TRACE (DEBUG::Automation, string_compose ("\ttransport is rolling @ %1, so enter write pass\n", _session->transport_speed())); - ac->list()->set_in_write_pass (true); + DEBUG_TRACE (DEBUG::Automation, string_compose ("\ttransport is rolling @ %1, audible = %2so enter write pass\n", + _session->transport_speed(), _session->audible_frame())); + /* add a guard point since we are already moving */ + ac->list()->set_in_write_pass (true, true, _session->audible_frame()); } /* we can't store shared_ptr in connections because it diff --git a/libs/evoral/evoral/ControlList.hpp b/libs/evoral/evoral/ControlList.hpp index f43cf0af01..967e08d619 100644 --- a/libs/evoral/evoral/ControlList.hpp +++ b/libs/evoral/evoral/ControlList.hpp @@ -83,6 +83,8 @@ public: virtual boost::shared_ptr create(Parameter id); + void dump (std::ostream&); + ControlList& operator= (const ControlList&); bool operator== (const ControlList&); void copy_events (const ControlList&); @@ -238,7 +240,7 @@ public: virtual bool touch_enabled() const { return false; } void start_write_pass (double time); void write_pass_finished (double when); - void set_in_write_pass (bool); + void set_in_write_pass (bool, bool add_point = false, double when = 0.0); bool in_write_pass () const; /** Emitted when mark_dirty() is called on this object */ @@ -292,6 +294,7 @@ protected: bool did_write_during_pass; bool _in_write_pass; void unlocked_invalidate_insert_iterator (); + void add_guard_point (double when); }; } // namespace Evoral diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp index 8daba39cdb..a095daa135 100644 --- a/libs/evoral/src/ControlList.cpp +++ b/libs/evoral/src/ControlList.cpp @@ -366,9 +366,68 @@ ControlList::write_pass_finished (double /*when*/) } void -ControlList::set_in_write_pass (bool yn) +ControlList::set_in_write_pass (bool yn, bool add_point, double when) { _in_write_pass = yn; + + if (yn && add_point) { + add_guard_point (when); + } +} + +void +ControlList::add_guard_point (double when) +{ + ControlEvent cp (when, 0.0); + most_recent_insert_iterator = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); + + DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 ADD GUARD POINT @ %2looked up insert iterator for new write pass\n", this, when)); + + double eval_value = unlocked_eval (insert_position); + + if (most_recent_insert_iterator == _events.end()) { + + DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert iterator at end, adding eval-value there %2\n", this, eval_value)); + _events.push_back (new ControlEvent (when, eval_value)); + /* leave insert iterator at the end */ + + } else if ((*most_recent_insert_iterator)->when == when) { + + DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert iterator at existing point, setting eval-value there %2\n", this, eval_value)); + + /* most_recent_insert_iterator points to a control event + already at the insert position, so there is + nothing to do. + + ... except ... + + advance most_recent_insert_iterator so that the "real" + insert occurs in the right place, since it + points to the control event just inserted. + */ + + ++most_recent_insert_iterator; + } else { + + /* insert a new control event at the right spot + */ + + DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert eval-value %2 just before iterator @ %3\n", + this, eval_value, (*most_recent_insert_iterator)->when)); + + most_recent_insert_iterator = _events.insert (most_recent_insert_iterator, new ControlEvent (when, eval_value)); + + /* advance most_recent_insert_iterator so that the "real" + * insert occurs in the right place, since it + * points to the control event just inserted. + */ + + ++most_recent_insert_iterator; + } + + /* don't do this again till the next write pass */ + + new_write_pass = false; } bool @@ -409,68 +468,7 @@ ControlList::add (double when, double value) if (_in_write_pass && new_write_pass) { - DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 new write pass, insert pos = %2\n", this, insert_position)); - - /* The first addition of a new control event during a - * write pass. - * - * We need to add a new point at insert_position - * corresponding to the (existing, implicit) value there. - */ - - /* the insert_iterator is not set, figure out where - * it needs to be. - */ - - ControlEvent cp (insert_position, 0.0); - most_recent_insert_iterator = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); - DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 looked up insert iterator for new write pass\n", this)); - - double eval_value = unlocked_eval (insert_position); - - if (most_recent_insert_iterator == _events.end()) { - - DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert iterator at end, adding eval-value there %2\n", this, eval_value)); - _events.push_back (new ControlEvent (insert_position, eval_value)); - /* leave insert iterator at the end */ - - } else if ((*most_recent_insert_iterator)->when == when) { - - DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert iterator at existing point, setting eval-value there %2\n", this, eval_value)); - - /* most_recent_insert_iterator points to a control event - already at the insert position, so there is - nothing to do. - - ... except ... - - advance most_recent_insert_iterator so that the "real" - insert occurs in the right place, since it - points to the control event just inserted. - */ - - ++most_recent_insert_iterator; - } else { - - /* insert a new control event at the right spot - */ - - DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 insert eval-value %2 just before iterator @ %3\n", - this, eval_value, (*most_recent_insert_iterator)->when)); - - most_recent_insert_iterator = _events.insert (most_recent_insert_iterator, new ControlEvent (insert_position, eval_value)); - - /* advance most_recent_insert_iterator so that the "real" - * insert occurs in the right place, since it - * points to the control event just inserted. - */ - - ++most_recent_insert_iterator; - } - - /* don't do this again till the next write pass */ - - new_write_pass = false; + add_guard_point (insert_position); did_write_during_pass = true; } else if (most_recent_insert_iterator == _events.end() || when > (*most_recent_insert_iterator)->when) { @@ -1725,5 +1723,15 @@ ControlList::operator!= (ControlList const & other) const ); } +void +ControlList::dump (ostream& o) +{ + /* NOT LOCKED ... for debugging only */ + + for (EventList::iterator x = _events.begin(); x != _events.end(); ++x) { + o << (*x)->value << " @ " << (*x)->when << endl; + } +} + } // namespace Evoral -- 2.30.2