summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/ardour_ui.cc6
-rw-r--r--gtk2_ardour/editor_ops.cc6
-rw-r--r--gtk2_ardour/editor_routes.cc12
-rw-r--r--gtk2_ardour/editor_routes.h2
-rw-r--r--gtk2_ardour/mixer_strip.cc2
-rw-r--r--gtk2_ardour/monitor_section.cc2
-rw-r--r--gtk2_ardour/route_ui.cc54
-rw-r--r--gtk2_ardour/route_ui.h2
-rw-r--r--libs/ardour/ardour/gain_control.h5
-rw-r--r--libs/ardour/ardour/midi_track.h7
-rw-r--r--libs/ardour/ardour/pan_controllable.h1
-rw-r--r--libs/ardour/ardour/plugin_insert.h1
-rw-r--r--libs/ardour/ardour/route.h35
-rw-r--r--libs/ardour/ardour/route_group.h6
-rw-r--r--libs/ardour/ardour/route_group_member.h3
-rw-r--r--libs/ardour/ardour/route_group_specialized.h4
-rw-r--r--libs/ardour/ardour/session.h46
-rw-r--r--libs/ardour/ardour/track.h12
-rw-r--r--libs/ardour/gain_control.cc13
-rw-r--r--libs/ardour/midi_track.cc23
-rw-r--r--libs/ardour/pan_controllable.cc16
-rw-r--r--libs/ardour/plugin_insert.cc14
-rw-r--r--libs/ardour/route.cc126
-rw-r--r--libs/ardour/route_group_member.cc10
-rw-r--r--libs/ardour/session.cc112
-rw-r--r--libs/ardour/session_midi.cc2
-rw-r--r--libs/ardour/session_rtevents.cc57
-rw-r--r--libs/ardour/track.cc37
-rw-r--r--libs/surfaces/control_protocol/control_protocol.cc6
-rw-r--r--libs/surfaces/faderport/faderport.cc17
-rw-r--r--libs/surfaces/faderport/faderport.h6
-rw-r--r--libs/surfaces/mackie/strip.cc22
-rw-r--r--libs/surfaces/osc/osc.cc8
33 files changed, 400 insertions, 275 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index 1ea6700b52..4d6a0a72d5 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -2247,10 +2247,10 @@ ARDOUR_UI::toggle_record_enable (uint32_t rid)
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);
}
}
}
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index 814cded541..55d38f3a88 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -5701,7 +5701,7 @@ Editor::toggle_record_enable ()
first = false;
}
- rtav->track()->set_record_enabled (new_state, this);
+ rtav->track()->set_record_enabled (new_state, Controllable::UseGroup);
}
}
@@ -5727,7 +5727,7 @@ Editor::toggle_solo ()
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
@@ -5752,7 +5752,7 @@ Editor::toggle_mute ()
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
diff --git a/gtk2_ardour/editor_routes.cc b/gtk2_ardour/editor_routes.cc
index 588b900f19..e4a48db5af 100644
--- a/gtk2_ardour/editor_routes.cc
+++ b/gtk2_ardour/editor_routes.cc
@@ -453,7 +453,7 @@ EditorRoutes::on_tv_solo_isolate_toggled (std::string const & path_string)
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);
}
}
@@ -467,7 +467,7 @@ EditorRoutes::on_tv_solo_safe_toggled (std::string const & path_string)
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);
}
}
@@ -711,8 +711,8 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
}
(*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 ());
@@ -721,7 +721,7 @@ EditorRoutes::routes_added (list<RouteTimeAxisView*> routes)
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 ();
@@ -1632,7 +1632,7 @@ EditorRoutes::update_mute_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));
diff --git a/gtk2_ardour/editor_routes.h b/gtk2_ardour/editor_routes.h
index 94a2186a4c..bee37378fb 100644
--- a/gtk2_ardour/editor_routes.h
+++ b/gtk2_ardour/editor_routes.h
@@ -86,7 +86,7 @@ private:
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 ();
diff --git a/gtk2_ardour/mixer_strip.cc b/gtk2_ardour/mixer_strip.cc
index 5247d89033..64b4494bac 100644
--- a/gtk2_ardour/mixer_strip.cc
+++ b/gtk2_ardour/mixer_strip.cc
@@ -637,7 +637,7 @@ MixerStrip::set_route (boost::shared_ptr<Route> rt)
update_mute_display ();
update_solo_display ();
name_changed ();
- comment_changed (0);
+ comment_changed ();
route_group_changed ();
connect_to_pan ();
diff --git a/gtk2_ardour/monitor_section.cc b/gtk2_ardour/monitor_section.cc
index 0741bffa5d..d07ca51dd5 100644
--- a/gtk2_ardour/monitor_section.cc
+++ b/gtk2_ardour/monitor_section.cc
@@ -1210,7 +1210,7 @@ MonitorSection::cancel_isolate (GdkEventButton*)
{
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;
diff --git a/gtk2_ardour/route_ui.cc b/gtk2_ardour/route_ui.cc
index 059f20a885..ddba45b73f 100644
--- a/gtk2_ardour/route_ui.cc
+++ b/gtk2_ardour/route_ui.cc
@@ -259,7 +259,7 @@ RouteUI::set_route (boost::shared_ptr<Route> rp)
_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());
@@ -426,7 +426,7 @@ RouteUI::mute_press (GdkEventButton* ev)
}
DisplaySuspender ds;
- _session->set_mute (rl, !_route->muted(), Session::rt_cleanup, true);
+ _session->set_mute (rl, !_route->muted(), Session::rt_cleanup, Controllable::WholeGroup);
}
} else {
@@ -454,7 +454,7 @@ RouteUI::mute_release (GdkEventButton* /*ev*/)
{
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;
}
@@ -555,9 +555,9 @@ RouteUI::solo_press(GdkEventButton* ev)
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))) {
@@ -589,7 +589,7 @@ RouteUI::solo_press(GdkEventButton* ev)
// 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;
@@ -620,9 +620,9 @@ RouteUI::solo_press(GdkEventButton* ev)
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);
}
}
@@ -663,9 +663,9 @@ RouteUI::solo_release (GdkEventButton* /*ev*/)
} 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);
}
}
@@ -735,7 +735,7 @@ RouteUI::rec_enable_press(GdkEventButton* ev)
}
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)) {
@@ -865,7 +865,7 @@ RouteUI::monitor_release (GdkEventButton* ev, MonitorChoice monitor_choice)
}
DisplaySuspender ds;
- _session->set_monitoring (rl, mc, Session::rt_cleanup, true);
+ _session->set_monitoring (rl, mc, Session::rt_cleanup, Controllable::UseGroup);
return false;
}
@@ -1437,11 +1437,11 @@ RouteUI::solo_isolate_button_release (GdkEventButton* ev)
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 {
@@ -1453,7 +1453,7 @@ RouteUI::solo_isolate_button_release (GdkEventButton* ev)
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);
}
}
}
@@ -1478,20 +1478,20 @@ RouteUI::solo_safe_button_release (GdkEventButton* ev)
/* 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);
}
}
}
@@ -1508,14 +1508,14 @@ RouteUI::toggle_solo_isolated (Gtk::CheckMenuItem* check)
/* 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
@@ -1702,17 +1702,13 @@ RouteUI::setup_comment_editor ()
}
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
diff --git a/gtk2_ardour/route_ui.h b/gtk2_ardour/route_ui.h
index ff4d45300f..461419c848 100644
--- a/gtk2_ardour/route_ui.h
+++ b/gtk2_ardour/route_ui.h
@@ -241,7 +241,7 @@ class RouteUI : public virtual AxisView
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;
diff --git a/libs/ardour/ardour/gain_control.h b/libs/ardour/ardour/gain_control.h
index 17c250151a..07a900a164 100644
--- a/libs/ardour/ardour/gain_control.h
+++ b/libs/ardour/ardour/gain_control.h
@@ -33,7 +33,8 @@ namespace ARDOUR {
class Session;
-struct LIBARDOUR_API GainControl : public AutomationControl {
+class LIBARDOUR_API GainControl : public AutomationControl {
+ public:
GainControl (Session& session, const Evoral::Parameter &param,
boost::shared_ptr<AutomationList> al = boost::shared_ptr<AutomationList>());
@@ -48,6 +49,8 @@ struct LIBARDOUR_API GainControl : public AutomationControl {
double lower_db;
double range_db;
+ private:
+ void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
};
} /* namespace */
diff --git a/libs/ardour/ardour/midi_track.h b/libs/ardour/ardour/midi_track.h
index ba418082f8..a007757679 100644
--- a/libs/ardour/ardour/midi_track.h
+++ b/libs/ardour/ardour/midi_track.h
@@ -50,8 +50,8 @@ public:
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;
@@ -94,6 +94,9 @@ public:
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);
diff --git a/libs/ardour/ardour/pan_controllable.h b/libs/ardour/ardour/pan_controllable.h
index 77acbee04f..85a4efe2fc 100644
--- a/libs/ardour/ardour/pan_controllable.h
+++ b/libs/ardour/ardour/pan_controllable.h
@@ -52,6 +52,7 @@ class LIBARDOUR_API PanControllable : public AutomationControl
private:
Pannable* owner;
+ void _set_value (double, PBD::Controllable::GroupControlDisposition group_override);
};
} // namespace
diff --git a/libs/ardour/ardour/plugin_insert.h b/libs/ardour/ardour/plugin_insert.h
index 6b434bef7f..ffa55b9eaa 100644
--- a/libs/ardour/ardour/plugin_insert.h
+++ b/libs/ardour/ardour/plugin_insert.h
@@ -103,6 +103,7 @@ class LIBARDOUR_API PluginInsert : public Processor
private:
PluginInsert* _plugin;
+ void _set_value (double val, PBD::Controllable::GroupControlDisposition group_override);
};
/** A control that manipulates a plugin property (message). */
diff --git a/libs/ardour/ardour/route.h b/libs/ardour/ardour/route.h
index e3eec71078..5351d8490a 100644
--- a/libs/ardour/ardour/route.h
+++ b/libs/ardour/ardour/route.h
@@ -128,9 +128,9 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
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 () {}
@@ -145,20 +145,20 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
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 ();
@@ -167,13 +167,13 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
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 ();
@@ -286,12 +286,12 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
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
@@ -438,6 +438,8 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
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 {
@@ -452,17 +454,20 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
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);
@@ -654,7 +659,7 @@ class LIBARDOUR_API Route : public SessionObject, public Automatable, public Rou
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;
diff --git a/libs/ardour/ardour/route_group.h b/libs/ardour/ardour/route_group.h
index 763430e1f1..fc295a658c 100644
--- a/libs/ardour/ardour/route_group.h
+++ b/libs/ardour/ardour/route_group.h
@@ -25,9 +25,9 @@
#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"
@@ -108,7 +108,7 @@ class LIBARDOUR_API RouteGroup : public SessionObject
/* 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 */
@@ -134,7 +134,7 @@ class LIBARDOUR_API RouteGroup : public SessionObject
int set_state (const XMLNode&, int version);
-private:
+ private:
boost::shared_ptr<RouteList> routes;
boost::shared_ptr<Route> subgroup_bus;
diff --git a/libs/ardour/ardour/route_group_member.h b/libs/ardour/ardour/route_group_member.h
index b0368cb240..0bf4166745 100644
--- a/libs/ardour/ardour/route_group_member.h
+++ b/libs/ardour/ardour/route_group_member.h
@@ -20,6 +20,7 @@
#ifndef __libardour_route_group_member_h__
#define __libardour_route_group_member_h__
+#include "pbd/controllable.h"
#include "pbd/signals.h"
namespace ARDOUR {
@@ -37,6 +38,8 @@ class LIBARDOUR_API RouteGroupMember
/** 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;
diff --git a/libs/ardour/ardour/route_group_specialized.h b/libs/ardour/ardour/route_group_specialized.h
index 242a16c43e..800ddc4289 100644
--- a/libs/ardour/ardour/route_group_specialized.h
+++ b/libs/ardour/ardour/route_group_specialized.h
@@ -26,13 +26,13 @@
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);
}
}
}
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h
index 43bd7483fb..e28ff8e966 100644
--- a/libs/ardour/ardour/session.h
+++ b/libs/ardour/ardour/session.h
@@ -739,16 +739,16 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
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;
@@ -1544,10 +1544,10 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
/* 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 ();
@@ -1772,8 +1772,8 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
/* 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;
@@ -1782,15 +1782,15 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop
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;
diff --git a/libs/ardour/ardour/track.h b/libs/ardour/ardour/track.h
index 5bf887f517..39f9a52ec5 100644
--- a/libs/ardour/ardour/track.h
+++ b/libs/ardour/ardour/track.h
@@ -108,9 +108,9 @@ class LIBARDOUR_API Track : public Route, public PublicDiskstream
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;
@@ -203,7 +203,8 @@ class LIBARDOUR_API Track : public Route, public PublicDiskstream
FreezeState state;
};
- struct RecEnableControl : public AutomationControl {
+ class RecEnableControl : public AutomationControl {
+ public:
RecEnableControl (boost::shared_ptr<Track> t);
void set_value (double, PBD::Controllable::GroupControlDisposition);
@@ -211,6 +212,9 @@ class LIBARDOUR_API Track : public Route, public PublicDiskstream
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;
diff --git a/libs/ardour/gain_control.cc b/libs/ardour/gain_control.cc
index 9314e1270e..867edaf5a3 100644
--- a/libs/ardour/gain_control.cc
+++ b/libs/ardour/gain_control.cc
@@ -37,17 +37,24 @@ GainControl::GainControl (Session& session, const Evoral::Parameter &param, boos
}
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 ();
}
diff --git a/libs/ardour/midi_track.cc b/libs/ardour/midi_track.cc
index 69d10c44e0..d3653dc929 100644
--- a/libs/ardour/midi_track.cc
+++ b/libs/ardour/midi_track.cc
@@ -103,23 +103,23 @@ MidiTrack::create_diskstream ()
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
@@ -725,15 +725,22 @@ MidiTrack::set_parameter_automation_state (Evoral::Parameter param, AutoState st
}
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 &parameter = _list ? _list->parameter() : Control::parameter();
const Evoral::ParameterDescriptor &desc = EventTypeMap::instance().descriptor(parameter);
@@ -790,7 +797,7 @@ MidiTrack::MidiControl::set_value_unchecked(double val)
_route->write_immediate_event(size, ev);
}
- AutomationControl::set_value(val, Controllable::NoGroup);
+ AutomationControl::set_value(val, group_override);
}
void
diff --git a/libs/ardour/pan_controllable.cc b/libs/ardour/pan_controllable.cc
index faf04cc8d7..a6a96787a2 100644
--- a/libs/ardour/pan_controllable.cc
+++ b/libs/ardour/pan_controllable.cc
@@ -35,21 +35,27 @@ PanControllable::lower () const
}
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;
}
@@ -70,7 +76,7 @@ PanControllable::set_value_unchecked (double v)
}
if (can_set) {
- AutomationControl::set_value (v, Controllable::NoGroup);
+ AutomationControl::set_value (v, group_override);
}
}
diff --git a/libs/ardour/plugin_insert.cc b/libs/ardour/plugin_insert.cc
index 02b802e955..b001895e0e 100644
--- a/libs/ardour/plugin_insert.cc
+++ b/libs/ardour/plugin_insert.cc
@@ -1349,16 +1349,22 @@ PluginInsert::PluginControl::PluginControl (PluginInsert* p,
/** @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.. */
for (Plugins::iterator i = _plugin->_plugins.begin(); i != _plugin->_plugins.end(); ++i) {
@@ -1370,7 +1376,7 @@ PluginInsert::PluginControl::set_value_unchecked (double user_val)
iasp->set_parameter (_list->parameter().id(), user_val);
}
- AutomationControl::set_value (user_val, Controllable::NoGroup);
+ AutomationControl::set_value (user_val, group_override);
}
void
diff --git a/libs/ardour/route.cc b/libs/ardour/route.cc
index c07612f125..74fe71cfff 100644
--- a/libs/ardour/route.cc
+++ b/libs/ardour/route.cc
@@ -406,7 +406,7 @@ Route::inc_gain (gain_t factor)
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()) {
@@ -459,7 +459,7 @@ Route::set_gain (gain_t val, Controllable::GroupControlDisposition group_overrid
}
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);
@@ -784,19 +784,14 @@ Route::passthru_silence (framepos_t start_frame, framepos_t end_frame, pframes_t
}
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;
}
@@ -811,7 +806,7 @@ Route::set_listen (bool yn, void* src, bool group_override)
}
_mute_master->set_soloed_by_others (false);
- listen_changed (src, group_override); /* EMIT SIGNAL */
+ listen_changed (group_override); /* EMIT SIGNAL */
}
}
}
@@ -827,11 +822,11 @@ Route::listening_via_monitor () const
}
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 ();
}
}
@@ -868,17 +863,17 @@ Route::clear_all_solo_state ()
{
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()));
@@ -890,21 +885,17 @@ Route::set_solo (bool yn, void *src, bool group_override)
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 */
}
@@ -915,7 +906,7 @@ Route::set_solo (bool yn, void *src, bool group_override)
*/
if (yn && Profile->get_trx()) {
- set_mute (false, src);
+ set_mute (false, Controllable::UseGroup);
}
}
@@ -982,7 +973,7 @@ Route::mod_solo_by_others_upstream (int32_t delta)
}
set_mute_master_solo ();
- solo_changed (false, this, false); /* EMIT SIGNAL */
+ solo_changed (false, Controllable::UseGroup); /* EMIT SIGNAL */
}
void
@@ -1004,7 +995,7 @@ Route::mod_solo_by_others_downstream (int32_t delta)
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
@@ -1015,7 +1006,7 @@ Route::set_mute_master_solo ()
}
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",
@@ -1034,19 +1025,19 @@ Route::mod_solo_isolated_by_upstream (bool yn, void* src)
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;
}
@@ -1084,13 +1075,13 @@ Route::set_solo_isolated (bool yn, void *src)
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
@@ -1106,16 +1097,16 @@ Route::set_mute_points (MuteMaster::MutePoint mp)
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;
}
@@ -1126,7 +1117,7 @@ Route::set_mute (bool yn, void *src)
*/
act_on_mute ();
/* tell everyone else */
- mute_changed (src); /* EMIT SIGNAL */
+ mute_changed (); /* EMIT SIGNAL */
_mute_control->Changed (); /* EMIT SIGNAL */
}
}
@@ -2514,11 +2505,11 @@ Route::set_state (const XMLNode& node, int version)
}
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) {
@@ -2673,7 +2664,7 @@ Route::set_state_2X (const XMLNode& node, int version)
/* XXX force reset of solo status */
- set_solo (yn, this);
+ set_solo (yn);
}
if ((prop = node.property (X_("muted"))) != 0) {
@@ -3240,7 +3231,7 @@ void
Route::set_comment (string cmt, void *src)
{
_comment = cmt;
- comment_changed (src);
+ comment_changed ();
_session.set_dirty ();
}
@@ -3414,7 +3405,7 @@ Route::input_change_handler (IOChange change, void * /*src*/)
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?
@@ -3434,7 +3425,7 @@ Route::input_change_handler (IOChange change, void * /*src*/)
}
if (idelta < 0 && does_feed && !sends_only) {
- (*i)->mod_solo_isolated_by_upstream (false, this);
+ (*i)->mod_solo_isolated_by_upstream (false);
}
}
}
@@ -3901,13 +3892,13 @@ Route::set_control (AutomationType type, double val, PBD::Controllable::GroupCon
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;
@@ -3915,7 +3906,7 @@ Route::set_control (AutomationType type, double val, PBD::Controllable::GroupCon
/* 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;
@@ -3924,7 +3915,7 @@ Route::set_control (AutomationType type, double val, PBD::Controllable::GroupCon
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);
}
@@ -3936,7 +3927,7 @@ Route::set_control (AutomationType type, double val, PBD::Controllable::GroupCon
/* 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;
@@ -3976,15 +3967,15 @@ Route::SoloControllable::SoloControllable (std::string name, boost::shared_ptr<R
}
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);
@@ -3998,12 +3989,20 @@ Route::SoloControllable::set_value_unchecked (double val)
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
{
@@ -4053,16 +4052,23 @@ Route::MuteControllable::set_superficial_value(bool muted)
}
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);
boost::shared_ptr<Route> r = _route.lock ();
@@ -4074,12 +4080,12 @@ Route::MuteControllable::set_value_unchecked (double val)
// 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);
}
}
diff --git a/libs/ardour/route_group_member.cc b/libs/ardour/route_group_member.cc
index 3caa7cd1d0..6ab2ade21e 100644
--- a/libs/ardour/route_group_member.cc
+++ b/libs/ardour/route_group_member.cc
@@ -18,6 +18,7 @@
#include "ardour/libardour_visibility.h"
#include "ardour/route_group_member.h"
+#include "ardour/route_group.h"
using namespace ARDOUR;
@@ -34,3 +35,12 @@ RouteGroupMember::set_route_group (RouteGroup *rg)
_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)())));
+}
diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc
index 8f71ef29ef..70a62e5b75 100644
--- a/libs/ardour/session.cc
+++ b/libs/ardour/session.cc
@@ -3281,10 +3281,10 @@ Session::add_routes_inner (RouteList& new_routes, bool input_auto_connect, bool
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));
@@ -3450,7 +3450,7 @@ Session::remove_routes (boost::shared_ptr<RouteList> routes_to_remove)
continue;
}
- (*iter)->set_solo (false, this);
+ (*iter)->set_solo (false, Controllable::NoGroup);
rs->remove (*iter);
@@ -3558,13 +3558,13 @@ Session::remove_route (boost::shared_ptr<Route> route)
}
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) {
@@ -3575,18 +3575,32 @@ Session::route_listen_changed (bool group_override, boost::weak_ptr<Route> wpr)
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);
}
}
@@ -3600,7 +3614,7 @@ Session::route_listen_changed (bool group_override, boost::weak_ptr<Route> wpr)
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 ();
@@ -3630,7 +3644,7 @@ Session::route_solo_isolated_changed (void* /*src*/, boost::weak_ptr<Route> wpr)
}
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));
@@ -3651,21 +3665,51 @@ Session::route_solo_changed (bool self_solo_change, bool group_override, boost:
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);
}
}
@@ -3679,8 +3723,22 @@ Session::route_solo_changed (bool self_solo_change, bool group_override, boost:
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;
}
@@ -3746,7 +3804,7 @@ Session::route_solo_changed (bool self_solo_change, bool group_override, boost:
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 */
@@ -3777,7 +3835,7 @@ Session::update_route_solo_state (boost::shared_ptr<RouteList> r)
listeners++;
something_listening = true;
} else {
- (*i)->set_listen (false, this);
+ (*i)->set_listen (false, Controllable::NoGroup);
}
}
diff --git a/libs/ardour/session_midi.cc b/libs/ardour/session_midi.cc
index c7bced8346..baff2c7bfe 100644
--- a/libs/ardour/session_midi.cc
+++ b/libs/ardour/session_midi.cc
@@ -350,7 +350,7 @@ Session::mmc_record_enable (MIDI::MachineControl &mmc, size_t trk, bool enabled)
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;
}
}
diff --git a/libs/ardour/session_rtevents.cc b/libs/ardour/session_rtevents.cc
index 2b24b59970..deb033c6fd 100644
--- a/libs/ardour/session_rtevents.cc
+++ b/libs/ardour/session_rtevents.cc
@@ -33,13 +33,15 @@ using namespace ARDOUR;
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()) {
@@ -56,11 +58,11 @@ Session::rt_set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, b
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()) {
@@ -72,17 +74,18 @@ Session::rt_clear_all_solo_state (boost::shared_ptr<RouteList> rl, bool /* yn */
}
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);
}
}
@@ -104,38 +107,38 @@ Session::set_just_one_solo (boost::shared_ptr<Route> r, bool yn, SessionEvent::R
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);
}
}
@@ -143,7 +146,7 @@ Session::rt_set_listen (boost::shared_ptr<RouteList> rl, bool yn, bool group_ove
}
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) {
@@ -155,11 +158,11 @@ Session::set_mute (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeve
}
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);
}
}
@@ -167,17 +170,17 @@ Session::rt_set_mute (boost::shared_ptr<RouteList> rl, bool yn, bool /*group_ove
}
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);
}
}
@@ -185,7 +188,7 @@ Session::rt_set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, bool /*
}
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;
@@ -206,7 +209,7 @@ Session::set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, SessionEv
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);
}
}
@@ -214,7 +217,7 @@ Session::set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, SessionEv
}
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 ()) {
@@ -224,7 +227,7 @@ Session::rt_set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, bool g
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);
}
}
@@ -233,14 +236,14 @@ Session::rt_set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, bool g
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?
@@ -250,7 +253,7 @@ Session::rt_set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, bool grou
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);
}
}
diff --git a/libs/ardour/track.cc b/libs/ardour/track.cc
index 21256b09ce..63c3477704 100644
--- a/libs/ardour/track.cc
+++ b/libs/ardour/track.cc
@@ -190,22 +190,30 @@ Track::RecEnableControl::RecEnableControl (boost::shared_ptr<Track> t)
}
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
@@ -238,7 +246,7 @@ Track::can_record()
}
void
-Track::prep_record_enabled (bool yn, void *src)
+Track::prep_record_enabled (bool yn, Controllable::GroupControlDisposition group_override)
{
if (yn && record_safe ()) {
return;
@@ -252,8 +260,8 @@ Track::prep_record_enabled (bool yn, void *src)
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;
}
@@ -282,7 +290,7 @@ Track::prep_record_enabled (bool yn, void *src)
}
void
-Track::set_record_enabled (bool yn, void *src)
+Track::set_record_enabled (bool yn, Controllable::GroupControlDisposition group_override)
{
if (_diskstream->record_safe ()) {
return;
@@ -296,8 +304,8 @@ Track::set_record_enabled (bool yn, void *src)
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;
}
@@ -313,18 +321,18 @@ Track::record_safe () const
}
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;
}
@@ -1149,4 +1157,3 @@ Track::metering_state () const
}
return rv ? MeteringInput : MeteringRoute;
}
-
diff --git a/libs/surfaces/control_protocol/control_protocol.cc b/libs/surfaces/control_protocol/control_protocol.cc
index 1ce51bcd75..6d016359bb 100644
--- a/libs/surfaces/control_protocol/control_protocol.cc
+++ b/libs/surfaces/control_protocol/control_protocol.cc
@@ -199,7 +199,7 @@ ControlProtocol::route_set_rec_enable (uint32_t table_index, bool yn)
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);
}
}
@@ -312,7 +312,7 @@ ControlProtocol::route_set_muted (uint32_t table_index, bool yn)
boost::shared_ptr<Route> r = route_table[table_index];
if (r != 0) {
- r->set_mute (yn, this);
+ r->set_mute (yn, Controllable::UseGroup);
}
}
@@ -343,7 +343,7 @@ ControlProtocol::route_set_soloed (uint32_t table_index, bool yn)
boost::shared_ptr<Route> r = route_table[table_index];
if (r != 0) {
- r->set_solo (yn, this);
+ r->set_solo (yn, Controllable::UseGroup);
}
}
diff --git a/libs/surfaces/faderport/faderport.cc b/libs/surfaces/faderport/faderport.cc
index 50250a5f13..a1ca393d73 100644
--- a/libs/surfaces/faderport/faderport.cc
+++ b/libs/surfaces/faderport/faderport.cc
@@ -1107,9 +1107,9 @@ FaderPort::set_current_route (boost::shared_ptr<Route> r)
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) {
@@ -1187,7 +1187,7 @@ FaderPort::map_cut ()
}
void
-FaderPort::map_mute (void*)
+FaderPort::map_mute ()
{
if (_current_route) {
if (_current_route->muted()) {
@@ -1204,7 +1204,7 @@ FaderPort::map_mute (void*)
}
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());
@@ -1214,7 +1214,7 @@ FaderPort::map_solo (bool, void*, bool)
}
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());
@@ -1292,8 +1292,7 @@ FaderPort::map_route_state ()
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 ();
@@ -1301,7 +1300,7 @@ FaderPort::map_route_state ()
if (_current_route == session->monitor_out()) {
map_cut ();
} else {
- map_mute (0);
+ map_mute ();
}
}
}
diff --git a/libs/surfaces/faderport/faderport.h b/libs/surfaces/faderport/faderport.h
index 025cf09e00..d0a4d915f0 100644
--- a/libs/surfaces/faderport/faderport.h
+++ b/libs/surfaces/faderport/faderport.h
@@ -302,9 +302,9 @@ class FaderPort : public ARDOUR::ControlProtocol, public AbstractUI<FaderPortReq
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 ();
diff --git a/libs/surfaces/mackie/strip.cc b/libs/surfaces/mackie/strip.cc
index af938b8990..582f7e34bf 100644
--- a/libs/surfaces/mackie/strip.cc
+++ b/libs/surfaces/mackie/strip.cc
@@ -876,15 +876,7 @@ Strip::handle_button (Button& button, ButtonState bs)
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
@@ -897,10 +889,18 @@ Strip::handle_button (Button& button, ButtonState bs)
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 {
diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc
index 7504cf0cdb..7308941ac7 100644
--- a/libs/surfaces/osc/osc.cc
+++ b/libs/surfaces/osc/osc.cc
@@ -1047,7 +1047,7 @@ OSC::route_mute (int rid, int yn)
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;
@@ -1063,7 +1063,7 @@ OSC::route_solo (int rid, int yn)
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;
@@ -1077,7 +1077,7 @@ OSC::route_recenable (int rid, int yn)
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;
@@ -1112,7 +1112,7 @@ OSC::route_set_trim_abs (int rid, float level)
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;