mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-13 18:16:35 +01:00
change API for GainControl, VCA and VCAManager
This allows sane state save/restore
This commit is contained in:
parent
cab88c6aad
commit
35172bb369
6 changed files with 104 additions and 29 deletions
|
|
@ -20,7 +20,7 @@
|
||||||
#define __ardour_gain_control_h__
|
#define __ardour_gain_control_h__
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <set>
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <glibmm/threads.h>
|
#include <glibmm/threads.h>
|
||||||
|
|
@ -54,20 +54,28 @@ class LIBARDOUR_API GainControl : public AutomationControl {
|
||||||
double range_db;
|
double range_db;
|
||||||
|
|
||||||
gain_t get_master_gain () const;
|
gain_t get_master_gain () const;
|
||||||
void add_master (boost::shared_ptr<GainControl>);
|
void add_master (boost::shared_ptr<VCA>);
|
||||||
void remove_master (boost::shared_ptr<GainControl>);
|
void remove_master (boost::shared_ptr<VCA>);
|
||||||
void clear_masters ();
|
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:
|
private:
|
||||||
void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
|
void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
|
||||||
|
|
||||||
mutable Glib::Threads::Mutex master_lock;
|
mutable Glib::Threads::Mutex master_lock;
|
||||||
|
|
||||||
typedef std::list<boost::shared_ptr<GainControl> > Masters;
|
typedef std::set<boost::shared_ptr<GainControl> > Masters;
|
||||||
Masters _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;
|
gain_t get_master_gain_locked () const;
|
||||||
|
void master_going_away (boost::weak_ptr<VCA>);
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace */
|
} /* namespace */
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ class LIBARDOUR_API VCA : public SessionHandleRef, public PBD::StatefulDestructi
|
||||||
public:
|
public:
|
||||||
VCA (Session& session, const std::string& name, uint32_t num);
|
VCA (Session& session, const std::string& name, uint32_t num);
|
||||||
VCA (Session& session, XMLNode const&, int version);
|
VCA (Session& session, XMLNode const&, int version);
|
||||||
|
~VCA();
|
||||||
|
|
||||||
std::string name() const { return _name; }
|
std::string name() const { return _name; }
|
||||||
uint32_t number () const { return _number; }
|
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; }
|
boost::shared_ptr<GainControl> control() const { return _control; }
|
||||||
|
|
||||||
void add (boost::shared_ptr<Route>);
|
|
||||||
void remove (boost::shared_ptr<Route>);
|
|
||||||
|
|
||||||
XMLNode& get_state();
|
XMLNode& get_state();
|
||||||
int set_state (XMLNode const&, int version);
|
int set_state (XMLNode const&, int version);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,14 @@
|
||||||
675 Mass Ave, Cambridge, MA 02139, USA.
|
675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "pbd/convert.h"
|
||||||
|
#include "pbd/strsplit.h"
|
||||||
|
|
||||||
#include "ardour/dB.h"
|
#include "ardour/dB.h"
|
||||||
#include "ardour/gain_control.h"
|
#include "ardour/gain_control.h"
|
||||||
#include "ardour/session.h"
|
#include "ardour/session.h"
|
||||||
|
#include "ardour/vca.h"
|
||||||
|
#include "ardour/vca_manager.h"
|
||||||
|
|
||||||
#include "i18n.h"
|
#include "i18n.h"
|
||||||
|
|
||||||
|
|
@ -124,7 +129,7 @@ GainControl::get_master_gain_locked () const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GainControl::add_master (boost::shared_ptr<GainControl> m)
|
GainControl::add_master (boost::shared_ptr<VCA> vca)
|
||||||
{
|
{
|
||||||
gain_t old_master_val;
|
gain_t old_master_val;
|
||||||
gain_t new_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);
|
Glib::Threads::Mutex::Lock lm (master_lock);
|
||||||
old_master_val = get_master_gain_locked ();
|
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 ();
|
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) {
|
if (old_master_val != new_master_val) {
|
||||||
|
|
@ -142,7 +156,16 @@ GainControl::add_master (boost::shared_ptr<GainControl> m)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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 old_master_val;
|
||||||
gain_t new_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);
|
Glib::Threads::Mutex::Lock lm (master_lock);
|
||||||
old_master_val = get_master_gain_locked ();
|
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 ();
|
new_master_val = get_master_gain_locked ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,6 +193,7 @@ GainControl::clear_masters ()
|
||||||
Glib::Threads::Mutex::Lock lm (master_lock);
|
Glib::Threads::Mutex::Lock lm (master_lock);
|
||||||
old_master_val = get_master_gain_locked ();
|
old_master_val = get_master_gain_locked ();
|
||||||
_masters.clear ();
|
_masters.clear ();
|
||||||
|
_masters_numbers.clear ();
|
||||||
new_master_val = get_master_gain_locked ();
|
new_master_val = get_master_gain_locked ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -178,8 +203,61 @@ GainControl::clear_masters ()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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);
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5892,5 +5892,5 @@ Route::slaved_to (boost::shared_ptr<VCA> vca) const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _gain_control->slaved_to (vca->control());
|
return _gain_control->slaved_to (vca);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,11 @@ VCA::VCA (Session& s, XMLNode const & node, int version)
|
||||||
set_state (node, version);
|
set_state (node, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VCA::~VCA ()
|
||||||
|
{
|
||||||
|
DropReferences (); /* emit signal */
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
VCA::set_value (double val, Controllable::GroupControlDisposition gcd)
|
VCA::set_value (double val, Controllable::GroupControlDisposition gcd)
|
||||||
{
|
{
|
||||||
|
|
@ -78,19 +83,6 @@ VCA::get_value() const
|
||||||
return _control->get_value();
|
return _control->get_value();
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
void
|
||||||
VCA::set_name (string const& str)
|
VCA::set_name (string const& str)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,6 @@ VCAManager::set_state (XMLNode const& node, int version)
|
||||||
|
|
||||||
for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
|
for (XMLNodeList::const_iterator i = children.begin(); i != children.end(); ++i) {
|
||||||
if ((*i)->name() == VCA::xml_node_name) {
|
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));
|
boost::shared_ptr<VCA> vca = boost::shared_ptr<VCA> (new VCA (_session, **i, version));
|
||||||
_vcas.push_back (vca);
|
_vcas.push_back (vca);
|
||||||
vcal.push_back (vca);
|
vcal.push_back (vca);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue