save and restore vca assignments
This commit is contained in:
parent
760beab7fa
commit
1e9b2abe73
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user