mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 15:54:57 +01:00
change VCA model to facilitate Harrison *and* SSL designs
This commit is contained in:
parent
3daad04936
commit
405f9fc712
3 changed files with 78 additions and 26 deletions
|
|
@ -20,7 +20,10 @@
|
|||
#define __ardour_gain_control_h__
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <glibmm/threads.h>
|
||||
|
||||
#include "pbd/controllable.h"
|
||||
|
||||
|
|
@ -51,12 +54,18 @@ class LIBARDOUR_API GainControl : public AutomationControl {
|
|||
double lower_db;
|
||||
double range_db;
|
||||
|
||||
boost::shared_ptr<GainControl> master() const { return _master; }
|
||||
void set_master (boost::shared_ptr<GainControl>);
|
||||
void add_master (boost::shared_ptr<GainControl>);
|
||||
void remove_master (boost::shared_ptr<GainControl>);
|
||||
void clear_masters ();
|
||||
|
||||
private:
|
||||
void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
|
||||
boost::shared_ptr<GainControl> _master;
|
||||
gain_t get_master_gain () const;
|
||||
|
||||
mutable Glib::Threads::Mutex master_lock;
|
||||
|
||||
typedef std::list<boost::shared_ptr<GainControl> > Masters;
|
||||
Masters _masters;
|
||||
};
|
||||
|
||||
} /* namespace */
|
||||
|
|
|
|||
|
|
@ -39,10 +39,17 @@ GainControl::GainControl (Session& session, const Evoral::Parameter ¶m, boos
|
|||
double
|
||||
GainControl::get_value() const
|
||||
{
|
||||
if (!_master) {
|
||||
Glib::Threads::Mutex::Lock sm (master_lock, Glib::Threads::TRY_LOCK);
|
||||
|
||||
if (sm.locked()) {
|
||||
if (_masters.empty()) {
|
||||
return AutomationControl::get_value();
|
||||
}
|
||||
return AutomationControl::get_value() * _master->get_value();
|
||||
return AutomationControl::get_value() * get_master_gain ();
|
||||
} else {
|
||||
/* could not take lock */
|
||||
return AutomationControl::get_value ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -106,25 +113,31 @@ GainControl::get_user_string () const
|
|||
return std::string(theBuf);
|
||||
}
|
||||
|
||||
void
|
||||
GainControl::set_master (boost::shared_ptr<GainControl> m)
|
||||
gain_t
|
||||
GainControl::get_master_gain () const
|
||||
{
|
||||
double old_master_val;
|
||||
/* Master lock MUST be held */
|
||||
|
||||
if (_master) {
|
||||
old_master_val = _master->get_value();
|
||||
} else {
|
||||
old_master_val = 1.0;
|
||||
gain_t g = 1.0;
|
||||
|
||||
for (Masters::const_iterator m = _masters.begin(); m != _masters.end(); ++m) {
|
||||
g *= (*m)->get_value ();
|
||||
}
|
||||
|
||||
_master = m;
|
||||
return g;
|
||||
}
|
||||
|
||||
double new_master_val;
|
||||
void
|
||||
GainControl::add_master (boost::shared_ptr<GainControl> m)
|
||||
{
|
||||
gain_t old_master_val;
|
||||
gain_t new_master_val;
|
||||
|
||||
if (_master) {
|
||||
new_master_val = _master->get_value();
|
||||
} else {
|
||||
new_master_val = 1.0;
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (master_lock);
|
||||
old_master_val = get_master_gain ();
|
||||
_masters.push_back (m);
|
||||
new_master_val = get_master_gain ();
|
||||
}
|
||||
|
||||
if (old_master_val != new_master_val) {
|
||||
|
|
@ -132,3 +145,38 @@ GainControl::set_master (boost::shared_ptr<GainControl> m)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
GainControl::remove_master (boost::shared_ptr<GainControl> m)
|
||||
{
|
||||
gain_t old_master_val;
|
||||
gain_t new_master_val;
|
||||
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (master_lock);
|
||||
old_master_val = get_master_gain ();
|
||||
_masters.remove (m);
|
||||
new_master_val = get_master_gain ();
|
||||
}
|
||||
|
||||
if (old_master_val != new_master_val) {
|
||||
Changed(); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GainControl::clear_masters ()
|
||||
{
|
||||
gain_t old_master_val;
|
||||
gain_t new_master_val;
|
||||
|
||||
{
|
||||
Glib::Threads::Mutex::Lock lm (master_lock);
|
||||
old_master_val = get_master_gain ();
|
||||
_masters.clear ();
|
||||
new_master_val = get_master_gain ();
|
||||
}
|
||||
|
||||
if (old_master_val != new_master_val) {
|
||||
Changed(); /* EMIT SIGNAL */
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,16 +47,11 @@ VCA::get_value() const
|
|||
void
|
||||
VCA::add (boost::shared_ptr<Route> r)
|
||||
{
|
||||
boost::dynamic_pointer_cast<GainControl>(r->gain_control())->set_master (_control);
|
||||
boost::dynamic_pointer_cast<GainControl>(r->gain_control())->add_master (_control);
|
||||
}
|
||||
|
||||
void
|
||||
VCA::remove (boost::shared_ptr<Route> r)
|
||||
{
|
||||
boost::shared_ptr<GainControl> route_gain = boost::dynamic_pointer_cast<GainControl>(r->gain_control());
|
||||
boost::shared_ptr<GainControl> current_master = route_gain->master();
|
||||
|
||||
if (current_master == _control) {
|
||||
route_gain->set_master (boost::shared_ptr<GainControl>());
|
||||
}
|
||||
r->gain_control()->remove_master (_control);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue