X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fautomatable.cc;h=8629722889de2fe5d86a65140893146237addcbe;hb=aa0effb4cb38f4c3a06564bd9e6a0ee516d4f958;hp=6d8114939de2c3d8130aa5ae112575cdf4b9bd8c;hpb=106024330230fca331e2f611fec42ec1f4f43e5a;p=ardour.git diff --git a/libs/ardour/automatable.cc b/libs/ardour/automatable.cc index 6d8114939d..8629722889 100644 --- a/libs/ardour/automatable.cc +++ b/libs/ardour/automatable.cc @@ -17,27 +17,20 @@ */ -#include "ardour/ardour.h" #include -#include #include #include #include #include "pbd/error.h" -#include "pbd/enumwriter.h" -#include "pbd/stacktrace.h" -#include "midi++/names.h" - -#include "ardour/automatable.h" #include "ardour/amp.h" +#include "ardour/automatable.h" #include "ardour/event_type_map.h" #include "ardour/midi_track.h" -#include "ardour/pannable.h" -#include "ardour/panner.h" #include "ardour/pan_controllable.h" +#include "ardour/pannable.h" #include "ardour/plugin_insert.h" #include "ardour/session.h" @@ -47,27 +40,36 @@ using namespace std; using namespace ARDOUR; using namespace PBD; -framecnt_t Automatable::_automation_interval = 0; const string Automatable::xml_node_name = X_("Automation"); Automatable::Automatable(Session& session) : _a_session(session) - , _last_automation_snapshot(0) { } Automatable::Automatable (const Automatable& other) : ControlSet (other) , _a_session (other._a_session) - , _last_automation_snapshot (0) { - Glib::Mutex::Lock lm (other._control_lock); + Glib::Threads::Mutex::Lock lm (other._control_lock); for (Controls::const_iterator i = other._controls.begin(); i != other._controls.end(); ++i) { boost::shared_ptr ac (control_factory (i->first)); add_control (ac); } } + +Automatable::~Automatable () +{ + { + Glib::Threads::Mutex::Lock lm (_control_lock); + + for (Controls::const_iterator li = _controls.begin(); li != _controls.end(); ++li) { + boost::dynamic_pointer_cast(li->second)->drop_references (); + } + } +} + int Automatable::old_set_automation_state (const XMLNode& node) { @@ -79,8 +81,6 @@ Automatable::old_set_automation_state (const XMLNode& node) warning << _("Automation node has no path property") << endmsg; } - _last_automation_snapshot = 0; - return 0; } @@ -103,12 +103,10 @@ Automatable::load_automation (const string& path) return 1; } - Glib::Mutex::Lock lm (control_lock()); + Glib::Threads::Mutex::Lock lm (control_lock()); set tosave; controls().clear (); - _last_automation_snapshot = 0; - while (in) { double when; double value; @@ -139,16 +137,20 @@ Automatable::add_control(boost::shared_ptr ac) Evoral::Parameter param = ac->parameter(); boost::shared_ptr al = boost::dynamic_pointer_cast (ac->list ()); - assert (al); - al->automation_state_changed.connect_same_thread ( - _list_connections, boost::bind (&Automatable::automation_list_automation_state_changed, this, ac->parameter(), _1) - ); + if (al) { + al->automation_state_changed.connect_same_thread ( + _list_connections, + boost::bind (&Automatable::automation_list_automation_state_changed, + this, ac->parameter(), _1)); + } ControlSet::add_control (ac); _can_automate_list.insert (param); - automation_list_automation_state_changed (param, al->automation_state ()); // sync everything up + if (al) { + automation_list_automation_state_changed (param, al->automation_state ()); // sync everything up + } } string @@ -158,9 +160,10 @@ Automatable::describe_parameter (Evoral::Parameter param) if (param == Evoral::Parameter(GainAutomation)) { return _("Fader"); + } else if (param.type() == MuteAutomation) { + return _("Mute"); } else if (param.type() == MidiCCAutomation) { - return string_compose("%1: %2 [%3]", - param.id(), midi_name(param.id()), int(param.channel()) + 1); + return string_compose("Controller %1 [%2]", 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) { @@ -185,7 +188,7 @@ Automatable::can_automate (Evoral::Parameter what) int Automatable::set_automation_xml_state (const XMLNode& node, Evoral::Parameter legacy_param) { - Glib::Mutex::Lock lm (control_lock()); + Glib::Threads::Mutex::Lock lm (control_lock()); /* Don't clear controls, since some may be special derived Controllable classes */ @@ -233,15 +236,13 @@ Automatable::set_automation_xml_state (const XMLNode& node, Evoral::Parameter le } } - _last_automation_snapshot = 0; - return 0; } XMLNode& Automatable::get_automation_xml_state () { - Glib::Mutex::Lock lm (control_lock()); + Glib::Threads::Mutex::Lock lm (control_lock()); XMLNode* node = new XMLNode (Automatable::xml_node_name); if (controls().empty()) { @@ -261,13 +262,12 @@ Automatable::get_automation_xml_state () void Automatable::set_parameter_automation_state (Evoral::Parameter param, AutoState s) { - Glib::Mutex::Lock lm (control_lock()); + Glib::Threads::Mutex::Lock lm (control_lock()); - boost::shared_ptr c = control (param, true); - boost::shared_ptr l = boost::dynamic_pointer_cast(c->list()); + boost::shared_ptr c = automation_control (param, true); - if (s != l->automation_state()) { - l->set_automation_state (s); + if (c && (s != c->automation_state())) { + c->set_automation_state (s); _a_session.set_dirty (); } } @@ -277,11 +277,10 @@ Automatable::get_parameter_automation_state (Evoral::Parameter param) { AutoState result = Off; - boost::shared_ptr c = control(param); - boost::shared_ptr l = boost::dynamic_pointer_cast(c->list()); - + boost::shared_ptr c = automation_control(param); + if (c) { - result = l->automation_state(); + result = c->automation_state(); } return result; @@ -290,13 +289,12 @@ Automatable::get_parameter_automation_state (Evoral::Parameter param) void Automatable::set_parameter_automation_style (Evoral::Parameter param, AutoStyle s) { - Glib::Mutex::Lock lm (control_lock()); + Glib::Threads::Mutex::Lock lm (control_lock()); - boost::shared_ptr c = control(param, true); - boost::shared_ptr l = boost::dynamic_pointer_cast(c->list()); + boost::shared_ptr c = automation_control(param, true); - if (s != l->automation_style()) { - l->set_automation_style (s); + if (c && (s != c->automation_style())) { + c->set_automation_style (s); _a_session.set_dirty (); } } @@ -304,7 +302,7 @@ Automatable::set_parameter_automation_style (Evoral::Parameter param, AutoStyle AutoStyle Automatable::get_parameter_automation_style (Evoral::Parameter param) { - Glib::Mutex::Lock lm (control_lock()); + Glib::Threads::Mutex::Lock lm (control_lock()); boost::shared_ptr c = control(param); boost::shared_ptr l = boost::dynamic_pointer_cast(c->list()); @@ -341,19 +339,20 @@ Automatable::protect_automation () } void -Automatable::automation_snapshot (framepos_t now, bool force) +Automatable::transport_located (framepos_t now) { - if (force || _last_automation_snapshot > now || (now - _last_automation_snapshot) > _automation_interval) { + for (Controls::iterator li = controls().begin(); li != controls().end(); ++li) { - for (Controls::iterator i = controls().begin(); i != controls().end(); ++i) { - boost::shared_ptr c - = boost::dynamic_pointer_cast(i->second); - if (_a_session.transport_rolling() && c->automation_write()) { - c->list()->rt_add (now, i->second->user_double()); + boost::shared_ptr c + = boost::dynamic_pointer_cast(li->second); + if (c) { + boost::shared_ptr l + = boost::dynamic_pointer_cast(c->list()); + + if (l) { + l->start_write_pass (now); } } - - _last_automation_snapshot = now; } } @@ -399,6 +398,7 @@ Automatable::control_factory(const Evoral::Parameter& param) MidiTrack* mt = dynamic_cast(this); if (mt) { control = new MidiTrack::MidiControl(mt, param); + list.reset(); // No list, this is region "automation" } else { warning << "MidiCCAutomation for non-MidiTrack" << endl; }