#include "evoral/types.hpp"
#include "evoral/Control.hpp"
-#include "ardour/libardour_visibility.h"
#include "ardour/automation_list.h"
+#include "ardour/control_group_member.h"
#include "ardour/parameter_descriptor.h"
+#include "ardour/libardour_visibility.h"
+
namespace ARDOUR {
class Session;
class Automatable;
-
+class ControlGroup;
/** A PBD::Controllable with associated automation data (AutomationList)
*/
: public PBD::Controllable
, public Evoral::Control
, public boost::enable_shared_from_this<AutomationControl>
+ , public ControlGroupMember
{
-public:
+ public:
AutomationControl(ARDOUR::Session&,
const Evoral::Parameter& parameter,
const ParameterDescriptor& desc,
void stop_touch(bool mark, double when);
/* inherited from PBD::Controllable.
- * Derived classes MUST call ::writable() to verify
- * that writing to the parameter is legal at that time.
*/
double get_value () const;
/* inherited from PBD::Controllable.
/* automation related value setting */
virtual bool writable () const;
/* Call to ::set_value() with no test for writable() because
- * this is only used by automation playback. We would like
- * to make it pure virtual
+ * this is only used by automation playback.
*/
- virtual void set_value_unchecked (double val) {}
+ void set_value_unchecked (double val) {
+ actually_set_value (val, PBD::Controllable::NoGroup);
+ }
double lower() const { return _desc.lower; }
double upper() const { return _desc.upper; }
const ARDOUR::Session& session() const { return _session; }
void commit_transaction (bool did_write);
- 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;
- bool slaved () const;
- std::vector<PBD::ID> masters () const;
-
- PBD::Signal0<void> MasterStatusChange;
-
protected:
ARDOUR::Session& _session;
+ boost::shared_ptr<ControlGroup> _group;
const ParameterDescriptor _desc;
+ bool check_rt (double val, Controllable::GroupControlDisposition gcd);
- class MasterRecord {
- public:
- MasterRecord (boost::shared_ptr<AutomationControl> gc, double r)
- : _master (gc)
- , _ratio (r)
- {}
-
- boost::shared_ptr<AutomationControl> master() const { return _master; }
- double ratio () const { return _ratio; }
- void reset_ratio (double r) { _ratio = r; }
-
- PBD::ScopedConnection connection;
-
- private:
- boost::shared_ptr<AutomationControl> _master;
- double _ratio;
+ /* derived classes may reimplement this, but should either
+ call this explicitly inside their version OR make sure that the
+ Controllable::Changed signal is emitted when necessary.
+ */
- };
+ virtual void actually_set_value (double value, PBD::Controllable::GroupControlDisposition);
- mutable Glib::Threads::RWLock master_lock;
- typedef std::map<PBD::ID,MasterRecord> Masters;
- Masters _masters;
- PBD::ScopedConnectionList masters_connections;
+ /* Session needs to call this method before it queues up the real
+ change for execution in a realtime context. C++ access control sucks.
+ */
+ friend class Session;
+ virtual void do_pre_realtime_queue_stuff (double new_value) {}
- void master_going_away (boost::weak_ptr<AutomationControl>);
- virtual void recompute_masters_ratios (double val) { /* do nothing by default */}
- virtual double get_masters_value_locked () const;
- double get_value_locked() const;
+ private:
+ /* I am unclear on why we have to make ControlGroup a friend in order
+ to get access to the ::set_group() method when it is already
+ declared to be a friend in ControlGroupMember. Oh well.
+ */
+ friend class ControlGroup;
+ void set_group (boost::shared_ptr<ControlGroup>);
};