2 Copyright (C) 1999-2009 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #include <boost/bind.hpp>
21 #include "pbd/error.h"
22 #include "pbd/compose.h"
24 #include "ardour/session.h"
25 #include "ardour/route.h"
26 #include "ardour/track.h"
32 using namespace ARDOUR;
36 Session::set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc,
37 SessionEvent::RTeventCallback after,
38 Controllable::GroupControlDisposition group_override)
40 queue_event (get_rt_event (rl, mc, after, group_override, &Session::rt_set_monitoring));
44 Session::rt_set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, Controllable::GroupControlDisposition group_override)
46 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
47 if (!(*i)->is_auditioner()) {
48 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
50 t->set_monitoring (mc, group_override);
59 Session::clear_all_solo_state (boost::shared_ptr<RouteList> rl)
61 queue_event (get_rt_event (rl, false, rt_cleanup, Controllable::NoGroup, &Session::rt_clear_all_solo_state));
65 Session::rt_clear_all_solo_state (boost::shared_ptr<RouteList> rl, bool /* yn */, Controllable::GroupControlDisposition /* group_override */)
67 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
68 if ((*i)->is_auditioner()) {
71 (*i)->clear_all_solo_state();
77 Session::set_solo (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after,
78 Controllable::GroupControlDisposition group_override)
80 queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_solo));
84 Session::rt_set_solo (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
86 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
87 if (!(*i)->is_auditioner()) {
88 (*i)->set_solo (yn, group_override);
93 /* XXX boost::shared_ptr<RouteList> goes out of scope here and is likley free()ed in RT context
94 * because boost's shared_ptr does reference counting and free/delete in the dtor.
95 * (this also applies to other rt_ methods here)
100 Session::set_just_one_solo (boost::shared_ptr<Route> r, bool yn, SessionEvent::RTeventCallback after)
102 /* its a bit silly to have to do this, but it keeps the API for this public method sane (we're
103 only going to solo one route) and keeps our ability to use get_rt_event() for the internal
107 boost::shared_ptr<RouteList> rl (new RouteList);
110 queue_event (get_rt_event (rl, yn, after, Controllable::NoGroup, &Session::rt_set_just_one_solo));
114 Session::rt_set_just_one_solo (boost::shared_ptr<RouteList> just_one, bool yn, Controllable::GroupControlDisposition /*ignored*/)
116 boost::shared_ptr<RouteList> rl = routes.reader ();
117 boost::shared_ptr<Route> r = just_one->front();
119 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
120 if (!(*i)->is_auditioner() && r != *i) {
121 (*i)->set_solo (!yn, Controllable::NoGroup);
125 r->set_solo (yn, Controllable::NoGroup);
131 Session::set_listen (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
133 queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_listen));
137 Session::rt_set_listen (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
139 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
140 if (!(*i)->is_auditioner()) {
141 (*i)->set_listen (yn, group_override);
149 Session::set_mute (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
151 /* Set superficial value of mute controls for automation. */
152 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
153 boost::shared_ptr<Route::MuteControllable> mc = (*i)->mute_control();
154 mc->set_superficial_value(yn);
157 queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_mute));
161 Session::rt_set_mute (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
163 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
164 if (!(*i)->is_monitor() && !(*i)->is_auditioner()) {
165 (*i)->set_mute (yn, group_override);
173 Session::set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
175 queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_solo_isolated));
179 Session::rt_set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
181 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
182 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner()) {
183 (*i)->set_solo_isolated (yn, group_override);
191 Session::set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
197 /* do the non-RT part of rec-enabling first - the RT part will be done
198 * on the next process cycle. This does mean that theoretically we are
199 * doing things provisionally on the assumption that the rec-enable
200 * change will work, but this had better be a solid assumption for
204 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
205 if ((*i)->is_auditioner() || (*i)->record_safe ()) {
209 boost::shared_ptr<Track> t;
211 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
212 t->prep_record_enabled (yn, group_override);
216 queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_record_enabled));
220 Session::rt_set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
222 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
223 if ((*i)->is_auditioner() || (*i)->record_safe ()) {
227 boost::shared_ptr<Track> t;
229 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
230 t->set_record_enabled (yn, group_override);
239 Session::set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, Controllable::GroupControlDisposition group_override)
241 set_record_enabled (rl, false, after, group_override);
242 queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_record_safe));
246 Session::rt_set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, Controllable::GroupControlDisposition group_override)
248 for (RouteList::iterator i = rl->begin (); i != rl->end (); ++i) {
249 if ((*i)->is_auditioner ()) { // REQUIRES REVIEW Can audiotioner be in Record Safe mode?
253 boost::shared_ptr<Track> t;
255 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
256 t->set_record_safe (yn, group_override);
264 Session::process_rtop (SessionEvent* ev)
268 if (ev->event_loop) {
269 ev->event_loop->call_slot (MISSING_INVALIDATOR, boost::bind (ev->rt_return, ev));
271 warning << string_compose ("programming error: %1", X_("Session RT event queued from thread without a UI - cleanup in RT thread!")) << endmsg;