if ((r = _session->route_by_remote_id (rid)) != 0) {
- Track* t;
+ boost::shared_ptr<Track> t;
- if ((t = dynamic_cast<Track*>(r.get())) != 0) {
- t->set_record_enabled (!t->record_enabled(), this);
+ if ((t = boost::dynamic_pointer_cast<Track>(r)) != 0) {
+ t->set_record_enabled (!t->record_enabled(), Controllable::UseGroup);
}
}
}
first = false;
}
- rtav->track()->set_record_enabled (new_state, this);
+ rtav->track()->set_record_enabled (new_state, Controllable::UseGroup);
}
}
rl->push_back (rtav->route());
}
- _session->set_solo (rl, new_state, Session::rt_cleanup, true);
+ _session->set_solo (rl, new_state, Session::rt_cleanup, Controllable::UseGroup);
}
void
rl->push_back (rtav->route());
}
- _session->set_mute (rl, new_state, Session::rt_cleanup, true);
+ _session->set_mute (rl, new_state, Session::rt_cleanup, Controllable::UseGroup);
}
void
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tv);
if (rtv) {
- rtv->route()->set_solo_isolated (!rtv->route()->solo_isolated(), this);
+ rtv->route()->set_solo_isolated (!rtv->route()->solo_isolated(), Controllable::UseGroup);
}
}
RouteTimeAxisView* rtv = dynamic_cast<RouteTimeAxisView*> (tv);
if (rtv) {
- rtv->route()->set_solo_safe (!rtv->route()->solo_safe(), this);
+ rtv->route()->set_solo_safe (!rtv->route()->solo_safe(), Controllable::UseGroup);
}
}
}
(*x)->route()->mute_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_mute_display, this), gui_context());
- (*x)->route()->solo_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_display, this, _1), gui_context());
- (*x)->route()->listen_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_display, this, _1), gui_context());
+ (*x)->route()->solo_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_display, this), gui_context());
+ (*x)->route()->listen_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_display, this), gui_context());
(*x)->route()->solo_isolated_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_isolate_display, this), gui_context());
(*x)->route()->solo_safe_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_solo_safe_display, this), gui_context());
(*x)->route()->active_changed.connect (*this, MISSING_INVALIDATOR, boost::bind (&EditorRoutes::update_active_display, this), gui_context ());
update_rec_display ();
update_mute_display ();
- update_solo_display (true);
+ update_solo_display ();
update_solo_isolate_display ();
update_solo_safe_display ();
update_input_active_display ();
}
void
-EditorRoutes::update_solo_display (bool /* selfsoloed */)
+EditorRoutes::update_solo_display ()
{
if (g_atomic_int_compare_and_exchange (&_queue_tv_update, 0, 1)) {
Glib::signal_idle().connect (sigc::mem_fun (*this, &EditorRoutes::idle_update_mute_rec_solo_etc));
bool idle_update_mute_rec_solo_etc ();
void update_rec_display ();
void update_mute_display ();
- void update_solo_display (bool);
+ void update_solo_display ();
void update_solo_isolate_display ();
void update_solo_safe_display ();
void update_input_active_display ();
update_mute_display ();
update_solo_display ();
name_changed ();
- comment_changed (0);
+ comment_changed ();
route_group_changed ();
connect_to_pan ();
{
if (_session) {
boost::shared_ptr<RouteList> rl (_session->get_routes ());
- _session->set_solo_isolated (rl, false, Session::rt_cleanup, true);
+ _session->set_solo_isolated (rl, false, Session::rt_cleanup, Controllable::NoGroup);
}
return true;
_route->active_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::route_active_changed, this), gui_context());
_route->mute_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_mute_display, this), gui_context());
- _route->comment_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::comment_changed, this, _1), gui_context());
+ _route->comment_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::comment_changed, this), gui_context());
_route->solo_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
_route->solo_safe_changed.connect (route_connections, invalidator (*this), boost::bind (&RouteUI::update_solo_display, this), gui_context());
}
DisplaySuspender ds;
- _session->set_mute (rl, !_route->muted(), Session::rt_cleanup, true);
+ _session->set_mute (rl, !_route->muted(), Session::rt_cleanup, Controllable::WholeGroup);
}
} else {
{
if (_mute_release){
DisplaySuspender ds;
- _session->set_mute (_mute_release->routes, _mute_release->active, Session::rt_cleanup, true);
+ _session->set_mute (_mute_release->routes, _mute_release->active, Session::rt_cleanup, Controllable::UseGroup);
delete _mute_release;
_mute_release = 0;
}
DisplaySuspender ds;
if (Config->get_solo_control_is_listen_control()) {
- _session->set_listen (_session->get_routes(), !_route->listening_via_monitor(), Session::rt_cleanup, false);
+ _session->set_listen (_session->get_routes(), !_route->listening_via_monitor(), Session::rt_cleanup, Controllable::NoGroup);
} else {
- _session->set_solo (_session->get_routes(), !_route->self_soloed(), Session::rt_cleanup, false);
+ _session->set_solo (_session->get_routes(), !_route->self_soloed(), Session::rt_cleanup, Controllable::NoGroup);
}
} else if (Keyboard::modifier_state_contains (ev->state, Keyboard::ModifierMask (Keyboard::PrimaryModifier|Keyboard::SecondaryModifier))) {
// shift-click: toggle solo isolated status
- _route->set_solo_isolated (!_route->solo_isolated(), this);
+ _route->set_solo_isolated (!_route->solo_isolated(), Controllable::UseGroup);
delete _solo_release;
_solo_release = 0;
DisplaySuspender ds;
if (Config->get_solo_control_is_listen_control()) {
- _session->set_listen (rl, !_route->listening_via_monitor(), Session::rt_cleanup, true);
+ _session->set_listen (rl, !_route->listening_via_monitor(), Session::rt_cleanup, Controllable::WholeGroup);
} else {
- _session->set_solo (rl, !_route->self_soloed(), Session::rt_cleanup, true);
+ _session->set_solo (rl, !_route->self_soloed(), Session::rt_cleanup, Controllable::WholeGroup);
}
}
} else {
DisplaySuspender ds;
if (Config->get_solo_control_is_listen_control()) {
- _session->set_listen (_solo_release->routes, _solo_release->active, Session::rt_cleanup, false);
+ _session->set_listen (_solo_release->routes, _solo_release->active, Session::rt_cleanup, Controllable::UseGroup);
} else {
- _session->set_solo (_solo_release->routes, _solo_release->active, Session::rt_cleanup, false);
+ _session->set_solo (_solo_release->routes, _solo_release->active, Session::rt_cleanup, Controllable::UseGroup);
}
}
}
DisplaySuspender ds;
- _session->set_record_enabled (rl, !_route->record_enabled(), Session::rt_cleanup, true);
+ _session->set_record_enabled (rl, !_route->record_enabled(), Session::rt_cleanup, Controllable::WholeGroup);
}
} else if (Keyboard::is_context_menu_event (ev)) {
}
DisplaySuspender ds;
- _session->set_monitoring (rl, mc, Session::rt_cleanup, true);
+ _session->set_monitoring (rl, mc, Session::rt_cleanup, Controllable::UseGroup);
return false;
}
if (model) {
/* disable isolate for all routes */
DisplaySuspender ds;
- _session->set_solo_isolated (_session->get_routes(), false, Session::rt_cleanup, true);
+ _session->set_solo_isolated (_session->get_routes(), false, Session::rt_cleanup, Controllable::NoGroup);
} else {
/* enable isolate for all routes */
DisplaySuspender ds;
- _session->set_solo_isolated (_session->get_routes(), true, Session::rt_cleanup, true);
+ _session->set_solo_isolated (_session->get_routes(), true, Session::rt_cleanup, Controllable::NoGroup);
}
} else {
boost::shared_ptr<RouteList> rl (new RouteList);
rl->push_back (_route);
DisplaySuspender ds;
- _session->set_solo_isolated (rl, !view, Session::rt_cleanup, true);
+ _session->set_solo_isolated (rl, !view, Session::rt_cleanup, Controllable::NoGroup);
}
}
}
/* disable solo safe for all routes */
DisplaySuspender ds;
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
- (*i)->set_solo_safe (false, this);
+ (*i)->set_solo_safe (false, Controllable::NoGroup);
}
} else {
/* enable solo safe for all routes */
DisplaySuspender ds;
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
- (*i)->set_solo_safe (true, this);
+ (*i)->set_solo_safe (true, Controllable::NoGroup);
}
}
}
else {
if (model == view) {
/* flip just this route */
- _route->set_solo_safe (!view, this);
+ _route->set_solo_safe (!view, Controllable::NoGroup);
}
}
}
/* called AFTER the view has changed */
if (model != view) {
- _route->set_solo_isolated (view, this);
+ _route->set_solo_isolated (view, Controllable::UseGroup);
}
}
void
RouteUI::toggle_solo_safe (Gtk::CheckMenuItem* check)
{
- _route->set_solo_safe (check->get_active(), this);
+ _route->set_solo_safe (check->get_active(), Controllable::UseGroup);
}
/** Ask the user to choose a colour, and then apply that color to my route
}
void
-RouteUI::comment_changed (void *src)
+RouteUI::comment_changed ()
{
- ENSURE_GUI_THREAD (*this, &MixerStrip::comment_changed, src)
-
- if (src != this) {
- ignore_comment_edit = true;
- if (comment_area) {
- comment_area->get_buffer()->set_text (_route->comment());
- }
- ignore_comment_edit = false;
+ ignore_comment_edit = true;
+ if (comment_area) {
+ comment_area->get_buffer()->set_text (_route->comment());
}
+ ignore_comment_edit = false;
}
void
void toggle_comment_editor ();
gint comment_key_release_handler (GdkEventKey*);
- void comment_changed (void *src);
+ void comment_changed ();
void comment_edited ();
bool ignore_comment_edit;
class Session;
-struct LIBARDOUR_API GainControl : public AutomationControl {
+class LIBARDOUR_API GainControl : public AutomationControl {
+ public:
GainControl (Session& session, const Evoral::Parameter ¶m,
boost::shared_ptr<AutomationList> al = boost::shared_ptr<AutomationList>());
double lower_db;
double range_db;
+ private:
+ void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
};
} /* namespace */
boost::shared_ptr<Diskstream> create_diskstream ();
void set_diskstream (boost::shared_ptr<Diskstream>);
- void set_record_enabled (bool yn, void *src);
- void set_record_safe (bool yn, void *src);
+ void set_record_enabled (bool yn, PBD::Controllable::GroupControlDisposition);
+ void set_record_safe (bool yn, PBD::Controllable::GroupControlDisposition);
DataType data_type () const {
return DataType::MIDI;
bool writable() const { return true; }
MidiTrack* _route;
+
+ private:
+ void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
};
virtual void set_parameter_automation_state (Evoral::Parameter param, AutoState);
private:
Pannable* owner;
+ void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
};
} // namespace
private:
PluginInsert* _plugin;
+ void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
};
/** A control that manipulates a plugin property (message). */
virtual bool can_record() { return false; }
- virtual void set_record_enabled (bool /*yn*/, void * /*src*/) {}
+ virtual void set_record_enabled (bool /*yn*/, PBD::Controllable::GroupControlDisposition) {}
virtual bool record_enabled() const { return false; }
- virtual void set_record_safe (bool yn, void *src) {}
+ virtual void set_record_safe (bool /*yn*/, PBD::Controllable::GroupControlDisposition) {}
virtual bool record_safe () const {return false; }
virtual void nonrealtime_handle_transport_stopped (bool abort, bool did_locate, bool flush_processors);
virtual void realtime_handle_transport_stopped () {}
void set_gain (gain_t val, PBD::Controllable::GroupControlDisposition);
void inc_gain (gain_t delta);
- void set_trim (gain_t val, void *src);
+ void set_trim (gain_t val, PBD::Controllable::GroupControlDisposition);
void set_mute_points (MuteMaster::MutePoint);
MuteMaster::MutePoint mute_points () const;
bool muted () const;
- void set_mute (bool yn, void* src);
+ void set_mute (bool yn, PBD::Controllable::GroupControlDisposition);
bool muted_by_others() const;
/* controls use set_solo() to modify this route's solo state
*/
- void set_solo (bool yn, void *src, bool group_override = false);
+ void set_solo (bool yn, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
bool soloed () const { return self_soloed () || soloed_by_others (); }
void clear_all_solo_state ();
bool soloed_by_others_downstream () const { return _soloed_by_others_downstream; }
bool self_soloed () const { return _self_solo; }
- void set_solo_isolated (bool yn, void *src);
+ void set_solo_isolated (bool yn, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
bool solo_isolated() const;
- void set_solo_safe (bool yn, void *src);
+ void set_solo_safe (bool yn, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
bool solo_safe() const;
- void set_listen (bool yn, void* src, bool group_override = false);
+ void set_listen (bool yn, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
bool listening_via_monitor () const;
void enable_monitor_send ();
PBD::Signal0<void> active_changed;
PBD::Signal0<void> phase_invert_changed;
PBD::Signal0<void> denormal_protection_changed;
- PBD::Signal2<void,void*,bool> listen_changed;
- PBD::Signal3<void,bool,void*,bool> solo_changed;
- PBD::Signal1<void,void*> solo_safe_changed;
- PBD::Signal1<void,void*> solo_isolated_changed;
- PBD::Signal1<void,void*> comment_changed;
- PBD::Signal1<void,void*> mute_changed;
+ PBD::Signal1<void,PBD::Controllable::GroupControlDisposition> listen_changed;
+ PBD::Signal2<void,bool,PBD::Controllable::GroupControlDisposition> solo_changed;
+ PBD::Signal0<void> solo_safe_changed;
+ PBD::Signal0<void> solo_isolated_changed;
+ PBD::Signal0<void> comment_changed;
+ PBD::Signal0<void> mute_changed;
PBD::Signal0<void> mute_points_changed;
/** track numbers - assigned by session
void set_value (double, PBD::Controllable::GroupControlDisposition group_override);
void set_value_unchecked (double);
double get_value () const;
+ private:
+ void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
};
struct MuteControllable : public RouteAutomationControl {
private:
boost::weak_ptr<Route> _route;
+ void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
};
class LIBARDOUR_API PhaseControllable : public RouteAutomationControl {
public:
PhaseControllable (std::string name, boost::shared_ptr<Route>);
void set_value (double, PBD::Controllable::GroupControlDisposition group_override);
+ /* currently no automation, so no need for set_value_unchecked() */
void set_channel (uint32_t);
double get_value () const;
uint32_t channel() const;
private:
uint32_t _current_phase;
+ void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
};
void set_control (AutomationType, double val, PBD::Controllable::GroupControlDisposition group_override);
bool _solo_isolated;
uint32_t _solo_isolated_by_upstream;
- void mod_solo_isolated_by_upstream (bool, void*);
+ void mod_solo_isolated_by_upstream (bool);
bool _denormal_protection;
#include <string>
#include <stdint.h>
+#include "pbd/controllable.h"
#include "pbd/signals.h"
#include "pbd/stateful.h"
-#include "pbd/signals.h"
#include "ardour/libardour_visibility.h"
#include "ardour/types.h"
/* to use these, #include "ardour/route_group_specialized.h" */
- template<class T> void apply (void (Track::*func)(T, void *), T val, void *src);
+ template<class T> void apply (void (Track::*func)(T, PBD::Controllable::GroupControlDisposition), T val, PBD::Controllable::GroupControlDisposition);
/* fills at_set with all members of the group that are AudioTracks */
int set_state (const XMLNode&, int version);
-private:
+ private:
boost::shared_ptr<RouteList> routes;
boost::shared_ptr<Route> subgroup_bus;
#ifndef __libardour_route_group_member_h__
#define __libardour_route_group_member_h__
+#include "pbd/controllable.h"
#include "pbd/signals.h"
namespace ARDOUR {
/** Emitted when this member joins or leaves a route group */
PBD::Signal0<void> route_group_changed;
+ bool use_group (PBD::Controllable::GroupControlDisposition gcd, bool (RouteGroup::*predicate)(void) const) const;
+
protected:
RouteGroup* _route_group;
namespace ARDOUR {
template<class T> void
-RouteGroup::apply (void (Track::*func)(T, void *), T val, void* /*src*/)
+RouteGroup::apply (void (Track::*func)(T, PBD::Controllable::GroupControlDisposition), T val, PBD::Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = routes->begin(); i != routes->end(); i++) {
boost::shared_ptr<Track> at;
if ((at = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
- (at.get()->*func)(val, this);
+ (at.get()->*func)(val, group_override);
}
}
}
static const SessionEvent::RTeventCallback rt_cleanup;
- void set_solo (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
+ void set_solo (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
void clear_all_solo_state (boost::shared_ptr<RouteList>);
void set_just_one_solo (boost::shared_ptr<Route>, bool, SessionEvent::RTeventCallback after = rt_cleanup);
- void set_mute (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
- void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
- void set_record_enabled (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
- void set_record_safe (boost::shared_ptr<RouteList>, bool yn, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
- void set_solo_isolated (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
- void set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, SessionEvent::RTeventCallback after = rt_cleanup, bool group_override = false);
- void set_exclusive_input_active (boost::shared_ptr<RouteList> rt, bool onoff, bool flip_others=false);
+ void set_mute (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
+ void set_listen (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
+ void set_record_enabled (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
+ void set_record_safe (boost::shared_ptr<RouteList>, bool yn, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
+ void set_solo_isolated (boost::shared_ptr<RouteList>, bool, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
+ void set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, SessionEvent::RTeventCallback after = rt_cleanup, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup);
+ void set_exclusive_input_active (boost::shared_ptr<RouteList> rt, bool onoff, bool flip_others = false);
PBD::Signal1<void,bool> SoloActive;
PBD::Signal0<void> SoloChanged;
/* mixer stuff */
- void route_listen_changed (bool group_override, boost::weak_ptr<Route>);
- void route_mute_changed (void *src);
- void route_solo_changed (bool self_solo_change, bool group_override, boost::weak_ptr<Route>);
- void route_solo_isolated_changed (void *src, boost::weak_ptr<Route>);
+ void route_listen_changed (PBD::Controllable::GroupControlDisposition, boost::weak_ptr<Route>);
+ void route_mute_changed ();
+ void route_solo_changed (bool self_solo_change, PBD::Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route>);
+ void route_solo_isolated_changed (boost::weak_ptr<Route>);
void update_route_solo_state (boost::shared_ptr<RouteList> r = boost::shared_ptr<RouteList>());
void listen_position_changed ();
/* realtime "apply to set of routes" operations */
template<typename T> SessionEvent*
- get_rt_event (boost::shared_ptr<RouteList> rl, T targ, SessionEvent::RTeventCallback after, bool group_override,
- void (Session::*method) (boost::shared_ptr<RouteList>, T, bool)) {
+ get_rt_event (boost::shared_ptr<RouteList> rl, T targ, SessionEvent::RTeventCallback after, PBD::Controllable::GroupControlDisposition group_override,
+ void (Session::*method) (boost::shared_ptr<RouteList>, T, PBD::Controllable::GroupControlDisposition)) {
SessionEvent* ev = new SessionEvent (SessionEvent::RealTimeOperation, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0);
ev->rt_slot = boost::bind (method, this, rl, targ, group_override);
ev->rt_return = after;
return ev;
}
- void rt_set_solo (boost::shared_ptr<RouteList>, bool yn, bool group_override);
- void rt_clear_all_solo_state (boost::shared_ptr<RouteList>, bool yn, bool group_override);
- void rt_set_just_one_solo (boost::shared_ptr<RouteList>, bool yn, bool /* ignored*/ );
- void rt_set_mute (boost::shared_ptr<RouteList>, bool yn, bool group_override);
- void rt_set_listen (boost::shared_ptr<RouteList>, bool yn, bool group_override);
- void rt_set_solo_isolated (boost::shared_ptr<RouteList>, bool yn, bool group_override);
- void rt_set_record_enabled (boost::shared_ptr<RouteList>, bool yn, bool group_override);
- void rt_set_record_safe (boost::shared_ptr<RouteList>, bool yn, bool group_override);
- void rt_set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, bool group_override);
+ void rt_set_solo (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
+ void rt_clear_all_solo_state (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
+ void rt_set_just_one_solo (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition /* ignored*/ );
+ void rt_set_mute (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
+ void rt_set_listen (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
+ void rt_set_solo_isolated (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
+ void rt_set_record_enabled (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
+ void rt_set_record_safe (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override);
+ void rt_set_monitoring (boost::shared_ptr<RouteList>, MonitorChoice, PBD::Controllable::GroupControlDisposition group_override);
/** temporary list of Diskstreams used only during load of 2.X sessions */
std::list<boost::shared_ptr<Diskstream> > _diskstreams_2X;
bool record_enabled() const;
bool record_safe () const;
- void set_record_enabled (bool yn, void *src);
- void set_record_safe (bool yn, void *src);
- void prep_record_enabled (bool yn, void *src);
+ void set_record_enabled (bool yn, PBD::Controllable::GroupControlDisposition);
+ void set_record_safe (bool yn, PBD::Controllable::GroupControlDisposition);
+ void prep_record_enabled (bool yn, PBD::Controllable::GroupControlDisposition);
bool using_diskstream_id (PBD::ID) const;
FreezeState state;
};
- struct RecEnableControl : public AutomationControl {
+ class RecEnableControl : public AutomationControl {
+ public:
RecEnableControl (boost::shared_ptr<Track> t);
void set_value (double, PBD::Controllable::GroupControlDisposition);
double get_value (void) const;
boost::weak_ptr<Track> track;
+
+ private:
+ void _set_value (double, PBD::Controllable::GroupControlDisposition);
};
virtual void set_state_part_two () = 0;
}
void
-GainControl::set_value (double val, PBD::Controllable::GroupControlDisposition /* group_override */)
+GainControl::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
if (writable()) {
- set_value_unchecked (val);
+ _set_value (val, group_override);
}
}
void
GainControl::set_value_unchecked (double val)
{
- AutomationControl::set_value (std::max (std::min (val, (double)_desc.upper), (double)_desc.lower), Controllable::NoGroup);
+ /* used only automation playback */
+ _set_value (val, Controllable::NoGroup);
+}
+
+void
+GainControl::_set_value (double val, Controllable::GroupControlDisposition group_override)
+{
+ AutomationControl::set_value (std::max (std::min (val, (double)_desc.upper), (double)_desc.lower), group_override);
_session.set_dirty ();
}
void
-MidiTrack::set_record_enabled (bool yn, void *src)
+MidiTrack::set_record_enabled (bool yn, Controllable::GroupControlDisposition group_override)
{
if (_step_editing) {
return;
}
- Track::set_record_enabled (yn, src);
+ Track::set_record_enabled (yn, group_override);
}
void
-MidiTrack::set_record_safe (bool yn, void *src)
+MidiTrack::set_record_safe (bool yn, Controllable::GroupControlDisposition group_override)
{
if (_step_editing) { /* REQUIRES REVIEW */
return;
}
- Track::set_record_safe (yn, src);
+ Track::set_record_safe (yn, group_override);
}
void
}
void
-MidiTrack::MidiControl::set_value (double val, PBD::Controllable::GroupControlDisposition /* group_override */)
+MidiTrack::MidiControl::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
if (writable()) {
- set_value_unchecked (val);
+ _set_value (val, group_override);
}
}
void
-MidiTrack::MidiControl::set_value_unchecked(double val)
+MidiTrack::MidiControl::set_value_unchecked (double val)
+{
+ /* used only by automation playback */
+ _set_value (val, Controllable::NoGroup);
+}
+
+void
+MidiTrack::MidiControl::_set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
const Evoral::Parameter ¶meter = _list ? _list->parameter() : Control::parameter();
const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter);
_route->write_immediate_event(size, ev);
}
- AutomationControl::set_value(val, Controllable::NoGroup);
+ AutomationControl::set_value(val, group_override);
}
void
}
void
-PanControllable::set_value (double v, PBD::Controllable::GroupControlDisposition /* group_override */)
+PanControllable::set_value (double v, PBD::Controllable::GroupControlDisposition group_override)
{
if (writable()) {
- set_value_unchecked (v);
+ _set_value (v, group_override);
}
}
-
void
PanControllable::set_value_unchecked (double v)
+{
+ /* used only automation playback */
+ _set_value (v, Controllable::NoGroup);
+}
+
+void
+PanControllable::_set_value (double v, Controllable::GroupControlDisposition group_override)
{
boost::shared_ptr<Panner> p = owner->panner();
if (!p) {
/* no panner: just do it */
- AutomationControl::set_value (v, Controllable::NoGroup);
+ AutomationControl::set_value (v, group_override);
return;
}
}
if (can_set) {
- AutomationControl::set_value (v, Controllable::NoGroup);
+ AutomationControl::set_value (v, group_override);
}
}
/** @param val `user' value */
void
-PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition /* group_override */)
+PluginInsert::PluginControl::set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
{
if (writable()) {
- set_value_unchecked (user_val);
+ _set_value (user_val, group_override);
}
}
-
void
PluginInsert::PluginControl::set_value_unchecked (double user_val)
+{
+ /* used only by automation playback */
+ _set_value (user_val, Controllable::NoGroup);
+}
+
+void
+PluginInsert::PluginControl::_set_value (double user_val, PBD::Controllable::GroupControlDisposition group_override)
{
/* FIXME: probably should be taking out some lock here.. */
iasp->set_parameter (_list->parameter().id(), user_val);
}
- AutomationControl::set_value (user_val, Controllable::NoGroup);
+ AutomationControl::set_value (user_val, group_override);
}
void
void
Route::set_gain (gain_t val, Controllable::GroupControlDisposition group_override)
{
- if (_route_group && (group_override != Controllable::NoGroup) && _route_group->is_active() && _route_group->is_gain()) {
+ if (use_group (group_override, &RouteGroup::is_gain)) {
if (_route_group->is_relative()) {
}
void
-Route::set_trim (gain_t val, void * /* src */)
+Route::set_trim (gain_t val, Controllable::GroupControlDisposition /* group override */)
{
// TODO route group, see set_gain()
_trim_control->route_set_value (val);
}
void
-Route::set_listen (bool yn, void* src, bool group_override)
+Route::set_listen (bool yn, Controllable::GroupControlDisposition group_override)
{
if (_solo_safe) {
return;
}
- bool group_active = _route_group && _route_group->is_active() && _route_group->is_solo();
- if (group_override && _route_group) {
- group_active = !group_active;
- }
-
- if (_route_group && src != _route_group && group_active) {
- _route_group->foreach_route (boost::bind (&Route::set_listen, _1, yn, _route_group, group_override));
+ if (use_group (group_override, &RouteGroup::is_solo)) {
+ _route_group->foreach_route (boost::bind (&Route::set_listen, _1, yn, Controllable::NoGroup));
return;
}
}
_mute_master->set_soloed_by_others (false);
- listen_changed (src, group_override); /* EMIT SIGNAL */
+ listen_changed (group_override); /* EMIT SIGNAL */
}
}
}
}
void
-Route::set_solo_safe (bool yn, void *src)
+Route::set_solo_safe (bool yn, Controllable::GroupControlDisposition /* group_override */)
{
if (_solo_safe != yn) {
_solo_safe = yn;
- solo_safe_changed (src);
+ solo_safe_changed ();
}
}
{
PBD::Unwinder<bool> uw (_solo_safe, false);
- set_solo (false, this);
+ set_solo (false, Controllable::NoGroup);
}
if (emit_changed) {
set_mute_master_solo ();
- solo_changed (false, this, false); /* EMIT SIGNAL */
+ solo_changed (false, Controllable::UseGroup); /* EMIT SIGNAL */
}
}
void
-Route::set_solo (bool yn, void *src, bool group_override)
+Route::set_solo (bool yn, Controllable::GroupControlDisposition group_override)
{
if (_solo_safe) {
DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 ignore solo change due to solo-safe\n", name()));
return;
}
- bool group_active = _route_group && _route_group->is_active() && _route_group->is_solo();
- if (group_override && _route_group) {
- group_active = !group_active;
- }
- if (_route_group && src != _route_group && group_active) {
- _route_group->foreach_route (boost::bind (&Route::set_solo, _1, yn, _route_group, group_override));
+ if (use_group (group_override, &RouteGroup::is_solo)) {
+ _route_group->foreach_route (boost::bind (&Route::set_solo, _1, yn, Controllable::NoGroup));
return;
}
- DEBUG_TRACE (DEBUG::Solo, string_compose ("%1: set solo => %2, src: %3 grp ? %4 currently self-soloed ? %5\n",
- name(), yn, src, (src == _route_group), self_soloed()));
+ DEBUG_TRACE (DEBUG::Solo, string_compose ("%1: set solo => %2, grp ? %3 currently self-soloed ? %4\n",
+ name(), yn, enum_2_string(group_override), self_soloed()));
if (self_soloed() != yn) {
set_self_solo (yn);
- solo_changed (true, src, group_override); /* EMIT SIGNAL */
+ solo_changed (true, group_override); /* EMIT SIGNAL */
_solo_control->Changed (); /* EMIT SIGNAL */
}
*/
if (yn && Profile->get_trx()) {
- set_mute (false, src);
+ set_mute (false, Controllable::UseGroup);
}
}
}
set_mute_master_solo ();
- solo_changed (false, this, false); /* EMIT SIGNAL */
+ solo_changed (false, Controllable::UseGroup); /* EMIT SIGNAL */
}
void
DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 SbD delta %2 = %3\n", name(), delta, _soloed_by_others_downstream));
set_mute_master_solo ();
- solo_changed (false, this, false); /* EMIT SIGNAL */
+ solo_changed (false, Controllable::UseGroup); /* EMIT SIGNAL */
}
void
}
void
-Route::mod_solo_isolated_by_upstream (bool yn, void* src)
+Route::mod_solo_isolated_by_upstream (bool yn)
{
bool old = solo_isolated ();
DEBUG_TRACE (DEBUG::Solo, string_compose ("%1 mod_solo_isolated_by_upstream cur: %2 d: %3\n",
if (solo_isolated() != old) {
/* solo isolated status changed */
_mute_master->set_solo_ignore (solo_isolated());
- solo_isolated_changed (src); /* EMIT SIGNAL */
+ solo_isolated_changed (); /* EMIT SIGNAL */
}
}
void
-Route::set_solo_isolated (bool yn, void *src)
+Route::set_solo_isolated (bool yn, Controllable::GroupControlDisposition group_override)
{
if (is_master() || is_monitor() || is_auditioner()) {
return;
}
- if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_solo()) {
- _route_group->foreach_route (boost::bind (&Route::set_solo_isolated, _1, yn, _route_group));
+ if (use_group (group_override, &RouteGroup::is_solo)) {
+ _route_group->foreach_route (boost::bind (&Route::set_solo_isolated, _1, yn, Controllable::NoGroup));
return;
}
bool does_feed = feeds (*i, &sends_only);
if (does_feed && !sends_only) {
- (*i)->mod_solo_isolated_by_upstream (yn, src);
+ (*i)->mod_solo_isolated_by_upstream (yn);
}
}
/* XXX should we back-propagate as well? (April 2010: myself and chris goddard think not) */
- solo_isolated_changed (src); /* EMIT SIGNAL */
+ solo_isolated_changed (); /* EMIT SIGNAL */
}
bool
mute_points_changed (); /* EMIT SIGNAL */
if (_mute_master->muted_by_self()) {
- mute_changed (this); /* EMIT SIGNAL */
+ mute_changed (); /* EMIT SIGNAL */
_mute_control->Changed (); /* EMIT SIGNAL */
}
}
void
-Route::set_mute (bool yn, void *src)
+Route::set_mute (bool yn, Controllable::GroupControlDisposition group_override)
{
- if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_mute()) {
- _route_group->foreach_route (boost::bind (&Route::set_mute, _1, yn, _route_group));
+ if (use_group (group_override, &RouteGroup::is_mute)) {
+ _route_group->foreach_route (boost::bind (&Route::set_mute, _1, yn, Controllable::NoGroup));
return;
}
*/
act_on_mute ();
/* tell everyone else */
- mute_changed (src); /* EMIT SIGNAL */
+ mute_changed (); /* EMIT SIGNAL */
_mute_control->Changed (); /* EMIT SIGNAL */
}
}
}
if ((prop = node.property ("solo-isolated")) != 0) {
- set_solo_isolated (string_is_affirmative (prop->value()), this);
+ set_solo_isolated (string_is_affirmative (prop->value()), Controllable::NoGroup);
}
if ((prop = node.property ("solo-safe")) != 0) {
- set_solo_safe (string_is_affirmative (prop->value()), this);
+ set_solo_safe (string_is_affirmative (prop->value()), Controllable::NoGroup);
}
if ((prop = node.property (X_("phase-invert"))) != 0) {
/* XXX force reset of solo status */
- set_solo (yn, this);
+ set_solo (yn);
}
if ((prop = node.property (X_("muted"))) != 0) {
Route::set_comment (string cmt, void *src)
{
_comment = cmt;
- comment_changed (src);
+ comment_changed ();
_session.set_dirty ();
}
if (_solo_isolated_by_upstream) {
// solo-isolate currently only propagates downstream
if (idelta < 0) {
- mod_solo_isolated_by_upstream (false, this);
+ mod_solo_isolated_by_upstream (false);
}
// TODO think: mod_solo_isolated_by_upstream() does not take delta arg,
// but idelta can't be smaller than -1, can it?
}
if (idelta < 0 && does_feed && !sends_only) {
- (*i)->mod_solo_isolated_by_upstream (false, this);
+ (*i)->mod_solo_isolated_by_upstream (false);
}
}
}
switch (type) {
case GainAutomation:
/* route must mediate group control */
- set_gain (val, group_override);
+ set_gain (val, group_override);
return;
break;
case TrimAutomation:
/* route must mediate group control */
- set_trim (val, this); /* any "src" argument will do other than our route group */
+ set_trim (val, group_override); /* any "src" argument will do other than our route group */
return;
break;
/* session must mediate group control */
rl.reset (new RouteList);
rl->push_back (shared_from_this());
- _session.set_record_enabled (rl, val >= 0.5 ? true : false);
+ _session.set_record_enabled (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
return;
break;
rl.reset (new RouteList);
rl->push_back (shared_from_this());
if (Config->get_solo_control_is_listen_control()) {
- _session.set_listen (rl, val >= 0.5 ? true : false);
+ _session.set_listen (rl, val >= 0.5 ? true : false, Session::rt_cleanup, group_override);
} else {
_session.set_solo (rl, val >= 0.5 ? true : false);
}
/* session must mediate group control */
rl.reset (new RouteList);
rl->push_back (shared_from_this());
- _session.set_mute (rl, !muted());
+ _session.set_mute (rl, !muted(), Session::rt_cleanup, group_override);
return;
break;
}
void
-Route::SoloControllable::set_value (double val, PBD::Controllable::GroupControlDisposition /* group_override */)
+Route::SoloControllable::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
if (writable()) {
- set_value_unchecked (val);
+ _set_value (val, group_override);
}
}
void
-Route::SoloControllable::set_value_unchecked (double val)
+Route::SoloControllable::_set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
const bool bval = ((val >= 0.5) ? true : false);
rl->push_back (r);
if (Config->get_solo_control_is_listen_control()) {
- _session.set_listen (rl, bval);
+ _session.set_listen (rl, bval, Session::rt_cleanup, group_override);
} else {
- _session.set_solo (rl, bval);
+ _session.set_solo (rl, bval, Session::rt_cleanup, group_override);
}
}
+void
+Route::SoloControllable::set_value_unchecked (double val)
+{
+ /* Used only by automation playback */
+
+ _set_value (val, Controllable::NoGroup);
+}
+
double
Route::SoloControllable::get_value () const
{
}
void
-Route::MuteControllable::set_value (double val, PBD::Controllable::GroupControlDisposition /* group_override */)
+Route::MuteControllable::set_value (double val, PBD::Controllable::GroupControlDisposition group_override)
{
if (writable()) {
- set_value_unchecked (val);
+ _set_value (val, group_override);
}
}
void
Route::MuteControllable::set_value_unchecked (double val)
+{
+ /* used only automation playback */
+ _set_value (val, Controllable::NoGroup);
+}
+
+void
+Route::MuteControllable::_set_value (double val, Controllable::GroupControlDisposition group_override)
{
const bool bval = ((val >= 0.5) ? true : false);
// Set superficial/automation value to drive controller (and possibly record)
set_superficial_value (bval);
// Playing back automation, set route mute directly
- r->set_mute (bval, this);
+ r->set_mute (bval, Controllable::NoGroup);
} else {
// Set from user, queue mute event
boost::shared_ptr<RouteList> rl (new RouteList);
rl->push_back (r);
- _session.set_mute (rl, bval, Session::rt_cleanup);
+ _session.set_mute (rl, bval, Session::rt_cleanup, group_override);
}
}
#include "ardour/libardour_visibility.h"
#include "ardour/route_group_member.h"
+#include "ardour/route_group.h"
using namespace ARDOUR;
_route_group = rg;
route_group_changed (); /* EMIT SIGNAL */
}
+
+bool
+RouteGroupMember::use_group (PBD::Controllable::GroupControlDisposition gcd, bool (RouteGroup::*predicate)(void) const) const
+{
+ return (gcd != PBD::Controllable::NoGroup) &&
+ (_route_group &&
+ ((gcd == PBD::Controllable::WholeGroup) ||
+ (_route_group->is_active() && (_route_group->*predicate)())));
+}
boost::weak_ptr<Route> wpr (*x);
boost::shared_ptr<Route> r (*x);
- r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _2, wpr));
- r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _3, wpr));
- r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, _1, wpr));
- r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this, _1));
+ r->listen_changed.connect_same_thread (*this, boost::bind (&Session::route_listen_changed, this, _1, wpr));
+ r->solo_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_changed, this, _1, _2, wpr));
+ r->solo_isolated_changed.connect_same_thread (*this, boost::bind (&Session::route_solo_isolated_changed, this, wpr));
+ r->mute_changed.connect_same_thread (*this, boost::bind (&Session::route_mute_changed, this));
r->output()->changed.connect_same_thread (*this, boost::bind (&Session::set_worst_io_latencies_x, this, _1, _2));
r->processors_changed.connect_same_thread (*this, boost::bind (&Session::route_processors_changed, this, _1));
continue;
}
- (*iter)->set_solo (false, this);
+ (*iter)->set_solo (false, Controllable::NoGroup);
rs->remove (*iter);
}
void
-Session::route_mute_changed (void* /*src*/)
+Session::route_mute_changed ()
{
set_dirty ();
}
void
-Session::route_listen_changed (bool group_override, boost::weak_ptr<Route> wpr)
+Session::route_listen_changed (Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
{
boost::shared_ptr<Route> route = wpr.lock();
if (!route) {
if (route->listening_via_monitor ()) {
if (Config->get_exclusive_solo()) {
- /* new listen: disable all other listen, except solo-grouped channels */
+
RouteGroup* rg = route->route_group ();
- bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
- if (group_override && rg) {
- leave_group_alone = !leave_group_alone;
- }
+ const bool group_already_accounted_for = route->use_group (group_override, &RouteGroup::is_solo);
+
boost::shared_ptr<RouteList> r = routes.reader ();
+
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- if ((*i) == route || (*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() || (leave_group_alone && ((*i)->route_group() == rg))) {
+ if ((*i) == route) {
+ /* already changed */
+ continue;
+ }
+
+ if ((*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner()) {
+ /* route does not get solo propagated to it */
+ continue;
+ }
+
+ if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
+ /* this route is a part of the same solo group as the route
+ * that was changed. Changing that route did change or will
+ * change all group members appropriately, so we can ignore it
+ * here
+ */
continue;
}
- (*i)->set_listen (false, this, group_override);
+ (*i)->set_listen (false, Controllable::NoGroup);
}
}
update_route_solo_state ();
}
void
-Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
+Session::route_solo_isolated_changed (boost::weak_ptr<Route> wpr)
{
boost::shared_ptr<Route> route = wpr.lock ();
}
void
-Session::route_solo_changed (bool self_solo_change, bool group_override, boost::weak_ptr<Route> wpr)
+Session::route_solo_changed (bool self_solo_change, Controllable::GroupControlDisposition group_override, boost::weak_ptr<Route> wpr)
{
DEBUG_TRACE (DEBUG::Solo, string_compose ("route solo change, self = %1\n", self_solo_change));
delta = -1;
}
+ /* the route may be a member of a group that has shared-solo
+ * semantics. If so, then all members of that group should follow the
+ * solo of the changed route. But ... this is optional, controlled by a
+ * Controllable::GroupControlDisposition.
+ *
+ * The first argument to the signal that this method is connected to is the
+ * GroupControlDisposition value that was used to change solo.
+ *
+ * If the solo change was done with group semantics (either WholeGroup
+ * (force the entire group to change even if the group shared solo is
+ * disabled) or UseGroup (use the group, which may or may not have the
+ * shared solo property enabled)) then as we propagate the change to
+ * the entire session we should IGNORE THE GROUP that the changed route
+ * belongs to.
+ */
+
RouteGroup* rg = route->route_group ();
- bool leave_group_alone = (rg && rg->is_active() && rg->is_solo());
- if (group_override && rg) {
- leave_group_alone = !leave_group_alone;
- }
+ const bool group_already_accounted_for = route->use_group (group_override, &RouteGroup::is_solo);
+
if (delta == 1 && Config->get_exclusive_solo()) {
/* new solo: disable all other solos, but not the group if its solo-enabled */
for (RouteList::iterator i = r->begin(); i != r->end(); ++i) {
- if ((*i) == route || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() ||
- (leave_group_alone && ((*i)->route_group() == rg))) {
+
+ if ((*i) == route) {
+ /* already changed */
+ continue;
+ }
+
+ if ((*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner()) {
+ /* route does not get solo propagated to it */
+ continue;
+ }
+
+ if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
+ /* this route is a part of the same solo group as the route
+ * that was changed. Changing that route did change or will
+ * change all group members appropriately, so we can ignore it
+ * here
+ */
continue;
}
- (*i)->set_solo (false, this, group_override);
+
+ (*i)->set_solo (false, group_override);
}
}
bool via_sends_only;
bool in_signal_flow;
- if ((*i) == route || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner() ||
- (leave_group_alone && ((*i)->route_group() == rg))) {
+ if ((*i) == route) {
+ /* already changed */
+ continue;
+ }
+
+ if ((*i)->solo_isolated() || (*i)->is_master() || (*i)->is_monitor() || (*i)->is_auditioner()) {
+ /* route does not get solo propagated to it */
+ continue;
+ }
+
+ if ((group_already_accounted_for && (*i)->route_group() && (*i)->route_group() == rg)) {
+ /* this route is a part of the same solo group as the route
+ * that was changed. Changing that route did change or will
+ * change all group members appropriately, so we can ignore it
+ * here
+ */
continue;
}
for (RouteList::iterator i = uninvolved.begin(); i != uninvolved.end(); ++i) {
DEBUG_TRACE (DEBUG::Solo, string_compose ("mute change for %1, which neither feeds or is fed by %2\n", (*i)->name(), route->name()));
(*i)->act_on_mute ();
- (*i)->mute_changed (this);
+ (*i)->mute_changed ();
}
SoloChanged (); /* EMIT SIGNAL */
listeners++;
something_listening = true;
} else {
- (*i)->set_listen (false, this);
+ (*i)->set_listen (false, Controllable::NoGroup);
}
}
if ((at = dynamic_cast<AudioTrack*>((*i).get())) != 0) {
if (trk == at->remote_control_id()) {
- at->set_record_enabled (enabled, &mmc);
+ at->set_record_enabled (enabled, Controllable::UseGroup);
break;
}
}
using namespace Glib;
void
-Session::set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, SessionEvent::RTeventCallback after, bool group_override)
+Session::set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc,
+ SessionEvent::RTeventCallback after,
+ Controllable::GroupControlDisposition group_override)
{
queue_event (get_rt_event (rl, mc, after, group_override, &Session::rt_set_monitoring));
}
void
-Session::rt_set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, bool /* group_override */)
+Session::rt_set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, Controllable::GroupControlDisposition /*group_override*/)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if (!(*i)->is_auditioner()) {
void
Session::clear_all_solo_state (boost::shared_ptr<RouteList> rl)
{
- queue_event (get_rt_event (rl, false, rt_cleanup, false, &Session::rt_clear_all_solo_state));
+ queue_event (get_rt_event (rl, false, rt_cleanup, Controllable::NoGroup, &Session::rt_clear_all_solo_state));
}
void
-Session::rt_clear_all_solo_state (boost::shared_ptr<RouteList> rl, bool /* yn */, bool /* group_override */)
+Session::rt_clear_all_solo_state (boost::shared_ptr<RouteList> rl, bool /* yn */, Controllable::GroupControlDisposition /* group_override */)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if ((*i)->is_auditioner()) {
}
void
-Session::set_solo (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
+Session::set_solo (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after,
+ Controllable::GroupControlDisposition group_override)
{
queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_solo));
}
void
-Session::rt_set_solo (boost::shared_ptr<RouteList> rl, bool yn, bool group_override)
+Session::rt_set_solo (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if (!(*i)->is_auditioner()) {
- (*i)->set_solo (yn, this, group_override);
+ (*i)->set_solo (yn, group_override);
}
}
boost::shared_ptr<RouteList> rl (new RouteList);
rl->push_back (r);
- queue_event (get_rt_event (rl, yn, after, false, &Session::rt_set_just_one_solo));
+ queue_event (get_rt_event (rl, yn, after, Controllable::NoGroup, &Session::rt_set_just_one_solo));
}
void
-Session::rt_set_just_one_solo (boost::shared_ptr<RouteList> just_one, bool yn, bool /*ignored*/)
+Session::rt_set_just_one_solo (boost::shared_ptr<RouteList> just_one, bool yn, Controllable::GroupControlDisposition /*ignored*/)
{
boost::shared_ptr<RouteList> rl = routes.reader ();
boost::shared_ptr<Route> r = just_one->front();
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if (!(*i)->is_auditioner() && r != *i) {
- (*i)->set_solo (!yn, (*i)->route_group());
+ (*i)->set_solo (!yn, Controllable::NoGroup);
}
}
- r->set_solo (yn, r->route_group());
+ r->set_solo (yn, Controllable::NoGroup);
set_dirty();
}
void
-Session::set_listen (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
+Session::set_listen (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
{
queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_listen));
}
void
-Session::rt_set_listen (boost::shared_ptr<RouteList> rl, bool yn, bool group_override)
+Session::rt_set_listen (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if (!(*i)->is_auditioner()) {
- (*i)->set_listen (yn, this, group_override);
+ (*i)->set_listen (yn, group_override);
}
}
}
void
-Session::set_mute (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
+Session::set_mute (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
{
/* Set superficial value of mute controls for automation. */
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
}
void
-Session::rt_set_mute (boost::shared_ptr<RouteList> rl, bool yn, bool /*group_override*/)
+Session::rt_set_mute (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if (!(*i)->is_monitor() && !(*i)->is_auditioner()) {
- (*i)->set_mute (yn, this);
+ (*i)->set_mute (yn, group_override);
}
}
}
void
-Session::set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
+Session::set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
{
queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_solo_isolated));
}
void
-Session::rt_set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, bool /*group_override*/)
+Session::rt_set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner()) {
- (*i)->set_solo_isolated (yn, this);
+ (*i)->set_solo_isolated (yn, group_override);
}
}
}
void
-Session::set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
+Session::set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
{
if (!writable()) {
return;
boost::shared_ptr<Track> t;
if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
- t->prep_record_enabled (yn, (group_override ? (void*) t->route_group() : (void *) this));
+ t->prep_record_enabled (yn, group_override);
}
}
}
void
-Session::rt_set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, bool group_override)
+Session::rt_set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
if ((*i)->is_auditioner() || (*i)->record_safe ()) {
boost::shared_ptr<Track> t;
if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
- t->set_record_enabled (yn, (group_override ? (void*) t->route_group() : (void *) this));
+ t->set_record_enabled (yn, group_override);
}
}
void
-Session::set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
+Session::set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
{
set_record_enabled (rl, false, after, group_override);
queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_record_safe));
}
void
-Session::rt_set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, bool group_override)
+Session::rt_set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
{
for (RouteList::iterator i = rl->begin (); i != rl->end (); ++i) {
if ((*i)->is_auditioner ()) { // REQUIRES REVIEW Can audiotioner be in Record Safe mode?
boost::shared_ptr<Track> t;
if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
- t->set_record_safe (yn, (group_override ? (void*) t->route_group () : (void *) this));
+ t->set_record_safe (yn, group_override);
}
}
}
void
-Track::RecEnableControl::set_value (double val, Controllable::GroupControlDisposition /* group_override */)
+Track::RecEnableControl::set_value (double val, Controllable::GroupControlDisposition group_override)
{
if (writable()) {
- set_value_unchecked (val);
+ _set_value (val, group_override);
}
}
void
Track::RecEnableControl::set_value_unchecked (double val)
+{
+ if (writable()) {
+ _set_value (val, Controllable::NoGroup);
+ }
+}
+
+void
+Track::RecEnableControl::_set_value (double val, Controllable::GroupControlDisposition group_override)
{
boost::shared_ptr<Track> t = track.lock ();
if (!t) {
return;
}
- t->set_record_enabled (val >= 0.5 ? true : false, this);
+ t->set_record_enabled (val >= 0.5 ? true : false, group_override);
}
double
}
void
-Track::prep_record_enabled (bool yn, void *src)
+Track::prep_record_enabled (bool yn, Controllable::GroupControlDisposition group_override)
{
if (yn && record_safe ()) {
return;
return;
}
- if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) {
- _route_group->apply (&Track::prep_record_enabled, yn, _route_group);
+ if (use_group (group_override, &RouteGroup::is_recenable)) {
+ _route_group->apply (&Track::prep_record_enabled, yn, Controllable::NoGroup);
return;
}
}
void
-Track::set_record_enabled (bool yn, void *src)
+Track::set_record_enabled (bool yn, Controllable::GroupControlDisposition group_override)
{
if (_diskstream->record_safe ()) {
return;
return;
}
- if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) {
- _route_group->apply (&Track::set_record_enabled, yn, _route_group);
+ if (use_group (group_override, &RouteGroup::is_recenable)) {
+ _route_group->apply (&Track::set_record_enabled, yn, Controllable::NoGroup);
return;
}
}
void
-Track::set_record_safe (bool yn, void *src)
+Track::set_record_safe (bool yn, Controllable::GroupControlDisposition group_override)
{
- if (!_session.writable()) { /* REQUIRES REVIEW */
+ if (!_session.writable()) {
return;
}
- if (_freeze_record.state == Frozen) { /* REQUIRES REVIEW */
+ if (_freeze_record.state == Frozen) {
return;
}
- if (_route_group && src != _route_group && _route_group->is_active() && _route_group->is_recenable()) {
- _route_group->apply (&Track::set_record_safe, yn, _route_group);
+ if (use_group (group_override, &RouteGroup::is_recenable)) {
+ _route_group->apply (&Track::set_record_safe, yn, Controllable::NoGroup);
return;
}
}
return rv ? MeteringInput : MeteringRoute;
}
-
boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack>(r);
if (at) {
- at->set_record_enabled (yn, this);
+ at->set_record_enabled (yn, Controllable::NoGroup);
}
}
boost::shared_ptr<Route> r = route_table[table_index];
if (r != 0) {
- r->set_mute (yn, this);
+ r->set_mute (yn, Controllable::UseGroup);
}
}
boost::shared_ptr<Route> r = route_table[table_index];
if (r != 0) {
- r->set_solo (yn, this);
+ r->set_solo (yn, Controllable::UseGroup);
}
}
if (_current_route) {
_current_route->DropReferences.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::drop_current_route, this), this);
- _current_route->mute_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_mute, this, _1), this);
- _current_route->solo_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_solo, this, _1, _2, _3), this);
- _current_route->listen_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_listen, this, _1, _2), this);
+ _current_route->mute_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_mute, this), this);
+ _current_route->solo_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_solo, this), this);
+ _current_route->listen_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&FaderPort::map_listen, this), this);
boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (_current_route);
if (t) {
}
void
-FaderPort::map_mute (void*)
+FaderPort::map_mute ()
{
if (_current_route) {
if (_current_route->muted()) {
}
void
-FaderPort::map_solo (bool, void*, bool)
+FaderPort::map_solo ()
{
if (_current_route) {
get_button (Solo).set_led_state (_output_port, _current_route->soloed() || _current_route->listening_via_monitor());
}
void
-FaderPort::map_listen (void*, bool)
+FaderPort::map_listen ()
{
if (_current_route) {
get_button (Solo).set_led_state (_output_port, _current_route->listening_via_monitor());
stop_blinking (Solo);
get_button (Rec).set_led_state (_output_port, false);
} else {
- /* arguments to these map_*() methods are all ignored */
- map_solo (false, 0, false);
+ map_solo ();
map_recenable ();
map_gain ();
map_auto ();
if (_current_route == session->monitor_out()) {
map_cut ();
} else {
- map_mute (0);
+ map_mute ();
}
}
}
PBD::ScopedConnectionList route_connections;
void map_route_state ();
- void map_solo (bool,void*,bool);
- void map_listen (void*,bool);
- void map_mute (void*);
+ void map_solo ();
+ void map_listen ();
+ void map_mute ();
void map_recenable ();
void map_gain ();
void map_cut ();
DEBUG_TRACE (DEBUG::MackieControl, "add button on press\n");
_surface->mcp().add_down_button ((AutomationType) control->parameter().type(), _surface->number(), _index);
- float new_value;
- int ms = _surface->mcp().main_modifier_state();
-
- if (ms & MackieControlProtocol::MODIFIER_SHIFT) {
- /* reset to default/normal value */
- new_value = control->normal();
- } else {
- new_value = control->get_value() ? 0.0 : 1.0;
- }
+ float new_value = control->get_value() ? 0.0 : 1.0;
/* get all controls that either have their
* button down or are within a range of
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("there are %1 buttons down for control type %2, new value = %3\n",
controls.size(), control->parameter().type(), new_value));
- /* apply change */
+ /* apply change, with potential modifier semantics */
+
+ Controllable::GroupControlDisposition gcd;
+
+ if (_surface->mcp().main_modifier_state() & MackieControlProtocol::MODIFIER_SHIFT) {
+ gcd = Controllable::NoGroup;
+ } else {
+ gcd = Controllable::UseGroup;
+ }
for (MackieControlProtocol::ControlList::iterator c = controls.begin(); c != controls.end(); ++c) {
- (*c)->set_value (new_value, Controllable::NoGroup);
+ (*c)->set_value (new_value, gcd);
}
} else {
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
if (r) {
- r->set_mute (yn, this);
+ r->set_mute (yn, PBD::Controllable::NoGroup);
}
return 0;
if (r) {
boost::shared_ptr<RouteList> rl (new RouteList);
rl->push_back (r);
- session->set_solo (rl, yn);
+ session->set_solo (rl, yn, Session::rt_cleanup, PBD::Controllable::NoGroup);
}
return 0;
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
if (r) {
- r->set_record_enabled (yn, this);
+ r->set_record_enabled (yn, PBD::Controllable::NoGroup);
}
return 0;
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
if (r) {
- r->set_trim (level, this);
+ r->set_trim (level, PBD::Controllable::NoGroup);
}
return 0;