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, SessionEvent::RTeventCallback after, bool group_override)
38 queue_event (get_rt_event (rl, mc, after, group_override, &Session::rt_set_monitoring));
42 Session::rt_set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, bool /* group_override */)
44 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
45 if (!(*i)->is_auditioner()) {
46 boost::shared_ptr<Track> t = boost::dynamic_pointer_cast<Track> (*i);
48 t->set_monitoring (mc);
57 Session::clear_all_solo_state (boost::shared_ptr<RouteList> rl)
59 queue_event (get_rt_event (rl, false, rt_cleanup, false, &Session::rt_clear_all_solo_state));
63 Session::rt_clear_all_solo_state (boost::shared_ptr<RouteList> rl, bool /* yn */, bool /* group_override */)
65 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
66 if ((*i)->is_auditioner()) {
69 (*i)->clear_all_solo_state();
75 Session::set_solo (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
77 queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_solo));
82 Session::rt_set_solo (boost::shared_ptr<RouteList> rl, bool yn, bool /* group_override */)
84 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
85 if (!(*i)->is_auditioner()) {
86 (*i)->set_solo (yn, this);
91 /* XXX boost::shared_ptr<RouteList> goes out of scope here and is likley free()ed in RT context
92 * because boost's shared_ptr does reference counting and free/delete in the dtor.
93 * (this also applies to other rt_ methods here)
98 Session::set_just_one_solo (boost::shared_ptr<Route> r, bool yn, SessionEvent::RTeventCallback after)
100 /* its a bit silly to have to do this, but it keeps the API for this public method sane (we're
101 only going to solo one route) and keeps our ability to use get_rt_event() for the internal
105 boost::shared_ptr<RouteList> rl (new RouteList);
108 queue_event (get_rt_event (rl, yn, after, false, &Session::rt_set_just_one_solo));
112 Session::rt_set_just_one_solo (boost::shared_ptr<RouteList> just_one, bool yn, bool /*ignored*/)
114 boost::shared_ptr<RouteList> rl = routes.reader ();
115 boost::shared_ptr<Route> r = just_one->front();
117 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
118 if (!(*i)->is_auditioner() && r != *i) {
119 (*i)->set_solo (!yn, (*i)->route_group());
123 r->set_solo (yn, r->route_group());
129 Session::set_listen (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
131 queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_listen));
135 Session::rt_set_listen (boost::shared_ptr<RouteList> rl, bool yn, bool /*group_override*/ )
137 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
138 if (!(*i)->is_auditioner()) {
139 (*i)->set_listen (yn, this);
147 Session::set_mute (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
149 /* Set superficial value of mute controls for automation. */
150 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
151 boost::shared_ptr<Route::MuteControllable> mc = (*i)->mute_control();
152 mc->set_superficial_value(yn);
155 queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_mute));
159 Session::rt_set_mute (boost::shared_ptr<RouteList> rl, bool yn, bool /*group_override*/)
161 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
162 if (!(*i)->is_monitor() && !(*i)->is_auditioner()) {
163 (*i)->set_mute (yn, this);
171 Session::set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
173 queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_solo_isolated));
177 Session::rt_set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, bool /*group_override*/)
179 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
180 if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner()) {
181 (*i)->set_solo_isolated (yn, this);
189 Session::set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
195 /* do the non-RT part of rec-enabling first - the RT part will be done
196 * on the next process cycle. This does mean that theoretically we are
197 * doing things provisionally on the assumption that the rec-enable
198 * change will work, but this had better be a solid assumption for
202 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
203 if ((*i)->is_auditioner() || (*i)->record_safe ()) {
207 boost::shared_ptr<Track> t;
209 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
210 t->prep_record_enabled (yn, (group_override ? (void*) t->route_group() : (void *) this));
214 queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_record_enabled));
218 Session::rt_set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, bool group_override)
220 for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
221 if ((*i)->is_auditioner() || (*i)->record_safe ()) {
225 boost::shared_ptr<Track> t;
227 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
228 t->set_record_enabled (yn, (group_override ? (void*) t->route_group() : (void *) this));
237 Session::set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
239 set_record_enabled (rl, false, after, group_override);
240 queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_record_safe));
244 Session::rt_set_record_safe (boost::shared_ptr<RouteList> rl, bool yn, bool group_override)
246 for (RouteList::iterator i = rl->begin (); i != rl->end (); ++i) {
247 if ((*i)->is_auditioner ()) { // REQUIRES REVIEW Can audiotioner be in Record Safe mode?
251 boost::shared_ptr<Track> t;
253 if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
254 t->set_record_safe (yn, (group_override ? (void*) t->route_group () : (void *) this));
262 Session::process_rtop (SessionEvent* ev)
266 if (ev->event_loop) {
267 ev->event_loop->call_slot (MISSING_INVALIDATOR, boost::bind (ev->rt_return, ev));
269 warning << string_compose ("programming error: %1", X_("Session RT event queued from thread without a UI - cleanup in RT thread!")) << endmsg;