summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2016-03-02 12:09:24 -0500
committerPaul Davis <paul@linuxaudiosystems.com>2016-05-31 15:30:39 -0400
commit35172bb369eea6245e08b258f4a350411c20f98d (patch)
tree6cece2c4bc2f6cb986ec341cc3c11ff6a894892e /libs/ardour
parentcab88c6aad6782e621ae9c51aac5af24a2f3d5b8 (diff)
change API for GainControl, VCA and VCAManager
This allows sane state save/restore
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/gain_control.h18
-rw-r--r--libs/ardour/ardour/vca.h4
-rw-r--r--libs/ardour/gain_control.cc90
-rw-r--r--libs/ardour/route.cc2
-rw-r--r--libs/ardour/vca.cc18
-rw-r--r--libs/ardour/vca_manager.cc1
6 files changed, 104 insertions, 29 deletions
diff --git a/libs/ardour/ardour/gain_control.h b/libs/ardour/ardour/gain_control.h
index 7845679220..93d9c4fec0 100644
--- a/libs/ardour/ardour/gain_control.h
+++ b/libs/ardour/ardour/gain_control.h
@@ -20,7 +20,7 @@
#define __ardour_gain_control_h__
#include <string>
-#include <list>
+#include <set>
#include <boost/shared_ptr.hpp>
#include <glibmm/threads.h>
@@ -54,20 +54,28 @@ class LIBARDOUR_API GainControl : public AutomationControl {
double range_db;
gain_t get_master_gain () const;
- void add_master (boost::shared_ptr<GainControl>);
- void remove_master (boost::shared_ptr<GainControl>);
+ void add_master (boost::shared_ptr<VCA>);
+ void remove_master (boost::shared_ptr<VCA>);
void clear_masters ();
- bool slaved_to (boost::shared_ptr<GainControl>) const;
+ bool slaved_to (boost::shared_ptr<VCA>) const;
+ std::vector<uint32_t> masters () const;
+
+ int set_state (XMLNode const&, int);
+ XMLNode& get_state();
private:
void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
mutable Glib::Threads::Mutex master_lock;
- typedef std::list<boost::shared_ptr<GainControl> > Masters;
+ typedef std::set<boost::shared_ptr<GainControl> > Masters;
Masters _masters;
+ PBD::ScopedConnectionList masters_connections;
+ std::set<uint32_t> _masters_numbers;
+ std::string _masters_state_string ();
gain_t get_master_gain_locked () const;
+ void master_going_away (boost::weak_ptr<VCA>);
};
} /* namespace */
diff --git a/libs/ardour/ardour/vca.h b/libs/ardour/ardour/vca.h
index a4da21e31f..4359899f6f 100644
--- a/libs/ardour/ardour/vca.h
+++ b/libs/ardour/ardour/vca.h
@@ -37,6 +37,7 @@ class LIBARDOUR_API VCA : public SessionHandleRef, public PBD::StatefulDestructi
public:
VCA (Session& session, const std::string& name, uint32_t num);
VCA (Session& session, XMLNode const&, int version);
+ ~VCA();
std::string name() const { return _name; }
uint32_t number () const { return _number; }
@@ -48,9 +49,6 @@ class LIBARDOUR_API VCA : public SessionHandleRef, public PBD::StatefulDestructi
boost::shared_ptr<GainControl> control() const { return _control; }
- void add (boost::shared_ptr<Route>);
- void remove (boost::shared_ptr<Route>);
-
XMLNode& get_state();
int set_state (XMLNode const&, int version);
diff --git a/libs/ardour/gain_control.cc b/libs/ardour/gain_control.cc
index 5ba7179231..c5f1f25bb7 100644
--- a/libs/ardour/gain_control.cc
+++ b/libs/ardour/gain_control.cc
@@ -16,9 +16,14 @@
675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include "pbd/convert.h"
+#include "pbd/strsplit.h"
+
#include "ardour/dB.h"
#include "ardour/gain_control.h"
#include "ardour/session.h"
+#include "ardour/vca.h"
+#include "ardour/vca_manager.h"
#include "i18n.h"
@@ -124,7 +129,7 @@ GainControl::get_master_gain_locked () const
}
void
-GainControl::add_master (boost::shared_ptr<GainControl> m)
+GainControl::add_master (boost::shared_ptr<VCA> vca)
{
gain_t old_master_val;
gain_t new_master_val;
@@ -132,8 +137,17 @@ GainControl::add_master (boost::shared_ptr<GainControl> m)
{
Glib::Threads::Mutex::Lock lm (master_lock);
old_master_val = get_master_gain_locked ();
- _masters.push_back (m);
+ _masters.insert (vca->control());
+ _masters_numbers.insert (vca->number());
new_master_val = get_master_gain_locked ();
+
+ /* note that we bind @param m as a weak_ptr<GainControl>, thus
+ avoiding holding a reference to the control in the binding
+ itself.
+ */
+
+ vca->DropReferences.connect_same_thread (masters_connections, boost::bind (&GainControl::master_going_away, this, vca));
+
}
if (old_master_val != new_master_val) {
@@ -142,7 +156,16 @@ GainControl::add_master (boost::shared_ptr<GainControl> m)
}
void
-GainControl::remove_master (boost::shared_ptr<GainControl> m)
+GainControl::master_going_away (boost::weak_ptr<VCA> wv)
+{
+ boost::shared_ptr<VCA> v = wv.lock();
+ if (v) {
+ remove_master (v);
+ }
+}
+
+void
+GainControl::remove_master (boost::shared_ptr<VCA> vca)
{
gain_t old_master_val;
gain_t new_master_val;
@@ -150,7 +173,8 @@ GainControl::remove_master (boost::shared_ptr<GainControl> m)
{
Glib::Threads::Mutex::Lock lm (master_lock);
old_master_val = get_master_gain_locked ();
- _masters.remove (m);
+ _masters.erase (vca->control());
+ _masters_numbers.erase (vca->number());
new_master_val = get_master_gain_locked ();
}
@@ -169,6 +193,7 @@ GainControl::clear_masters ()
Glib::Threads::Mutex::Lock lm (master_lock);
old_master_val = get_master_gain_locked ();
_masters.clear ();
+ _masters_numbers.clear ();
new_master_val = get_master_gain_locked ();
}
@@ -178,8 +203,61 @@ GainControl::clear_masters ()
}
bool
-GainControl::slaved_to (boost::shared_ptr<GainControl> gc) const
+GainControl::slaved_to (boost::shared_ptr<VCA> vca) const
{
Glib::Threads::Mutex::Lock lm (master_lock);
- return find (_masters.begin(), _masters.end(), gc) != _masters.end();
+ return find (_masters.begin(), _masters.end(), vca->control()) != _masters.end();
+}
+
+XMLNode&
+GainControl::get_state ()
+{
+ XMLNode& node (AutomationControl::get_state());
+
+ /* store VCA master IDs */
+
+ string str;
+
+ {
+ Glib::Threads::Mutex::Lock lm (master_lock);
+ for (set<uint32_t>::const_iterator m = _masters_numbers.begin(); m != _masters_numbers.end(); ++m) {
+ if (!str.empty()) {
+ str += ',';
+ }
+ str += PBD::to_string (*m, std::dec);
+ }
+ }
+
+ if (!str.empty()) {
+ node.add_property (X_("masters"), str);
+ }
+
+ return node;
+}
+
+int
+GainControl::set_state (XMLNode const& node, int version)
+{
+ AutomationControl::set_state (node, version);
+
+ XMLProperty const* prop = node.property (X_("masters"));
+
+ /* XXXProblem here if we allow VCA's to be slaved to other VCA's .. we
+ * have to load all VCAs first, then call ::set_state() so that
+ * vca_by_number() will succeed.
+ */
+
+ if (prop) {
+ vector<string> masters;
+ split (prop->value(), 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);
+ }
+ }
+ }
+
+ return 0;
}
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index 8b1f47ec4e..581031c405 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -5892,5 +5892,5 @@ Route::slaved_to (boost::shared_ptr<VCA> vca) const
return false;
}
- return _gain_control->slaved_to (vca->control());
+ return _gain_control->slaved_to (vca);
}
diff --git a/libs/ardour/vca.cc b/libs/ardour/vca.cc
index 9ae0c5a2dc..5afa31d38d 100644
--- a/libs/ardour/vca.cc
+++ b/libs/ardour/vca.cc
@@ -66,6 +66,11 @@ VCA::VCA (Session& s, XMLNode const & node, int version)
set_state (node, version);
}
+VCA::~VCA ()
+{
+ DropReferences (); /* emit signal */
+}
+
void
VCA::set_value (double val, Controllable::GroupControlDisposition gcd)
{
@@ -79,19 +84,6 @@ VCA::get_value() const
}
void
-VCA::add (boost::shared_ptr<Route> r)
-{
- boost::dynamic_pointer_cast<GainControl>(r->gain_control())->add_master (_control);
- std::cerr << name() << " now controlling " << r->name() << std::endl;
-}
-
-void
-VCA::remove (boost::shared_ptr<Route> r)
-{
- r->gain_control()->remove_master (_control);
-}
-
-void
VCA::set_name (string const& str)
{
_name = str;
diff --git a/libs/ardour/vca_manager.cc b/libs/ardour/vca_manager.cc
index 4daae2e9e2..420396bf07 100644
--- a/libs/ardour/vca_manager.cc
+++ b/libs/ardour/vca_manager.cc
@@ -146,7 +146,6 @@ VCAManager::set_state (XMLNode const& node, int version)
for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
if ((*i)->name() == VCA::xml_node_name) {
- std::cerr << "Adding VCA from XML\n";
boost::shared_ptr<VCA> vca = boost::shared_ptr<VCA> (new VCA (_session, **i, version));
_vcas.push_back (vca);
vcal.push_back (vca);