diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/ardour/ardour/session.h | 14 | ||||
-rw-r--r-- | libs/ardour/session_rtevents.cc | 29 | ||||
-rw-r--r-- | libs/ardour/vca.cc | 2 |
3 files changed, 44 insertions, 1 deletions
diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 47329f7395..2976fec8f3 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -792,6 +792,7 @@ 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, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup); + void set_implicit_solo (boost::shared_ptr<RouteList>, int delta, bool up_or_downstream, 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, PBD::Controllable::GroupControlDisposition group_override = PBD::Controllable::UseGroup); @@ -1922,7 +1923,20 @@ class LIBARDOUR_API Session : public PBD::StatefulDestructible, public PBD::Scop return ev; } + /* specialized version realtime "apply to set of routes" operations */ + template<typename T1, typename T2> SessionEvent* + get_rt_event (boost::shared_ptr<RouteList> rl, T1 t1arg, T2 t2arg, SessionEvent::RTeventCallback after, PBD::Controllable::GroupControlDisposition group_override, + void (Session::*method) (boost::shared_ptr<RouteList>, T1, T2, PBD::Controllable::GroupControlDisposition)) { + SessionEvent* ev = new SessionEvent (SessionEvent::RealTimeOperation, SessionEvent::Add, SessionEvent::Immediate, 0, 0.0); + ev->rt_slot = boost::bind (method, this, rl, t1arg, t2arg, group_override); + ev->rt_return = after; + ev->event_loop = PBD::EventLoop::get_event_loop_for_thread (); + + return ev; + } + void rt_set_solo (boost::shared_ptr<RouteList>, bool yn, PBD::Controllable::GroupControlDisposition group_override); + void rt_set_implicit_solo (boost::shared_ptr<RouteList>, int delta, bool up_or_downstream, PBD::Controllable::GroupControlDisposition); 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); diff --git a/libs/ardour/session_rtevents.cc b/libs/ardour/session_rtevents.cc index 5850643739..68ba15550e 100644 --- a/libs/ardour/session_rtevents.cc +++ b/libs/ardour/session_rtevents.cc @@ -90,6 +90,35 @@ Session::rt_set_solo (boost::shared_ptr<RouteList> rl, bool yn, Controllable::Gr } set_dirty(); + + /* XXX boost::shared_ptr<RouteList> goes out of scope here and is likley free()ed in RT context + * because boost's shared_ptr does reference counting and free/delete in the dtor. + * (this also applies to other rt_ methods here) + */ +} + +void +Session::set_implicit_solo (boost::shared_ptr<RouteList> rl, int delta, bool upstream, SessionEvent::RTeventCallback after, + Controllable::GroupControlDisposition group_override) +{ + queue_event (get_rt_event (rl, delta, upstream, after, group_override, &Session::rt_set_implicit_solo)); +} + +void +Session::rt_set_implicit_solo (boost::shared_ptr<RouteList> rl, int delta, bool upstream, PBD::Controllable::GroupControlDisposition) +{ + for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) { + if (!(*i)->is_auditioner()) { + if (upstream) { + (*i)->mod_solo_by_others_upstream (delta); + } else { + (*i)->mod_solo_by_others_downstream (delta); + } + } + } + + set_dirty(); + /* XXX boost::shared_ptr<RouteList> goes out of scope here and is likley free()ed in RT context * because boost's shared_ptr does reference counting and free/delete in the dtor. * (this also applies to other rt_ methods here) diff --git a/libs/ardour/vca.cc b/libs/ardour/vca.cc index 8c4fe260ec..3fec2d9305 100644 --- a/libs/ardour/vca.cc +++ b/libs/ardour/vca.cc @@ -180,7 +180,7 @@ VCA::set_solo (bool yn) if (Config->get_solo_control_is_listen_control()) { _session.set_listen (rl, yn, Session::rt_cleanup, Controllable::NoGroup); } else { - _session.set_solo (rl, yn, Session::rt_cleanup, Controllable::NoGroup); + _session.set_implicit_solo (rl, (yn ? 1 : -1), true, Session::rt_cleanup, Controllable::NoGroup); } } |