Add API to run automation only (emit Changed signal).
[ardour.git] / libs / ardour / automation_list.cc
index f456ac210b9590164bec730f1c312ac00ade3fb5..27bc64462e336debfbff88ed283e38c201a62d3d 100644 (file)
@@ -60,6 +60,7 @@ AutomationList::AutomationList (const Evoral::Parameter& id, const Evoral::Param
 {
        _state = Off;
        g_atomic_int_set (&_touching, 0);
+       _interpolation = default_interpolation ();
 
        create_curve_if_necessary();
 
@@ -73,6 +74,7 @@ AutomationList::AutomationList (const Evoral::Parameter& id)
 {
        _state = Off;
        g_atomic_int_set (&_touching, 0);
+       _interpolation = default_interpolation ();
 
        create_curve_if_necessary();
 
@@ -115,6 +117,7 @@ AutomationList::AutomationList (const XMLNode& node, Evoral::Parameter id)
        , _before (0)
 {
        g_atomic_int_set (&_touching, 0);
+       _interpolation = default_interpolation ();
        _state = Off;
 
        set_state (node, Stateful::loading_state_version);
@@ -164,14 +167,14 @@ AutomationList&
 AutomationList::operator= (const AutomationList& other)
 {
        if (this != &other) {
-
-
+               ControlList::freeze ();
+               /* ControlList::operator= calls copy_events() which calls
+                * mark_dirty() and maybe_signal_changed()
+                */
                ControlList::operator= (other);
                _state = other._state;
                _touching = other._touching;
-
-               mark_dirty ();
-               maybe_signal_changed ();
+               ControlList::thaw ();
        }
 
        return *this;
@@ -202,6 +205,29 @@ AutomationList::set_automation_state (AutoState s)
        }
 }
 
+Evoral::ControlList::InterpolationStyle
+AutomationList::default_interpolation () const
+{
+       switch (_parameter.type()) {
+               case GainAutomation:
+               case BusSendLevel:
+               case EnvelopeAutomation:
+#ifndef XXX_NEW_INTERPOLATON__BREAK_SESSION_FORMAT_XXX
+                       /* use old, wrong linear gain interpolation */
+                       return ControlList::Linear;
+#endif
+                       return ControlList::Exponential;
+                       break;
+               case TrimAutomation:
+                       return ControlList::Logarithmic;
+                       break;
+               default:
+                       break;
+       }
+       /* based on Evoral::ParameterDescriptor log,toggle,.. */
+       return ControlList::default_interpolation ();
+}
+
 void
 AutomationList::start_write_pass (double when)
 {
@@ -317,11 +343,25 @@ XMLNode&
 AutomationList::state (bool full)
 {
        XMLNode* root = new XMLNode (X_("AutomationList"));
-       LocaleGuard lg;
 
        root->set_property ("automation-id", EventTypeMap::instance().to_symbol(_parameter));
        root->set_property ("id", id());
+
+#ifndef XXX_NEW_INTERPOLATON__BREAK_SESSION_FORMAT_XXX
+       /* force new enums to existing ones in session-file */
+       Evoral::ControlList::InterpolationStyle is = _interpolation;
+       switch (is) {
+               case ControlList::Exponential:
+               case ControlList::Logarithmic:
+                       is = ControlList::Linear;
+                       break;
+               default:
+                       break;
+       }
+       root->set_property ("interpolation-style", is);
+#else
        root->set_property ("interpolation-style", _interpolation);
+#endif
 
        if (full) {
                /* never serialize state with Write enabled - too dangerous
@@ -405,6 +445,7 @@ AutomationList::deserialize_events (const XMLNode& node)
                        ok = false;
                        break;
                }
+               y = std::min ((double)_desc.upper, std::max ((double)_desc.lower, y));
                fast_simple_add (x, y);
        }
 
@@ -424,7 +465,6 @@ AutomationList::deserialize_events (const XMLNode& node)
 int
 AutomationList::set_state (const XMLNode& node, int version)
 {
-       LocaleGuard lg;
        XMLNodeList nlist = node.children();
        XMLNode* nsos;
        XMLNodeIterator niter;
@@ -463,6 +503,7 @@ AutomationList::set_state (const XMLNode& node, int version)
                                continue;
                        }
 
+                       y = std::min ((double)_desc.upper, std::max ((double)_desc.lower, y));
                        fast_simple_add (x, y);
                }
 
@@ -489,8 +530,14 @@ AutomationList::set_state (const XMLNode& node, int version)
        }
 
        if (!node.get_property (X_("interpolation-style"), _interpolation)) {
-               _interpolation = Linear;
+               _interpolation = default_interpolation ();
        }
+#ifndef XXX_NEW_INTERPOLATON__BREAK_SESSION_FORMAT_XXX
+       /* internally force logarithmic and Trim params to use Log-scale */
+       if (_desc.logarithmic || _parameter.type() == TrimAutomation) {
+               _interpolation = ControlList::Logarithmic;
+       }
+#endif
 
        if (node.get_property (X_("state"), _state)) {
                if (_state == Write) {