ardour
session_rtevents.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 1999-2009 Paul Davis
3 
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.
8 
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.
13 
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.
17 */
18 
19 #include <boost/bind.hpp>
20 
21 #include "pbd/error.h"
22 #include "pbd/compose.h"
23 
24 #include "ardour/session.h"
25 #include "ardour/route.h"
26 #include "ardour/track.h"
27 
28 #include "i18n.h"
29 
30 using namespace std;
31 using namespace PBD;
32 using namespace ARDOUR;
33 using namespace Glib;
34 
35 void
36 Session::set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, SessionEvent::RTeventCallback after, bool group_override)
37 {
38  queue_event (get_rt_event (rl, mc, after, group_override, &Session::rt_set_monitoring));
39 }
40 
41 void
42 Session::rt_set_monitoring (boost::shared_ptr<RouteList> rl, MonitorChoice mc, bool /* group_override */)
43 {
44  for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
45  if (!(*i)->is_auditioner()) {
47  if (t) {
48  t->set_monitoring (mc);
49  }
50  }
51  }
52 
53  set_dirty();
54 }
55 
56 void
57 Session::set_solo (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
58 {
59  queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_solo));
60 }
61 
62 void
63 Session::rt_set_solo (boost::shared_ptr<RouteList> rl, bool yn, bool /* group_override */)
64 {
65  for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
66  if (!(*i)->is_auditioner()) {
67  (*i)->set_solo (yn, this);
68  }
69  }
70 
71  set_dirty();
72 }
73 
74 void
75 Session::cancel_solo_after_disconnect (boost::shared_ptr<Route> r, bool upstream, SessionEvent::RTeventCallback after)
76 {
78  rl->push_back (r);
79 
80  queue_event (get_rt_event (rl, upstream, after, false, &Session::rt_cancel_solo_after_disconnect));
81 }
82 
83 void
84 Session::rt_cancel_solo_after_disconnect (boost::shared_ptr<RouteList> rl, bool upstream, bool /* group_override */)
85 {
86  for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
87  if (!(*i)->is_auditioner()) {
88  (*i)->cancel_solo_after_disconnect (upstream);
89  }
90  }
91  /* no need to call set-dirty - the disconnect will already have done that */
92 }
93 
94 void
95 Session::set_just_one_solo (boost::shared_ptr<Route> r, bool yn, SessionEvent::RTeventCallback after)
96 {
97  /* its a bit silly to have to do this, but it keeps the API for this public method sane (we're
98  only going to solo one route) and keeps our ability to use get_rt_event() for the internal
99  private method.
100  */
101 
103  rl->push_back (r);
104 
105  queue_event (get_rt_event (rl, yn, after, false, &Session::rt_set_just_one_solo));
106 }
107 
108 void
109 Session::rt_set_just_one_solo (boost::shared_ptr<RouteList> just_one, bool yn, bool /*ignored*/)
110 {
111  boost::shared_ptr<RouteList> rl = routes.reader ();
112  boost::shared_ptr<Route> r = just_one->front();
113 
114  for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
115  if (!(*i)->is_auditioner() && r != *i) {
116  (*i)->set_solo (!yn, (*i)->route_group());
117  }
118  }
119 
120  r->set_solo (yn, r->route_group());
121 
122  set_dirty();
123 }
124 
125 void
126 Session::set_listen (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
127 {
128  queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_listen));
129 }
130 
131 void
132 Session::rt_set_listen (boost::shared_ptr<RouteList> rl, bool yn, bool /*group_override*/ )
133 {
134  for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
135  if (!(*i)->is_auditioner()) {
136  (*i)->set_listen (yn, this);
137  }
138  }
139 
140  set_dirty();
141 }
142 
143 void
144 Session::set_mute (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
145 {
146  /* Set superficial value of mute controls for automation. */
147  for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
148  boost::shared_ptr<Route::MuteControllable> mc = (*i)->mute_control();
149  mc->set_superficial_value(yn);
150  }
151 
152  queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_mute));
153 }
154 
155 void
156 Session::rt_set_mute (boost::shared_ptr<RouteList> rl, bool yn, bool /*group_override*/)
157 {
158  for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
159  if (!(*i)->is_monitor() && !(*i)->is_auditioner()) {
160  (*i)->set_mute (yn, this);
161  }
162  }
163 
164  set_dirty();
165 }
166 
167 void
168 Session::set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
169 {
170  queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_solo_isolated));
171 }
172 
173 void
174 Session::rt_set_solo_isolated (boost::shared_ptr<RouteList> rl, bool yn, bool /*group_override*/)
175 {
176  for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
177  if (!(*i)->is_master() && !(*i)->is_monitor() && !(*i)->is_auditioner()) {
178  (*i)->set_solo_isolated (yn, this);
179  }
180  }
181 
182  set_dirty();
183 }
184 
185 void
186 Session::set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, SessionEvent::RTeventCallback after, bool group_override)
187 {
188  if (!writable()) {
189  return;
190  }
191 
192  /* do the non-RT part of rec-enabling first - the RT part will be done
193  * on the next process cycle. This does mean that theoretically we are
194  * doing things provisionally on the assumption that the rec-enable
195  * change will work, but this had better be a solid assumption for
196  * other reasons.
197  */
198 
199  for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
200  if ((*i)->is_auditioner()) {
201  continue;
202  }
203 
205 
206  if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
207  t->prep_record_enabled (yn, (group_override ? (void*) t->route_group() : (void *) this));
208  }
209  }
210 
211  queue_event (get_rt_event (rl, yn, after, group_override, &Session::rt_set_record_enabled));
212 }
213 
214 void
215 Session::rt_set_record_enabled (boost::shared_ptr<RouteList> rl, bool yn, bool group_override)
216 {
217  for (RouteList::iterator i = rl->begin(); i != rl->end(); ++i) {
218  if ((*i)->is_auditioner()) {
219  continue;
220  }
221 
223 
224  if ((t = boost::dynamic_pointer_cast<Track>(*i)) != 0) {
225  t->set_record_enabled (yn, (group_override ? (void*) t->route_group() : (void *) this));
226  }
227  }
228 
229  set_dirty ();
230 }
231 
232 void
233 Session::process_rtop (SessionEvent* ev)
234 {
235  ev->rt_slot ();
236 
237  if (ev->event_loop) {
238  ev->event_loop->call_slot (MISSING_INVALIDATOR, boost::bind (ev->rt_return, ev));
239  } else {
240  warning << string_compose ("programming error: %1", X_("Session RT event queued from thread without a UI - cleanup in RT thread!")) << endmsg;
241  ev->rt_return (ev);
242  }
243 }
void set_record_enabled(bool yn, void *src)
Definition: track.cc:273
PBD::EventLoop * event_loop
boost::function< void(SessionEvent *)> RTeventCallback
shared_ptr< T > dynamic_pointer_cast(shared_ptr< U > const &r)
Definition: shared_ptr.hpp:396
virtual void set_monitoring(MonitorChoice)
Definition: track.cc:1017
boost::function< void(void)> rt_slot
Definition: Beats.hpp:239
LIBPBD_API Transmitter warning
RTeventCallback rt_return
std::ostream & endmsg(std::ostream &ostr)
Definition: transmitter.h:71
MonitorChoice
Definition: types.h:386
#define X_(Text)
Definition: i18n.h:13
Definition: amp.h:29
void set_solo(bool yn, void *src)
Definition: route.cc:810
void prep_record_enabled(bool yn, void *src)
Definition: track.cc:233
void set_superficial_value(bool muted)
Definition: route.cc:3706
RouteGroup * route_group() const
virtual void call_slot(InvalidationRecord *, const boost::function< void()> &)=0
Definition: debug.h:30
#define MISSING_INVALIDATOR
Definition: event_loop.h:86
std::list< boost::shared_ptr< Route > > RouteList
Definition: types.h:532
std::string string_compose(const std::string &fmt, const T1 &o1)
Definition: compose.h:208