cf6a7c18005ad10ffa6ac42d51c72489f124b53d
[ardour.git] / libs / surfaces / control_protocol / control_protocol.cc
1 /*
2     Copyright (C) 2006 Paul Davis 
3
4     This program is free software; you can redistribute it
5     and/or modify it under the terms of the GNU Lesser
6     General Public License as published by the Free Software
7     Foundation; either version 2 of the License, or (at your
8     option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20
21 #include "pbd/error.h"
22
23 #include "ardour/session.h"
24 #include "ardour/route.h"
25 #include "ardour/audio_track.h"
26 #include "ardour/meter.h"
27 #include "ardour/amp.h"
28 #include "control_protocol/control_protocol.h"
29
30 using namespace ARDOUR;
31 using namespace std;
32 using namespace PBD;
33
34 Signal0<void>       ControlProtocol::ZoomToSession;
35 Signal0<void>       ControlProtocol::ZoomOut;
36 Signal0<void>       ControlProtocol::ZoomIn;
37 Signal0<void>       ControlProtocol::Enter;
38 Signal0<void>       ControlProtocol::Undo;
39 Signal0<void>       ControlProtocol::Redo;
40 Signal1<void,float> ControlProtocol::ScrollTimeline;
41 Signal1<void,uint32_t> ControlProtocol::SelectByRID;
42 Signal0<void> ControlProtocol::UnselectTrack;
43 Signal1<void,uint32_t> ControlProtocol::GotoView;
44 Signal0<void> ControlProtocol::CloseDialog;
45 PBD::Signal0<void> ControlProtocol::VerticalZoomInAll;
46 PBD::Signal0<void> ControlProtocol::VerticalZoomOutAll;
47 PBD::Signal0<void> ControlProtocol::VerticalZoomInSelected;
48 PBD::Signal0<void> ControlProtocol::VerticalZoomOutSelected;
49 PBD::Signal1<void,RouteNotificationListPtr> ControlProtocol::TrackSelectionChanged;
50
51 ControlProtocol::ControlProtocol (Session& s, string str, EventLoop* evloop)
52         : BasicUI (s),
53           _name (str)
54 {
55         if (evloop) {
56                 _own_event_loop = false;
57                 _event_loop = evloop;
58         } else {
59                 _own_event_loop = true;
60                 fatal << "programming error: cannot create control protocols without an existing event loop (yet)" << endmsg;
61                 /*NOTREACHED*/
62         }
63
64         _active = false;
65         
66         session->RouteAdded.connect (*this, MISSING_INVALIDATOR, boost::protect (boost::bind (&ControlProtocol::add_strip, this, _1)), _event_loop);
67 }
68
69 ControlProtocol::~ControlProtocol ()
70 {
71 }
72
73 void
74 ControlProtocol::add_strip (ARDOUR::RouteList&)
75 {
76         route_list_changed();
77 }
78         
79 void
80 ControlProtocol::next_track (uint32_t initial_id)
81 {
82         uint32_t limit = session->nroutes();
83         boost::shared_ptr<Route> cr = route_table[0];
84         uint32_t id;
85
86         if (cr) {
87                 id = cr->remote_control_id ();
88         } else {
89                 id = 0;
90         }
91
92         if (id == limit) {
93                 id = 0;
94         } else {
95                 id++;
96         }
97
98         while (id <= limit) {
99                 if ((cr = session->route_by_remote_id (id)) != 0) {
100                         break;
101                 }
102                 id++;
103         }
104
105         if (id >= limit) {
106                 id = 0;
107                 while (id != initial_id) {
108                         if ((cr = session->route_by_remote_id (id)) != 0) {
109                                 break;
110                         }
111                         id++;
112                 }
113         }
114
115         route_table[0] = cr;
116 }
117
118 void
119 ControlProtocol::prev_track (uint32_t initial_id)
120 {
121         uint32_t limit = session->nroutes();
122         boost::shared_ptr<Route> cr = route_table[0];
123         int32_t id;
124
125         if (cr) {
126                 id = cr->remote_control_id ();
127         } else {
128                 id = 0;
129         }
130
131         if (id == 0) {
132                 id = limit;
133         } else {
134                 id--;
135         }
136
137         while (id >= 0) {
138                 if ((cr = session->route_by_remote_id (id)) != 0) {
139                         break;
140                 }
141                 id--;
142         }
143
144         if (id < 0) {
145                 uint32_t i = limit;
146                 while (i > initial_id) {
147                         if ((cr = session->route_by_remote_id (i)) != 0) {
148                                 break;
149                         }
150                         i--;
151                 }
152         }
153
154         route_table[0] = cr;
155 }
156
157
158 void
159 ControlProtocol::set_route_table_size (uint32_t size)
160 {
161         while (route_table.size() < size) {
162                 route_table.push_back (boost::shared_ptr<Route> ((Route*) 0));
163         }
164 }
165
166 void
167 ControlProtocol::set_route_table (uint32_t table_index, boost::shared_ptr<ARDOUR::Route> r)
168 {
169         if (table_index >= route_table.size()) {
170                 return;
171         }
172         
173         route_table[table_index] = r;
174
175         // XXX SHAREDPTR need to handle r->GoingAway
176 }
177
178 bool
179 ControlProtocol::set_route_table (uint32_t table_index, uint32_t remote_control_id)
180 {
181         boost::shared_ptr<Route> r = session->route_by_remote_id (remote_control_id);
182
183         if (!r) {
184                 return false;
185         }
186
187         set_route_table (table_index, r);
188
189         return true;
190 }
191
192 void
193 ControlProtocol::route_set_rec_enable (uint32_t table_index, bool yn)
194 {
195         if (table_index > route_table.size()) {
196                 return;
197         }
198
199         boost::shared_ptr<Route> r = route_table[table_index];
200
201         boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack>(r);
202
203         if (at) {
204                 at->set_record_enabled (yn, this);
205         }
206 }
207
208 bool
209 ControlProtocol::route_get_rec_enable (uint32_t table_index)
210 {
211         if (table_index > route_table.size()) {
212                 return false;
213         }
214
215         boost::shared_ptr<Route> r = route_table[table_index];
216
217         boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack>(r);
218
219         if (at) {
220                 return at->record_enabled ();
221         }
222
223         return false;
224 }
225
226
227 float
228 ControlProtocol::route_get_gain (uint32_t table_index)
229 {
230         if (table_index > route_table.size()) {
231                 return 0.0f;
232         }
233
234         boost::shared_ptr<Route> r = route_table[table_index];
235
236         if (r == 0) {
237                 return 0.0f;
238         }
239
240         return r->amp()->gain ();
241 }
242
243 void
244 ControlProtocol::route_set_gain (uint32_t table_index, float gain)
245 {
246         if (table_index > route_table.size()) {
247                 return;
248         }
249
250         boost::shared_ptr<Route> r = route_table[table_index];
251         
252         if (r != 0) {
253                 r->set_gain (gain, this);
254         }
255 }
256
257 float
258 ControlProtocol::route_get_effective_gain (uint32_t table_index)
259 {
260         if (table_index > route_table.size()) {
261                 return 0.0f;
262         }
263
264         boost::shared_ptr<Route> r = route_table[table_index];
265
266         if (r == 0) {
267                 return 0.0f;
268         }
269
270         return r->amp()->gain_control()->get_value();
271 }
272
273
274 float
275 ControlProtocol::route_get_peak_input_power (uint32_t table_index, uint32_t which_input)
276 {
277         if (table_index > route_table.size()) {
278                 return 0.0f;
279         }
280
281         boost::shared_ptr<Route> r = route_table[table_index];
282
283         if (r == 0) {
284                 return 0.0f;
285         }
286
287         return r->peak_meter().peak_power (which_input);
288 }
289
290
291 bool
292 ControlProtocol::route_get_muted (uint32_t table_index)
293 {
294         if (table_index > route_table.size()) {
295                 return false;
296         }
297
298         boost::shared_ptr<Route> r = route_table[table_index];
299
300         if (r == 0) {
301                 return false;
302         }
303
304         return r->muted ();
305 }
306
307 void
308 ControlProtocol::route_set_muted (uint32_t table_index, bool yn)
309 {
310         if (table_index > route_table.size()) {
311                 return;
312         }
313
314         boost::shared_ptr<Route> r = route_table[table_index];
315
316         if (r != 0) {
317                 r->set_mute (yn, this);
318         }
319 }
320
321
322 bool
323 ControlProtocol::route_get_soloed (uint32_t table_index)
324 {
325         if (table_index > route_table.size()) {
326                 return false;
327         }
328
329         boost::shared_ptr<Route> r = route_table[table_index];
330
331         if (r == 0) {
332                 return false;
333         }
334
335         return r->soloed ();
336 }
337
338 void
339 ControlProtocol::route_set_soloed (uint32_t table_index, bool yn)
340 {
341         if (table_index > route_table.size()) {
342                 return;
343         }
344
345         boost::shared_ptr<Route> r = route_table[table_index];
346
347         if (r != 0) {
348                 r->set_solo (yn, this);
349         }
350 }
351
352 string
353 ControlProtocol:: route_get_name (uint32_t table_index)
354 {
355         if (table_index > route_table.size()) {
356                 return "";
357         }
358
359         boost::shared_ptr<Route> r = route_table[table_index];
360
361         if (r == 0) {
362                 return "";
363         }
364
365         return r->name();
366 }
367
368 list<boost::shared_ptr<Bundle> >
369 ControlProtocol::bundles ()
370 {
371        return list<boost::shared_ptr<Bundle> > ();
372 }