diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2016-01-21 11:03:14 -0500 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2016-01-22 11:58:31 -0500 |
commit | 9e5b7db89f381c70232fab35dc21fd885863f998 (patch) | |
tree | 2300e2211267c9e09f06e4948965d86b5a7bf3fa | |
parent | eee07ac351cbdc5ade3d8ceed5de2df7f19a6217 (diff) |
first compiling, mostly working version of group controls changes
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 ¶m, 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 ¶m, 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 ¶meter = _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; |