summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2016-04-25 11:03:08 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2016-05-31 15:30:41 -0400
commit1e9b2abe730b89ff212ef61cee9e7112bf7c8f50 (patch)
tree2d666b2fab23475235b53bcc799a3ad9f5cab954 /libs/ardour
parent760beab7fa1b3fcccd653279ad736656793302ea (diff)
save and restore vca assignments
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/gain_control.h4
-rw-r--r--libs/ardour/ardour/slavable.h14
-rw-r--r--libs/ardour/ardour/vca_manager.h1
-rw-r--r--libs/ardour/gain_control.cc44
-rw-r--r--libs/ardour/route.cc15
-rw-r--r--libs/ardour/session_state.cc4
-rw-r--r--libs/ardour/slavable.cc65
-rw-r--r--libs/ardour/vca.cc4
-rw-r--r--libs/ardour/vca_manager.cc2
9 files changed, 87 insertions, 66 deletions
diff --git a/libs/ardour/ardour/gain_control.h b/libs/ardour/ardour/gain_control.h
index f7041fff78..f72320f1dd 100644
--- a/libs/ardour/ardour/gain_control.h
+++ b/libs/ardour/ardour/gain_control.h
@@ -54,10 +54,6 @@ class LIBARDOUR_API GainControl : public SlavableAutomationControl {
void inc_gain (gain_t);
private:
- std::string masters_string;
- PBD::ScopedConnection vca_loaded_connection;
-
- void vcas_loaded();
void recompute_masters_ratios (double val);
};
diff --git a/libs/ardour/ardour/slavable.h b/libs/ardour/ardour/slavable.h
index ae53caef38..b0ef33e1b4 100644
--- a/libs/ardour/ardour/slavable.h
+++ b/libs/ardour/ardour/slavable.h
@@ -26,12 +26,14 @@
#include <boost/shared_ptr.hpp>
+#include <pbd/signals.h>
+
class XMLNode;
namespace ARDOUR {
class VCA;
-class Session;
+class VCAManager;
class Slavable
{
@@ -39,14 +41,17 @@ class Slavable
Slavable ();
virtual ~Slavable() {}
- XMLNode& state () const;
- int assign (Session& s, XMLNode const&);
+ XMLNode& get_state () const;
+ int set_state (XMLNode const&, int);
void assign (boost::shared_ptr<VCA>);
void unassign (boost::shared_ptr<VCA>);
static std::string xml_node_name;
+ /* signal sent VCAManager once assignment is possible */
+ static PBD::Signal1<void,VCAManager*> Assign;
+
protected:
virtual int assign_controls (boost::shared_ptr<VCA>) = 0;
virtual int unassign_controls (boost::shared_ptr<VCA>) = 0;
@@ -54,6 +59,9 @@ class Slavable
private:
mutable Glib::Threads::RWLock master_lock;
std::set<uint32_t> _masters;
+ PBD::ScopedConnection assign_connection;
+
+ int do_assign (VCAManager* s);
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/vca_manager.h b/libs/ardour/ardour/vca_manager.h
index d18044a8df..5102d14698 100644
--- a/libs/ardour/ardour/vca_manager.h
+++ b/libs/ardour/ardour/vca_manager.h
@@ -50,7 +50,6 @@ class VCAManager : public SessionHandleRef, public PBD::StatefulDestructible
VCAList vcas() const;
- PBD::Signal0<void> VCAsLoaded;
PBD::Signal1<void,VCAList&> VCAAdded;
PBD::Signal1<void,VCAList&> VCARemoved;
diff --git a/libs/ardour/gain_control.cc b/libs/ardour/gain_control.cc
index 3ffeb057da..ef560085cc 100644
--- a/libs/ardour/gain_control.cc
+++ b/libs/ardour/gain_control.cc
@@ -178,48 +178,6 @@ GainControl::get_state ()
int
GainControl::set_state (XMLNode const& node, int version)
{
- AutomationControl::set_state (node, version);
-
-#if 0
- XMLProperty const* prop = node.property (X_("masters"));
-
- /* Problem here if we allow VCA's to be slaved to other VCA's .. we
- * have to load all VCAs first, then set up slave/master relationships
- * once we have them all.
- */
-
- if (prop) {
- masters_string = prop->value ();
-
- if (_session.vca_manager().vcas_loaded()) {
- vcas_loaded ();
- } else {
- _session.vca_manager().VCAsLoaded.connect_same_thread (vca_loaded_connection, boost::bind (&GainControl::vcas_loaded, this));
- }
- }
-#endif
-
- return 0;
-}
-
-void
-GainControl::vcas_loaded ()
-{
- if (masters_string.empty()) {
- return;
- }
-
- vector<string> masters;
- split (masters_string, masters, ',');
-
- for (vector<string>::const_iterator m = masters.begin(); m != masters.end(); ++m) {
- boost::shared_ptr<VCA> vca = _session.vca_manager().vca_by_number (PBD::atoi (*m));
- if (vca) {
- add_master (vca->gain_control());
- }
- }
-
- vca_loaded_connection.disconnect ();
- masters_string.clear ();
+ return AutomationControl::set_state (node, version);
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 301c7ba5c0..3e424a9603 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -2447,6 +2447,8 @@ Route::state(bool full_state)
foreach_processor (sigc::bind (sigc::mem_fun (*this, &Route::set_plugin_state_dir), ""));
}
+ node->add_child_copy (Slavable::get_state());
+
return *node;
}
@@ -2517,21 +2519,16 @@ Route::set_state (const XMLNode& node, int version)
} else if (prop->value() == "Output") {
_output->set_state (*child, version);
}
- }
- if (child->name() == X_("Processor")) {
+ } else if (child->name() == X_("Processor")) {
processor_state.add_child_copy (*child);
- }
-
- if (child->name() == X_("Pannable")) {
+ } else if (child->name() == X_("Pannable")) {
if (_pannable) {
_pannable->set_state (*child, version);
} else {
warning << string_compose (_("Pannable state found for route (%1) without a panner!"), name()) << endmsg;
}
- }
-
- if (child->name() == Controllable::xml_node_name) {
+ } else if (child->name() == Controllable::xml_node_name) {
if ((prop = child->property (X_("name"))) == 0) {
continue;
}
@@ -2547,6 +2544,8 @@ Route::set_state (const XMLNode& node, int version)
} else if (prop->value() == _solo_control->name()) {
_mute_control->set_state (*child, version);
}
+ } else if (child->name() == Slavable::xml_node_name) {
+ Slavable::set_state (*child, version);
}
}
diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc
index 4d5ffbffa7..ebbd37e4f9 100644
--- a/libs/ardour/session_state.cc
+++ b/libs/ardour/session_state.cc
@@ -1486,6 +1486,10 @@ Session::set_state (const XMLNode& node, int version)
goto out;
}
+ /* Now that we have Routes and masters loaded, connect them if appropriate */
+
+ Slavable::Assign (_vca_manager); /* EMIT SIGNAL */
+
/* our diskstreams list is no longer needed as they are now all owned by their Route */
_diskstreams_2X.clear ();
diff --git a/libs/ardour/slavable.cc b/libs/ardour/slavable.cc
index 989c2ec663..7a7b8e2919 100644
--- a/libs/ardour/slavable.cc
+++ b/libs/ardour/slavable.cc
@@ -17,27 +17,34 @@
*/
+#include <vector>
+
#include <glibmm/threads.h>
#include "pbd/convert.h"
+#include "pbd/error.h"
#include "pbd/xml++.h"
#include "ardour/slavable.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<void,VCAManager*> 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 +52,7 @@ Slavable::state () const
Glib::Threads::RWLock::ReaderLock lm (master_lock);
for (std::set<uint32_t>::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 +60,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<boost::shared_ptr<VCA> > vcas;
+
+ {
+ Glib::Threads::RWLock::ReaderLock lm (master_lock);
+
+ for (std::set<uint32_t>::const_iterator i = _masters.begin(); i != _masters.end(); ++i) {
+ boost::shared_ptr<VCA> 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<boost::shared_ptr<VCA> >::iterator v = vcas.begin(); v != vcas.end(); ++v) {
+ assign (*v);
+ }
+
+ assign_connection.disconnect ();
+
return 0;
}
void
Slavable::assign (boost::shared_ptr<VCA> 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 +123,7 @@ Slavable::assign (boost::shared_ptr<VCA> v)
void
Slavable::unassign (boost::shared_ptr<VCA> v)
{
- (void) unassign_controls (v);
Glib::Threads::RWLock::WriterLock lm (master_lock);
+ (void) unassign_controls (v);
_masters.erase (v->number());
}
diff --git a/libs/ardour/vca.cc b/libs/ardour/vca.cc
index 2ab84d5570..72c0a2cdcb 100644
--- a/libs/ardour/vca.cc
+++ b/libs/ardour/vca.cc
@@ -106,6 +106,8 @@ VCA::get_state ()
node->add_child_nocopy (_mute_control->get_state());
node->add_child_nocopy (get_automation_xml_state());
+ node->add_child_nocopy (Slavable::get_state());
+
return *node;
}
@@ -141,6 +143,8 @@ VCA::set_state (XMLNode const& node, int version)
if (prop->value() == _mute_control->name()) {
_mute_control->set_state (**i, version);
}
+ } else if ((*i)->name() == Slavable::xml_node_name) {
+ Slavable::set_state (**i, version);
}
}
diff --git a/libs/ardour/vca_manager.cc b/libs/ardour/vca_manager.cc
index e0d7e0fc82..e6143ea0b2 100644
--- a/libs/ardour/vca_manager.cc
+++ b/libs/ardour/vca_manager.cc
@@ -21,6 +21,7 @@
#include "pbd/error.h"
#include "pbd/replace_all.h"
+#include "ardour/slavable.h"
#include "ardour/vca.h"
#include "ardour/vca_manager.h"
@@ -175,7 +176,6 @@ VCAManager::set_state (XMLNode const& node, int version)
_vcas_loaded = true;
- VCAsLoaded (); /* EMIT SIGNAL */
VCAAdded (vcal); /* EMIT SIGNAL */
return 0;