X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fslavable.cc;h=4a759f5fef41a20abd567a74d314e731cf16ec3b;hb=f485cfa324717f57b9f820f43f1b53307b96a8b9;hp=989c2ec6636e20a716d3e9e4b933b5998989b08b;hpb=84a0386f9c7718d55f9c4dc4230df74372288d44;p=ardour.git diff --git a/libs/ardour/slavable.cc b/libs/ardour/slavable.cc index 989c2ec663..4a759f5fef 100644 --- a/libs/ardour/slavable.cc +++ b/libs/ardour/slavable.cc @@ -17,27 +17,35 @@ */ +#include + #include #include "pbd/convert.h" +#include "pbd/error.h" #include "pbd/xml++.h" #include "ardour/slavable.h" +#include "ardour/slavable_automation_control.h" #include "ardour/vca.h" +#include "ardour/vca_manager.h" #include "i18n.h" +using namespace PBD; using namespace ARDOUR; std::string Slavable::xml_node_name = X_("Slavable"); +PBD::Signal1 Slavable::Assign; /* signal sent once + * assignment is possible */ Slavable::Slavable () { - + Assign.connect_same_thread (assign_connection, boost::bind (&Slavable::do_assign, this, _1)); } XMLNode& -Slavable::state () const +Slavable::get_state () const { XMLNode* node = new XMLNode (xml_node_name); XMLNode* child; @@ -45,7 +53,7 @@ Slavable::state () const Glib::Threads::RWLock::ReaderLock lm (master_lock); for (std::set::const_iterator i = _masters.begin(); i != _masters.end(); ++i) { child = new XMLNode (X_("Master")); - child->add_property (X_("number"), PBD::to_string (*i, std::dec)); + child->add_property (X_("number"), to_string (*i, std::dec)); node->add_child_nocopy (*child); } @@ -53,16 +61,62 @@ Slavable::state () const } int -Slavable::assign (Session& s, XMLNode const& node) +Slavable::set_state (XMLNode const& node, int version) { + if (node.name() != xml_node_name) { + return -1; + } + + XMLNodeList const& children (node.children()); + Glib::Threads::RWLock::WriterLock lm (master_lock); + + for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) { + if ((*i)->name() == X_("Master")) { + XMLProperty const* prop = (*i)->property (X_("number")); + if (prop) { + uint32_t n = atoi (prop->value()); + _masters.insert (n); + } + } + } + + return 0; +} + +int +Slavable::do_assign (VCAManager* manager) +{ + std::vector > vcas; + + { + Glib::Threads::RWLock::ReaderLock lm (master_lock); + + for (std::set::const_iterator i = _masters.begin(); i != _masters.end(); ++i) { + boost::shared_ptr v = manager->vca_by_number (*i); + if (v) { + vcas.push_back (v); + } else { + warning << string_compose (_("Master #%1 not found, assignment lost"), *i) << endmsg; + } + } + } + + /* now that we've released the lock, we can do the assignments */ + + for (std::vector >::iterator v = vcas.begin(); v != vcas.end(); ++v) { + assign (*v); + } + + assign_connection.disconnect (); + return 0; } void Slavable::assign (boost::shared_ptr v) { + Glib::Threads::RWLock::WriterLock lm (master_lock); if (assign_controls (v) == 0) { - Glib::Threads::RWLock::WriterLock lm (master_lock); _masters.insert (v->number()); } } @@ -70,7 +124,63 @@ Slavable::assign (boost::shared_ptr v) void Slavable::unassign (boost::shared_ptr v) { - (void) unassign_controls (v); Glib::Threads::RWLock::WriterLock lm (master_lock); + (void) unassign_controls (v); _masters.erase (v->number()); } + +int +Slavable::assign_controls (boost::shared_ptr vca) +{ + boost::shared_ptr slave; + boost::shared_ptr master; + AutomationType types[] = { + GainAutomation, + SoloAutomation, + MuteAutomation, + RecEnableAutomation, + MonitoringAutomation, + NullAutomation + }; + + for (uint32_t n = 0; types[n] != NullAutomation; ++n) { + + slave = boost::dynamic_pointer_cast (automation_control (types[n])); + master = vca->automation_control (types[n]); + + if (slave && master) { + slave->add_master (master); + } + } + + return 0; +} + +int +Slavable::unassign_controls (boost::shared_ptr vca) +{ + boost::shared_ptr slave; + boost::shared_ptr master; + AutomationType types[] = { + GainAutomation, + SoloAutomation, + MuteAutomation, + RecEnableAutomation, + MonitoringAutomation, + NullAutomation + }; + + for (uint32_t n = 0; types[n] != NullAutomation; ++n) { + + slave = boost::dynamic_pointer_cast (automation_control (types[n])); + if (!vca) { + /* unassign from all */ + slave->clear_masters (); + } else { + slave->remove_master (master); + } + } + + return 0; +} +