X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fautomation_control.cc;h=be81e28dd5d3173a99267d3aa9c91718cf9ae375;hb=157253c2c633c184bb09edf3de30dd283b0ec506;hp=e0ebc00062e1b3dc751e9df7f796956fc0185eb8;hpb=b7e645ec61ab531917a03cdab14a8c22670677f7;p=ardour.git diff --git a/libs/ardour/automation_control.cc b/libs/ardour/automation_control.cc index e0ebc00062..be81e28dd5 100644 --- a/libs/ardour/automation_control.cc +++ b/libs/ardour/automation_control.cc @@ -31,7 +31,7 @@ #include "ardour/event_type_map.h" #include "ardour/session.h" -#include "i18n.h" +#include "pbd/i18n.h" #ifdef COMPILER_MSVC #include @@ -49,8 +49,10 @@ AutomationControl::AutomationControl(ARDOUR::Session& s const Evoral::Parameter& parameter, const ParameterDescriptor& desc, boost::shared_ptr list, - const string& name) - : Controllable (name.empty() ? EventTypeMap::instance().to_symbol(parameter) : name) + const string& name, + Controllable::Flag flags) + + : Controllable (name.empty() ? EventTypeMap::instance().to_symbol(parameter) : name, flags) , Evoral::Control(parameter, desc, list) , _session(session) , _desc(desc) @@ -117,16 +119,54 @@ AutomationControl::set_value (double val, PBD::Controllable::GroupControlDisposi void AutomationControl::actually_set_value (double value, PBD::Controllable::GroupControlDisposition gcd) { - bool to_list = _list && boost::dynamic_pointer_cast(_list)->automation_write(); - //const double old_value = Control::user_double (); + boost::shared_ptr al = boost::dynamic_pointer_cast (_list); + const framepos_t pos = _session.transport_frame(); + bool to_list; + double old_value; + + /* We cannot use ::get_value() here since that is virtual, and intended + to return a scalar value that in some way reflects the state of the + control (with semantics defined by the control itself, since it's + internal state may be more complex than can be fully represented by + a single scalar). + + This method's only job is to set the "user_double()" value of the + underlying Evoral::Control object, and so we should compare the new + value we're being given to the current user_double(). + + Unless ... we're doing automation playback, in which case the + current effective value of the control (used to determine if + anything has changed) is the one derived from the automation event + list. + */ - Control::set_double (value, _session.transport_frame(), to_list); + if (!al) { + to_list = false; + old_value = Control::user_double(); + } else { + if (al->automation_write ()) { + to_list = true; + old_value = Control::user_double (); + } else if (al->automation_playback()) { + to_list = false; + old_value = al->eval (pos); + } else { + to_list = false; + old_value = Control::user_double (); + } + } + + Control::set_double (value, pos, to_list); - //AutomationType at = (AutomationType) _parameter.type(); - //std::cerr << "++++ Changed (" << enum_2_string (at) << ", " << enum_2_string (gcd) << ") = " << value - //<< " (was " << old_value << ") @ " << this << std::endl; + if (old_value != value) { + // AutomationType at = (AutomationType) _parameter.type(); + // std::cerr << "++++ Changed (" << enum_2_string (at) << ", " << enum_2_string (gcd) << ") = " << value + // << " (was " << old_value << ") @ " << this << std::endl; + + Changed (true, gcd); + _session.set_dirty (); + } - Changed (true, gcd); } void @@ -155,7 +195,8 @@ AutomationControl::set_automation_state (AutoState as) AutomationWatch::instance().add_automation_watch (shared_from_this()); } else if (as == Touch) { if (alist()->empty()) { - Control::set_double (val, _session.transport_frame(), true); + Control::set_double (val, _session.current_start_frame (), true); + Control::set_double (val, _session.current_end_frame (), true); Changed (true, Controllable::NoGroup); } if (!touching()) {