diff --git a/libs/ardour/amp.cc b/libs/ardour/amp.cc index 27b29d87e4..80dd7422e9 100644 --- a/libs/ardour/amp.cc +++ b/libs/ardour/amp.cc @@ -383,7 +383,7 @@ Amp::set_gain (gain_t val, void *src) return; } - _gain_control->set_double(val, false); + _gain_control->set_double (val); _session.set_dirty(); } diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc index 1fde567e28..237d51a9d3 100644 --- a/libs/ardour/automation_control.cc +++ b/libs/ardour/automation_control.cc @@ -60,18 +60,18 @@ void AutomationControl::set_value (double value) { bool to_list = _list && ((AutomationList*)_list.get())->automation_write(); + bool erase_since_last = _session.transport_rolling(); if (to_list && parameter().toggled()) { // store the previous value just before this so any // interpolation works right - bool erase_since_last = _session.transport_rolling(); _list->add (get_double(), _session.transport_frame()-1, erase_since_last); } - Control::set_double (value, to_list, _session.transport_frame()); + Control::set_double (value, _session.transport_frame(), to_list, erase_since_last); Changed(); /* EMIT SIGNAL */ } diff --git a/libs/evoral/evoral/Control.hpp b/libs/evoral/evoral/Control.hpp index d09cb952f1..40f832d270 100644 --- a/libs/evoral/evoral/Control.hpp +++ b/libs/evoral/evoral/Control.hpp @@ -44,8 +44,8 @@ public: Control(const Parameter& parameter, boost::shared_ptr); virtual ~Control() {} - virtual void set_double(double val, bool to_list=false, double frame=0); - virtual double get_double(bool from_list=false, double frame=0) const; + virtual void set_double (double val, double frame=0, bool to_list=false, bool erase_since_last=false); + virtual double get_double (bool from_list=false, double frame=0) const; /** Get the latest user-set value * (which may not equal get_value() when automation is playing back). diff --git a/libs/evoral/src/Control.cpp b/libs/evoral/src/Control.cpp index bf8b0abaa0..a0271b56d4 100644 --- a/libs/evoral/src/Control.cpp +++ b/libs/evoral/src/Control.cpp @@ -46,12 +46,12 @@ Control::get_double (bool from_list, double frame) const void -Control::set_double (double value, bool to_list, double frame) +Control::set_double (double value, double frame, bool to_list, bool erase_since_last) { _user_value = value; if (to_list) { - _list->add (frame, value); + _list->add (frame, value, erase_since_last); } } diff --git a/libs/evoral/src/ControlList.cpp b/libs/evoral/src/ControlList.cpp index 9ae269453d..8e46392469 100644 --- a/libs/evoral/src/ControlList.cpp +++ b/libs/evoral/src/ControlList.cpp @@ -545,17 +545,13 @@ ControlList::start_write_pass (double when) new_write_pass = true; did_write_during_pass = false; insert_position = when; + + /* leave the insert iterator invalid, so that we will do the lookup + of where it should be in a "lazy" way - deferring it until + we actually add the first point (which may never happen). + */ - ControlEvent cp (when, 0.0); - insert_iterator = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); - - if ((*insert_iterator)->when != when) { - /* doesn't point at a control point at precisely this time, - so reset it to the end and we'll find where to insert - if/when a new control event is added. - */ - unlocked_invalidate_insert_iterator (); - } + unlocked_invalidate_insert_iterator (); } void @@ -590,8 +586,7 @@ ControlList::add (double when, double value, bool erase_since_last_add) if (new_write_pass) { - DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 new write pass, insert pos = %2, iter @ end ? %3\n", - this, insert_position, (insert_iterator == _events.end()))); + 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. @@ -600,21 +595,18 @@ ControlList::add (double when, double value, bool erase_since_last_add) * corresponding the value there. */ - if (insert_iterator == _events.end()) { - /* the insert_iterator is not set, figure out where - * it needs to be. - */ - - ControlEvent cp (insert_position, 0.0); - 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)); - } + /* the insert_iterator is not set, figure out where + * it needs to be. + */ + + ControlEvent cp (insert_position, 0.0); + 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 (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 */ @@ -698,14 +690,9 @@ ControlList::add (double when, double value, bool erase_since_last_add) } else { - DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 find based on lower bound, erase = %2\n", this, erase_since_last_add)); - - /* the new point is somewhere within the list, - * so figure out where to insert - */ - - ControlEvent cp (when, 0.0); - insert_iterator = lower_bound (_events.begin(), _events.end(), &cp, time_comparator); + DEBUG_TRACE (DEBUG::ControlList, string_compose ("@%1 erase %2 from existing iterator (@end ? %3\n", + this, erase_since_last_add, + (insert_iterator == _events.end()))); while (insert_iterator != _events.end()) { if ((*insert_iterator)->when < when) { diff --git a/libs/evoral/test/SequenceTest.cpp b/libs/evoral/test/SequenceTest.cpp index b0313ffd1b..6523675b0f 100644 --- a/libs/evoral/test/SequenceTest.cpp +++ b/libs/evoral/test/SequenceTest.cpp @@ -109,9 +109,9 @@ SequenceTest::controlInterpolationTest () MIDI::controller_range(min, max, normal); // Make a ramp like /\ from min to max and back to min - c->set_double(min, true, 0); - c->set_double(max, true, delay); - c->set_double(min, true, 2*delay); + c->set_double(min, 0, true); + c->set_double(max, delay, true); + c->set_double(min, 2*delay, true); CCTestSink