Update Slavable API
Do not use AutomationType to identify parameters, use complete Evoral::Parameter and Automatable. For "batch connections", a Slavables needs to implement an API to return the relevant controls. This is only a first step towards a more generic Master/Slave framework.
This commit is contained in:
parent
faa52a3349
commit
9334c99b35
|
@ -117,6 +117,8 @@ public:
|
|||
|
||||
framepos_t _last_automation_snapshot;
|
||||
|
||||
SlavableControlList slavables () const { return SlavableControlList(); }
|
||||
|
||||
private:
|
||||
PBD::ScopedConnectionList _control_connections; ///< connections to our controls' signals
|
||||
};
|
||||
|
|
|
@ -686,6 +686,8 @@ protected:
|
|||
|
||||
boost::shared_ptr<Processor> the_instrument_unlocked() const;
|
||||
|
||||
SlavableControlList slavables () const;
|
||||
|
||||
private:
|
||||
int64_t _track_number;
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "evoral/Parameter.hpp"
|
||||
|
||||
#include "ardour/types.h"
|
||||
#include "ardour/libardour_visibility.h"
|
||||
|
||||
class XMLNode;
|
||||
|
@ -39,33 +40,39 @@ namespace ARDOUR {
|
|||
class VCA;
|
||||
class VCAManager;
|
||||
class AutomationControl;
|
||||
class SlavableAutomationControl;
|
||||
|
||||
class LIBARDOUR_API Slavable
|
||||
{
|
||||
public:
|
||||
public:
|
||||
Slavable ();
|
||||
virtual ~Slavable() {}
|
||||
|
||||
XMLNode& get_state () const;
|
||||
int set_state (XMLNode const&, int);
|
||||
|
||||
void assign (boost::shared_ptr<VCA>, bool loading);
|
||||
void assign (boost::shared_ptr<VCA>);
|
||||
void unassign (boost::shared_ptr<VCA>);
|
||||
|
||||
PBD::Signal2<void,boost::shared_ptr<VCA>,bool> AssignmentChange;
|
||||
|
||||
virtual boost::shared_ptr<AutomationControl> automation_control (const Evoral::Parameter& id) = 0;
|
||||
virtual boost::shared_ptr<AutomationControl> automation_control (const Evoral::Parameter&) = 0;
|
||||
|
||||
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>, bool loading);
|
||||
virtual int unassign_controls (boost::shared_ptr<VCA>);
|
||||
protected:
|
||||
virtual SlavableControlList slavables () const = 0;
|
||||
|
||||
private:
|
||||
bool assign_controls (boost::shared_ptr<VCA>);
|
||||
void unassign_controls (boost::shared_ptr<VCA>);
|
||||
|
||||
bool assign_control (boost::shared_ptr<VCA>, boost::shared_ptr<SlavableAutomationControl>);
|
||||
void unassign_control (boost::shared_ptr<VCA>, boost::shared_ptr<SlavableAutomationControl>);
|
||||
|
||||
private:
|
||||
mutable Glib::Threads::RWLock master_lock;
|
||||
std::set<uint32_t> _masters;
|
||||
PBD::ScopedConnection assign_connection;
|
||||
|
@ -73,7 +80,6 @@ class LIBARDOUR_API Slavable
|
|||
|
||||
int do_assign (VCAManager* s);
|
||||
void weak_unassign (boost::weak_ptr<VCA>);
|
||||
|
||||
};
|
||||
|
||||
} // namespace ARDOUR
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
|
||||
double get_value () const;
|
||||
|
||||
void add_master (boost::shared_ptr<AutomationControl>, bool loading);
|
||||
void add_master (boost::shared_ptr<AutomationControl>);
|
||||
void remove_master (boost::shared_ptr<AutomationControl>);
|
||||
void clear_masters ();
|
||||
bool slaved_to (boost::shared_ptr<AutomationControl>) const;
|
||||
|
|
|
@ -55,6 +55,7 @@ namespace ARDOUR {
|
|||
class Stripable;
|
||||
class VCA;
|
||||
class AutomationControl;
|
||||
class SlavableAutomationControl;
|
||||
|
||||
typedef float Sample;
|
||||
typedef float pan_t;
|
||||
|
@ -588,6 +589,7 @@ namespace ARDOUR {
|
|||
typedef std::list<boost::weak_ptr <Route> > WeakRouteList;
|
||||
typedef std::list<boost::weak_ptr <Stripable> > WeakStripableList;
|
||||
typedef std::list<boost::shared_ptr<AutomationControl> > ControlList;
|
||||
typedef std::list<boost::shared_ptr<SlavableAutomationControl> > SlavableControlList;
|
||||
|
||||
typedef std::list<boost::shared_ptr<VCA> > VCAList;
|
||||
|
||||
|
|
|
@ -146,6 +146,9 @@ class LIBARDOUR_API VCA : public Stripable,
|
|||
boost::shared_ptr<AutomationControl> eq_lpf_controllable () const { return boost::shared_ptr<AutomationControl>(); }
|
||||
boost::shared_ptr<AutomationControl> filter_enable_controllable () const { return boost::shared_ptr<AutomationControl>(); }
|
||||
|
||||
protected:
|
||||
SlavableControlList slavables () const;
|
||||
|
||||
private:
|
||||
int32_t _number;
|
||||
|
||||
|
|
|
@ -5516,3 +5516,13 @@ Route::automation_control_recurse (PBD::ID const & id) const
|
|||
|
||||
return boost::shared_ptr<AutomationControl> ();
|
||||
}
|
||||
|
||||
SlavableControlList
|
||||
Route::slavables () const
|
||||
{
|
||||
SlavableControlList rv;
|
||||
rv.push_back (_gain_control);
|
||||
rv.push_back (_mute_control);
|
||||
rv.push_back (_solo_control);
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ RouteGroup::add (boost::shared_ptr<Route> r)
|
|||
boost::shared_ptr<VCA> vca (group_master.lock());
|
||||
|
||||
if (vca) {
|
||||
r->assign (vca, false);
|
||||
r->assign (vca);
|
||||
}
|
||||
|
||||
_session.set_dirty ();
|
||||
|
@ -656,7 +656,7 @@ RouteGroup::assign_master (boost::shared_ptr<VCA> master)
|
|||
}
|
||||
|
||||
for (RouteList::iterator r = routes->begin(); r != routes->end(); ++r) {
|
||||
(*r)->assign (master, false);
|
||||
(*r)->assign (master);
|
||||
}
|
||||
|
||||
group_master = master;
|
||||
|
|
|
@ -82,18 +82,6 @@ Slavable::set_state (XMLNode const& node, int version)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Gain, solo & mute are currently the only controls that are
|
||||
* automatically slaved to the master's own equivalent controls.
|
||||
*/
|
||||
|
||||
static AutomationType auto_slave_types[] = {
|
||||
GainAutomation,
|
||||
SoloAutomation,
|
||||
MuteAutomation,
|
||||
NullAutomation
|
||||
};
|
||||
|
||||
int
|
||||
Slavable::do_assign (VCAManager* manager)
|
||||
{
|
||||
|
@ -117,18 +105,12 @@ Slavable::do_assign (VCAManager* manager)
|
|||
if (!vcas.empty()) {
|
||||
|
||||
for (std::vector<boost::shared_ptr<VCA> >::iterator v = vcas.begin(); v != vcas.end(); ++v) {
|
||||
assign (*v, true);
|
||||
assign (*v);
|
||||
}
|
||||
|
||||
for (uint32_t n = 0; auto_slave_types[n] != NullAutomation; ++n) {
|
||||
|
||||
boost::shared_ptr<SlavableAutomationControl> slave;
|
||||
|
||||
slave = boost::dynamic_pointer_cast<SlavableAutomationControl> (automation_control (auto_slave_types[n]));
|
||||
|
||||
if (slave) {
|
||||
slave->use_saved_master_ratios ();
|
||||
}
|
||||
SlavableControlList scl = slavables ();
|
||||
for (SlavableControlList::iterator i = scl.begin(); i != scl.end(); ++i) {
|
||||
(*i)->use_saved_master_ratios ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,12 +120,12 @@ Slavable::do_assign (VCAManager* manager)
|
|||
}
|
||||
|
||||
void
|
||||
Slavable::assign (boost::shared_ptr<VCA> v, bool loading)
|
||||
Slavable::assign (boost::shared_ptr<VCA> v)
|
||||
{
|
||||
assert (v);
|
||||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (master_lock);
|
||||
if (assign_controls (v, loading) == 0) {
|
||||
if (assign_controls (v)) {
|
||||
_masters.insert (v->number());
|
||||
}
|
||||
|
||||
|
@ -175,7 +157,7 @@ Slavable::unassign (boost::shared_ptr<VCA> v)
|
|||
{
|
||||
Glib::Threads::RWLock::WriterLock lm (master_lock);
|
||||
|
||||
(void) unassign_controls (v);
|
||||
unassign_controls (v);
|
||||
if (v) {
|
||||
_masters.erase (v->number());
|
||||
} else {
|
||||
|
@ -185,47 +167,49 @@ Slavable::unassign (boost::shared_ptr<VCA> v)
|
|||
AssignmentChange (v, false);
|
||||
}
|
||||
|
||||
int
|
||||
Slavable::assign_controls (boost::shared_ptr<VCA> vca, bool loading)
|
||||
bool
|
||||
Slavable::assign_controls (boost::shared_ptr<VCA> vca)
|
||||
{
|
||||
boost::shared_ptr<SlavableAutomationControl> slave;
|
||||
boost::shared_ptr<AutomationControl> master;
|
||||
|
||||
for (uint32_t n = 0; auto_slave_types[n] != NullAutomation; ++n) {
|
||||
|
||||
slave = boost::dynamic_pointer_cast<SlavableAutomationControl> (automation_control (auto_slave_types[n]));
|
||||
master = vca->automation_control (auto_slave_types[n]);
|
||||
|
||||
if (slave && master) {
|
||||
slave->add_master (master, loading);
|
||||
}
|
||||
bool rv = false;
|
||||
SlavableControlList scl = slavables ();
|
||||
for (SlavableControlList::iterator i = scl.begin(); i != scl.end(); ++i) {
|
||||
rv |= assign_control (vca, *i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
Slavable::unassign_controls (boost::shared_ptr<VCA> vca)
|
||||
{
|
||||
boost::shared_ptr<SlavableAutomationControl> slave;
|
||||
SlavableControlList scl = slavables ();
|
||||
for (SlavableControlList::iterator i = scl.begin(); i != scl.end(); ++i) {
|
||||
unassign_control (vca, *i);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Slavable::assign_control (boost::shared_ptr<VCA> vca, boost::shared_ptr<SlavableAutomationControl> slave)
|
||||
{
|
||||
boost::shared_ptr<AutomationControl> master;
|
||||
master = vca->automation_control (slave->parameter());
|
||||
if (!master) {
|
||||
return false;
|
||||
}
|
||||
slave->add_master (master);
|
||||
return true;
|
||||
}
|
||||
|
||||
for (uint32_t n = 0; auto_slave_types[n] != NullAutomation; ++n) {
|
||||
|
||||
slave = boost::dynamic_pointer_cast<SlavableAutomationControl> (automation_control (auto_slave_types[n]));
|
||||
|
||||
if (!vca) {
|
||||
/* unassign from all */
|
||||
if (slave) {
|
||||
slave->clear_masters ();
|
||||
}
|
||||
} else {
|
||||
master = vca->automation_control (auto_slave_types[n]);
|
||||
if (slave && master) {
|
||||
slave->remove_master (master);
|
||||
}
|
||||
void
|
||||
Slavable::unassign_control (boost::shared_ptr<VCA> vca, boost::shared_ptr<SlavableAutomationControl> slave)
|
||||
{
|
||||
if (!vca) {
|
||||
/* unassign from all */
|
||||
slave->clear_masters ();
|
||||
} else {
|
||||
boost::shared_ptr<AutomationControl> master;
|
||||
master = vca->automation_control (slave->parameter());
|
||||
if (master) {
|
||||
slave->remove_master (master);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ SlavableAutomationControl::actually_set_value (double value, PBD::Controllable::
|
|||
}
|
||||
|
||||
void
|
||||
SlavableAutomationControl::add_master (boost::shared_ptr<AutomationControl> m, bool loading)
|
||||
SlavableAutomationControl::add_master (boost::shared_ptr<AutomationControl> m)
|
||||
{
|
||||
std::pair<Masters::iterator,bool> res;
|
||||
|
||||
|
|
|
@ -207,3 +207,13 @@ VCA::slaved_to (boost::shared_ptr<VCA> vca) const
|
|||
|
||||
return _gain_control->slaved_to (vca->gain_control());
|
||||
}
|
||||
|
||||
SlavableControlList
|
||||
VCA::slavables () const
|
||||
{
|
||||
SlavableControlList rv;
|
||||
rv.push_back (_gain_control);
|
||||
rv.push_back (_mute_control);
|
||||
rv.push_back (_solo_control);
|
||||
return rv;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue