Some improvements to performance with crossfades: don't recompute a whole track's...
[ardour.git] / libs / ardour / automatable.cc
index c145c3c50129520a2cd552b7b01bbf0cc13b25b1..bf08a4026cf5423b400eaec70a8c70c75bc3ad03 100644 (file)
 
 */
 
-#include <ardour/ardour.h>
+#include "ardour/ardour.h"
 #include <fstream>
 #include <inttypes.h>
 #include <cstdio>
 #include <errno.h>
-#include <pbd/error.h>
-#include <pbd/enumwriter.h>
-#include <midi++/names.h>
-#include <ardour/session.h>
-#include <ardour/automatable.h>
-#include <ardour/midi_track.h>
-#include <ardour/plugin_insert.h>
-#include <ardour/panner.h>
+#include "pbd/error.h"
+#include "pbd/enumwriter.h"
+
+#include "midi++/names.h"
+
+#include "ardour/automatable.h"
+#include "ardour/amp.h"
+#include "ardour/event_type_map.h"
+#include "ardour/midi_track.h"
+#include "ardour/panner.h"
+#include "ardour/plugin_insert.h"
+#include "ardour/session.h"
 
 #include "i18n.h"
 
@@ -158,8 +162,8 @@ Automatable::describe_parameter (Evoral::Parameter param)
                /* ID's are zero-based, present them as 1-based */
                return (string_compose(_("Pan %1"), param.id() + 1));
        } else if (param.type() == MidiCCAutomation) {
-               return string_compose("CC %1 (%2) [%3]",
-                               param.id() + 1, midi_name(param.id()), int(param.channel()) + 1);                       
+               return string_compose("%2 [%3]",
+                               param.id() + 1, midi_name(param.id()), int(param.channel()) + 1);
        } else if (param.type() == MidiPgmChangeAutomation) {
                return string_compose("Program [%1]", int(param.channel()) + 1);
        } else if (param.type() == MidiPitchBenderAutomation) {
@@ -241,7 +245,6 @@ Automatable::set_automation_state (const XMLNode& node, Evoral::Parameter legacy
                            boost::shared_ptr<Evoral::Control> newcontrol = control_factory(param);
                                add_control(newcontrol);
                                newcontrol->set_list(al);
-                               warning << "Control did not exist";
                        }
 
                } else {
@@ -267,7 +270,9 @@ Automatable::get_automation_state ()
        for (Controls::iterator li = controls().begin(); li != controls().end(); ++li) {
                boost::shared_ptr<AutomationList> l
                                = boost::dynamic_pointer_cast<AutomationList>(li->second->list());
-               node->add_child_nocopy (l->get_state ());
+               if (!l->empty()) {
+                       node->add_child_nocopy (l->get_state ());
+               }
        }
 
        return *node;
@@ -380,7 +385,7 @@ Automatable::automation_snapshot (nframes_t now, bool force)
 }
 
 void
-Automatable::transport_stopped (nframes_t now)
+Automatable::transport_stopped (sframes_t now)
 {
        for (Controls::iterator li = controls().begin(); li != controls().end(); ++li) {
                
@@ -407,9 +412,14 @@ Automatable::control_factory(const Evoral::Parameter& param)
        } else if (param.type() == PluginAutomation) {
                control = new PluginInsert::PluginControl((PluginInsert*)this, param);
        } else if (param.type() == GainAutomation) {
-               control = new IO::GainControl( X_("gaincontrol"), (IO*)this, param);
+               control = new Amp::GainControl( X_("gaincontrol"), _a_session, (Amp*)this, param);
        } else if (param.type() == PanAutomation) {
-               control = new Panner::PanControllable( ((Panner *)this)->session(), X_("panner"), *(Panner *)this, param);
+               Panner* me = dynamic_cast<Panner*>(this);
+               if (me) {
+                       control = new Panner::PanControllable(me->session(), X_("panner"), *me, param);
+               } else {
+                       cerr << "ERROR: PanAutomation for non-Panner" << endl;
+               }
        } else {
                control = new AutomationControl(_a_session, param);
        }
@@ -417,3 +427,15 @@ Automatable::control_factory(const Evoral::Parameter& param)
        return boost::shared_ptr<Evoral::Control>(control);
 }
 
+boost::shared_ptr<AutomationControl>
+Automatable::automation_control (const Evoral::Parameter& id, bool create)
+{
+       return boost::dynamic_pointer_cast<AutomationControl>(Evoral::ControlSet::control(id, create));
+}
+
+boost::shared_ptr<const AutomationControl>
+Automatable::automation_control (const Evoral::Parameter& id) const
+{
+       return boost::dynamic_pointer_cast<const AutomationControl>(Evoral::ControlSet::control(id));
+}
+