framepos_t _last_automation_snapshot;
+ SlavableControlList slavables () const { return SlavableControlList(); }
+
private:
PBD::ScopedConnectionList _control_connections; ///< connections to our controls' signals
};
boost::shared_ptr<Processor> the_instrument_unlocked() const;
+ SlavableControlList slavables () const;
+
private:
int64_t _track_number;
#include "evoral/Parameter.hpp"
+#include "ardour/types.h"
#include "ardour/libardour_visibility.h"
class XMLNode;
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;
int do_assign (VCAManager* s);
void weak_unassign (boost::weak_ptr<VCA>);
-
};
} // namespace ARDOUR
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;
class Stripable;
class VCA;
class AutomationControl;
+ class SlavableAutomationControl;
typedef float Sample;
typedef float pan_t;
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;
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;
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;
+}
boost::shared_ptr<VCA> vca (group_master.lock());
if (vca) {
- r->assign (vca, false);
+ r->assign (vca);
}
_session.set_dirty ();
}
for (RouteList::iterator r = routes->begin(); r != routes->end(); ++r) {
- (*r)->assign (master, false);
+ (*r)->assign (master);
}
group_master = master;
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)
{
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 ();
}
}
}
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());
}
{
Glib::Threads::RWLock::WriterLock lm (master_lock);
- (void) unassign_controls (v);
+ unassign_controls (v);
if (v) {
_masters.erase (v->number());
} else {
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;
- boost::shared_ptr<AutomationControl> master;
-
- for (uint32_t n = 0; auto_slave_types[n] != NullAutomation; ++n) {
+ SlavableControlList scl = slavables ();
+ for (SlavableControlList::iterator i = scl.begin(); i != scl.end(); ++i) {
+ unassign_control (vca, *i);
+ }
+}
- slave = boost::dynamic_pointer_cast<SlavableAutomationControl> (automation_control (auto_slave_types[n]));
+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;
+}
- 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;
}
}
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;
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;
+}