rework design of midi clock ticker to avoid expensive generalization that has turned...
[ardour.git] / libs / ardour / automation_list.cc
index c8f5d18aec7377c4c01362842e6486d2359eac47..0810d2f2d007bb45c59eb8970d76e3048f6f5357 100644 (file)
@@ -124,7 +124,9 @@ AutomationList::create_curve_if_necessary()
 {
        switch (_parameter.type()) {
        case GainAutomation:
-       case PanAutomation:
+       case PanAzimuthAutomation:
+       case PanElevationAutomation:
+       case PanWidthAutomation:
        case FadeInAutomation:
        case FadeOutAutomation:
        case EnvelopeAutomation:
@@ -182,9 +184,8 @@ AutomationList::set_automation_state (AutoState s)
 
                 if (_state == Write) {
                         Glib::Mutex::Lock lm (ControlList::_lock);
-                        nascent.push_back (new NascentInfo (false));
+                        nascent.push_back (new NascentInfo ());
                 }
-
                automation_state_changed (s); /* EMIT SIGNAL */
        }
 }
@@ -203,7 +204,7 @@ AutomationList::start_touch (double when)
 {
         if (_state == Touch) {
                 Glib::Mutex::Lock lm (ControlList::_lock);
-                nascent.push_back (new NascentInfo (true, when));
+                nascent.push_back (new NascentInfo (when));
         }
 
        g_atomic_int_set (&_touching, 1);
@@ -212,19 +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.
                          */
-                        
+
                         NascentInfo* ninfo = nascent.back ();
                         nascent.erase (nascent.begin());
                         delete ninfo;
@@ -258,7 +270,7 @@ AutomationList::state (bool full)
 
        root->add_property ("automation-id", EventTypeMap::instance().to_symbol(_parameter));
 
-       root->add_property ("id", _id.to_s());
+       root->add_property ("id", id().to_s());
 
        snprintf (buf, sizeof (buf), "%.12g", _default_value);
        root->add_property ("default", buf);
@@ -354,6 +366,8 @@ AutomationList::deserialize_events (const XMLNode& node)
                fast_simple_add (x, y);
        }
 
+       thin ();
+
        if (!ok) {
                clear ();
                error << _("automation list: cannot load coordinates from XML, all points ignored") << endmsg;
@@ -392,7 +406,7 @@ AutomationList::set_state (const XMLNode& node, int version)
                const XMLNodeList& elist = node.children();
                XMLNodeConstIterator i;
                XMLProperty* prop;
-               nframes_t x;
+               pframes_t x;
                double y;
 
                 ControlList::freeze ();
@@ -415,6 +429,8 @@ AutomationList::set_state (const XMLNode& node, int version)
                        fast_simple_add (x, y);
                }
 
+               thin ();
+
                 thaw ();
 
                return 0;
@@ -425,8 +441,7 @@ AutomationList::set_state (const XMLNode& node, int version)
                return -1;
        }
 
-       if ((prop = node.property ("id")) != 0) {
-               _id = prop->value ();
+       if (set_id (node)) {
                /* update session AL list */
                AutomationListCreated(this);
        }
@@ -483,7 +498,7 @@ AutomationList::set_state (const XMLNode& node, int version)
        }
 
        bool have_events = false;
-       
+
        for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
                if ((*niter)->name() == X_("events")) {
                        deserialize_events (*(*niter));