OSC: Add master_send_enable for MB
[ardour.git] / libs / surfaces / osc / osc.cc
1 /*
2  * Copyright (C) 2006 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17  *
18  */
19
20 #include <cstdio>
21 #include <cstdlib>
22 #include <cerrno>
23 #include <algorithm>
24
25 #include <unistd.h>
26 #include <fcntl.h>
27
28 #include "pbd/gstdio_compat.h"
29 #include <glibmm.h>
30
31 #include "pbd/control_math.h"
32 #include <pbd/convert.h>
33 #include <pbd/pthread_utils.h>
34 #include <pbd/file_utils.h>
35 #include <pbd/failed_constructor.h>
36
37 #include "ardour/amp.h"
38 #include "ardour/session.h"
39 #include "ardour/route.h"
40 #include "ardour/audio_track.h"
41 #include "ardour/midi_track.h"
42 #include "ardour/monitor_control.h"
43 #include "ardour/dB.h"
44 #include "ardour/filesystem_paths.h"
45 #include "ardour/panner.h"
46 #include "ardour/plugin.h"
47 #include "ardour/plugin_insert.h"
48 #include "ardour/presentation_info.h"
49 #include "ardour/profile.h"
50 #include "ardour/send.h"
51 #include "ardour/internal_send.h"
52 #include "ardour/phase_control.h"
53 #include "ardour/solo_isolate_control.h"
54 #include "ardour/solo_safe_control.h"
55 #include "ardour/vca_manager.h"
56
57 #include "osc_select_observer.h"
58 #include "osc.h"
59 #include "osc_controllable.h"
60 #include "osc_route_observer.h"
61 #include "osc_global_observer.h"
62 #include "osc_cue_observer.h"
63 #include "pbd/i18n.h"
64
65 using namespace ARDOUR;
66 using namespace std;
67 using namespace Glib;
68 using namespace ArdourSurface;
69
70 #include "pbd/abstract_ui.cc" // instantiate template
71
72 OSC* OSC::_instance = 0;
73
74 #ifdef DEBUG
75 static void error_callback(int num, const char *m, const char *path)
76 {
77         fprintf(stderr, "liblo server error %d in path %s: %s\n", num, path, m);
78 }
79 #else
80 static void error_callback(int, const char *, const char *)
81 {
82
83 }
84 #endif
85
86 OSC::OSC (Session& s, uint32_t port)
87         : ControlProtocol (s, X_("Open Sound Control (OSC)"))
88         , AbstractUI<OSCUIRequest> (name())
89         , local_server (0)
90         , remote_server (0)
91         , _port(port)
92         , _ok (true)
93         , _shutdown (false)
94         , _osc_server (0)
95         , _osc_unix_server (0)
96         , _debugmode (Off)
97         , address_only (false)
98         , remote_port ("8000")
99         , default_banksize (0)
100         , default_strip (159)
101         , default_feedback (0)
102         , default_gainmode (0)
103         , default_send_size (0)
104         , default_plugin_size (0)
105         , tick (true)
106         , bank_dirty (false)
107         , scrub_speed (0)
108         , gui (0)
109 {
110         _instance = this;
111
112         session->Exported.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::session_exported, this, _1, _2), this);
113 }
114
115 OSC::~OSC()
116 {
117         stop ();
118         tear_down_gui ();
119         _instance = 0;
120 }
121
122 void*
123 OSC::request_factory (uint32_t num_requests)
124 {
125         /* AbstractUI<T>::request_buffer_factory() is a template method only
126            instantiated in this source module. To provide something visible for
127            use in the interface/descriptor, we have this static method that is
128            template-free.
129         */
130         return request_buffer_factory (num_requests);
131 }
132
133 void
134 OSC::do_request (OSCUIRequest* req)
135 {
136         if (req->type == CallSlot) {
137
138                 call_slot (MISSING_INVALIDATOR, req->the_slot);
139
140         } else if (req->type == Quit) {
141
142                 stop ();
143         }
144 }
145
146 int
147 OSC::set_active (bool yn)
148 {
149         if (yn != active()) {
150
151                 if (yn) {
152                         if (start ()) {
153                                 return -1;
154                         }
155                 } else {
156                         if (stop ()) {
157                                 return -1;
158                         }
159                 }
160
161         }
162
163         return ControlProtocol::set_active (yn);
164 }
165
166 bool
167 OSC::get_active () const
168 {
169         return _osc_server != 0;
170 }
171
172 int
173 OSC::start ()
174 {
175         char tmpstr[255];
176
177         if (_osc_server) {
178                 /* already started */
179                 return 0;
180         }
181
182         for (int j=0; j < 20; ++j) {
183                 snprintf(tmpstr, sizeof(tmpstr), "%d", _port);
184
185                 //if ((_osc_server = lo_server_new_with_proto (tmpstr, LO_TCP, error_callback))) {
186                 //      break;
187                 //}
188
189                 if ((_osc_server = lo_server_new (tmpstr, error_callback))) {
190                         break;
191                 }
192
193 #ifdef DEBUG
194                 cerr << "can't get osc at port: " << _port << endl;
195 #endif
196                 _port++;
197                 continue;
198         }
199
200         if (!_osc_server) {
201                 return 1;
202         }
203
204 #ifdef ARDOUR_OSC_UNIX_SERVER
205
206         // APPEARS sluggish for now
207
208         // attempt to create unix socket server too
209
210         snprintf(tmpstr, sizeof(tmpstr), "/tmp/sooperlooper_XXXXXX");
211         int fd = mkstemp(tmpstr);
212
213         if (fd >= 0 ) {
214                 ::g_unlink (tmpstr);
215                 close (fd);
216
217                 _osc_unix_server = lo_server_new (tmpstr, error_callback);
218
219                 if (_osc_unix_server) {
220                         _osc_unix_socket_path = tmpstr;
221                 }
222         }
223 #endif
224
225         PBD::info << "OSC @ " << get_server_url () << endmsg;
226
227         std::string url_file;
228
229         if (find_file (ardour_config_search_path(), "osc_url", url_file)) {
230                 _osc_url_file = url_file;
231                 if (g_file_set_contents (_osc_url_file.c_str(), get_server_url().c_str(), -1, NULL)) {
232                         cerr << "Couldn't write '" <<  _osc_url_file << "'" <<endl;
233                 }
234         }
235
236         register_callbacks();
237
238         session_loaded (*session);
239
240         // lo_server_thread_add_method(_sthread, NULL, NULL, OSC::_dummy_handler, this);
241
242         /* startup the event loop thread */
243
244         BaseUI::run ();
245
246         // start timers for metering, timecode and heartbeat.
247         // timecode and metering run at 100
248         Glib::RefPtr<Glib::TimeoutSource> periodic_timeout = Glib::TimeoutSource::create (100); // milliseconds
249         periodic_connection = periodic_timeout->connect (sigc::mem_fun (*this, &OSC::periodic));
250         periodic_timeout->attach (main_loop()->get_context());
251
252         // catch track reordering
253         // receive routes added
254         session->RouteAdded.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSC::notify_routes_added, this, _1), this);
255         // receive VCAs added
256         session->vca_manager().VCAAdded.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSC::notify_vca_added, this, _1), this);
257         // order changed
258         PresentationInfo::Change.connect (session_connections, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this);
259
260         _select = boost::shared_ptr<Stripable>();
261
262         return 0;
263 }
264
265 void
266 OSC::thread_init ()
267 {
268         pthread_set_name (event_loop_name().c_str());
269
270         if (_osc_unix_server) {
271                 Glib::RefPtr<IOSource> src = IOSource::create (lo_server_get_socket_fd (_osc_unix_server), IO_IN|IO_HUP|IO_ERR);
272                 src->connect (sigc::bind (sigc::mem_fun (*this, &OSC::osc_input_handler), _osc_unix_server));
273                 src->attach (_main_loop->get_context());
274                 local_server = src->gobj();
275                 g_source_ref (local_server);
276         }
277
278         if (_osc_server) {
279 #ifdef PLATFORM_WINDOWS
280                 Glib::RefPtr<IOChannel> chan = Glib::IOChannel::create_from_win32_socket (lo_server_get_socket_fd (_osc_server));
281                 Glib::RefPtr<IOSource> src  = IOSource::create (chan, IO_IN|IO_HUP|IO_ERR);
282 #else
283                 Glib::RefPtr<IOSource> src  = IOSource::create (lo_server_get_socket_fd (_osc_server), IO_IN|IO_HUP|IO_ERR);
284 #endif
285                 src->connect (sigc::bind (sigc::mem_fun (*this, &OSC::osc_input_handler), _osc_server));
286                 src->attach (_main_loop->get_context());
287                 remote_server = src->gobj();
288                 g_source_ref (remote_server);
289         }
290
291         PBD::notify_event_loops_about_thread_creation (pthread_self(), event_loop_name(), 2048);
292         SessionEvent::create_per_thread_pool (event_loop_name(), 128);
293 }
294
295 int
296 OSC::stop ()
297 {
298         /* stop main loop */
299
300         if (local_server) {
301                 g_source_destroy (local_server);
302                 g_source_unref (local_server);
303                 local_server = 0;
304         }
305
306         if (remote_server) {
307                 g_source_destroy (remote_server);
308                 g_source_unref (remote_server);
309                 remote_server = 0;
310         }
311
312         BaseUI::quit ();
313
314         if (_osc_server) {
315                 lo_server_free (_osc_server);
316                 _osc_server = 0;
317         }
318
319         if (_osc_unix_server) {
320                 lo_server_free (_osc_unix_server);
321                 _osc_unix_server = 0;
322         }
323
324         if (!_osc_unix_socket_path.empty()) {
325                 ::g_unlink (_osc_unix_socket_path.c_str());
326         }
327
328         if (!_osc_url_file.empty() ) {
329                 ::g_unlink (_osc_url_file.c_str() );
330         }
331
332         periodic_connection.disconnect ();
333         session_connections.drop_connections ();
334         cueobserver_connections.drop_connections ();
335         // Delete any active route observers
336         for (RouteObservers::iterator x = route_observers.begin(); x != route_observers.end();) {
337
338                 OSCRouteObserver* rc;
339
340                 if ((rc = dynamic_cast<OSCRouteObserver*>(*x)) != 0) {
341                         delete *x;
342                         x = route_observers.erase (x);
343                 } else {
344                         ++x;
345                 }
346         }
347 // Should maybe do global_observers too
348         for (GlobalObservers::iterator x = global_observers.begin(); x != global_observers.end();) {
349
350                 OSCGlobalObserver* gc;
351
352                 if ((gc = dynamic_cast<OSCGlobalObserver*>(*x)) != 0) {
353                         delete *x;
354                         x = global_observers.erase (x);
355                 } else {
356                         ++x;
357                 }
358         }
359
360 // delete select observers
361         for (uint32_t it = 0; it < _surface.size(); ++it) {
362                 OSCSurface* sur = &_surface[it];
363                 OSCSelectObserver* so;
364                 if ((so = dynamic_cast<OSCSelectObserver*>(sur->sel_obs)) != 0) {
365                         delete so;
366                 }
367         }
368
369 // delete cue observers
370         for (CueObservers::iterator x = cue_observers.begin(); x != cue_observers.end();) {
371
372                 OSCCueObserver* co;
373
374                 if ((co = dynamic_cast<OSCCueObserver*>(*x)) != 0) {
375                         delete *x;
376                         x = cue_observers.erase (x);
377                 } else {
378                         ++x;
379                 }
380         }
381
382         return 0;
383 }
384
385 void
386 OSC::register_callbacks()
387 {
388         lo_server srvs[2];
389         lo_server serv;
390
391         srvs[0] = _osc_server;
392         srvs[1] = _osc_unix_server;
393
394         for (size_t i = 0; i < 2; ++i) {
395
396                 if (!srvs[i]) {
397                         continue;
398                 }
399
400                 serv = srvs[i];
401
402
403 #define REGISTER_CALLBACK(serv,path,types, function) lo_server_add_method (serv, path, types, OSC::_ ## function, this)
404
405                 // Some controls have optional "f" for feedback or touchosc
406                 // http://hexler.net/docs/touchosc-controls-reference
407
408                 REGISTER_CALLBACK (serv, "/refresh", "", refresh_surface);
409                 REGISTER_CALLBACK (serv, "/refresh", "f", refresh_surface);
410                 REGISTER_CALLBACK (serv, "/strip/list", "", routes_list);
411                 REGISTER_CALLBACK (serv, "/strip/list", "f", routes_list);
412                 REGISTER_CALLBACK (serv, "/add_marker", "", add_marker);
413                 REGISTER_CALLBACK (serv, "/add_marker", "f", add_marker);
414                 REGISTER_CALLBACK (serv, "/access_action", "s", access_action);
415                 REGISTER_CALLBACK (serv, "/loop_toggle", "", loop_toggle);
416                 REGISTER_CALLBACK (serv, "/loop_toggle", "f", loop_toggle);
417                 REGISTER_CALLBACK (serv, "/loop_location", "ii", loop_location);
418                 REGISTER_CALLBACK (serv, "/goto_start", "", goto_start);
419                 REGISTER_CALLBACK (serv, "/goto_start", "f", goto_start);
420                 REGISTER_CALLBACK (serv, "/goto_end", "", goto_end);
421                 REGISTER_CALLBACK (serv, "/goto_end", "f", goto_end);
422                 REGISTER_CALLBACK (serv, "/scrub", "f", scrub);
423                 REGISTER_CALLBACK (serv, "/jog", "f", jog);
424                 REGISTER_CALLBACK (serv, "/jog/mode", "f", jog_mode);
425                 REGISTER_CALLBACK (serv, "/rewind", "", rewind);
426                 REGISTER_CALLBACK (serv, "/rewind", "f", rewind);
427                 REGISTER_CALLBACK (serv, "/ffwd", "", ffwd);
428                 REGISTER_CALLBACK (serv, "/ffwd", "f", ffwd);
429                 REGISTER_CALLBACK (serv, "/transport_stop", "", transport_stop);
430                 REGISTER_CALLBACK (serv, "/transport_stop", "f", transport_stop);
431                 REGISTER_CALLBACK (serv, "/transport_play", "", transport_play);
432                 REGISTER_CALLBACK (serv, "/transport_play", "f", transport_play);
433                 REGISTER_CALLBACK (serv, "/transport_frame", "", transport_frame);
434                 REGISTER_CALLBACK (serv, "/transport_speed", "", transport_speed);
435                 REGISTER_CALLBACK (serv, "/record_enabled", "", record_enabled);
436                 REGISTER_CALLBACK (serv, "/set_transport_speed", "f", set_transport_speed);
437                 // locate ii is position and bool roll
438                 REGISTER_CALLBACK (serv, "/locate", "ii", locate);
439                 REGISTER_CALLBACK (serv, "/save_state", "", save_state);
440                 REGISTER_CALLBACK (serv, "/save_state", "f", save_state);
441                 REGISTER_CALLBACK (serv, "/prev_marker", "", prev_marker);
442                 REGISTER_CALLBACK (serv, "/prev_marker", "f", prev_marker);
443                 REGISTER_CALLBACK (serv, "/next_marker", "", next_marker);
444                 REGISTER_CALLBACK (serv, "/next_marker", "f", next_marker);
445                 REGISTER_CALLBACK (serv, "/undo", "", undo);
446                 REGISTER_CALLBACK (serv, "/undo", "f", undo);
447                 REGISTER_CALLBACK (serv, "/redo", "", redo);
448                 REGISTER_CALLBACK (serv, "/redo", "f", redo);
449                 REGISTER_CALLBACK (serv, "/toggle_punch_in", "", toggle_punch_in);
450                 REGISTER_CALLBACK (serv, "/toggle_punch_in", "f", toggle_punch_in);
451                 REGISTER_CALLBACK (serv, "/toggle_punch_out", "", toggle_punch_out);
452                 REGISTER_CALLBACK (serv, "/toggle_punch_out", "f", toggle_punch_out);
453                 REGISTER_CALLBACK (serv, "/rec_enable_toggle", "", rec_enable_toggle);
454                 REGISTER_CALLBACK (serv, "/rec_enable_toggle", "f", rec_enable_toggle);
455                 REGISTER_CALLBACK (serv, "/toggle_all_rec_enables", "", toggle_all_rec_enables);
456                 REGISTER_CALLBACK (serv, "/toggle_all_rec_enables", "f", toggle_all_rec_enables);
457                 REGISTER_CALLBACK (serv, "/all_tracks_rec_in", "f", all_tracks_rec_in);
458                 REGISTER_CALLBACK (serv, "/all_tracks_rec_out", "f", all_tracks_rec_out);
459                 REGISTER_CALLBACK (serv, "/cancel_all_solos", "f", cancel_all_solos);
460                 REGISTER_CALLBACK (serv, "/remove_marker", "", remove_marker_at_playhead);
461                 REGISTER_CALLBACK (serv, "/remove_marker", "f", remove_marker_at_playhead);
462                 REGISTER_CALLBACK (serv, "/jump_bars", "f", jump_by_bars);
463                 REGISTER_CALLBACK (serv, "/jump_seconds", "f", jump_by_seconds);
464                 REGISTER_CALLBACK (serv, "/mark_in", "", mark_in);
465                 REGISTER_CALLBACK (serv, "/mark_in", "f", mark_in);
466                 REGISTER_CALLBACK (serv, "/mark_out", "", mark_out);
467                 REGISTER_CALLBACK (serv, "/mark_out", "f", mark_out);
468                 REGISTER_CALLBACK (serv, "/toggle_click", "", toggle_click);
469                 REGISTER_CALLBACK (serv, "/toggle_click", "f", toggle_click);
470                 REGISTER_CALLBACK (serv, "/midi_panic", "", midi_panic);
471                 REGISTER_CALLBACK (serv, "/midi_panic", "f", midi_panic);
472                 REGISTER_CALLBACK (serv, "/toggle_roll", "", toggle_roll);
473                 REGISTER_CALLBACK (serv, "/toggle_roll", "f", toggle_roll);
474                 REGISTER_CALLBACK (serv, "/stop_forget", "", stop_forget);
475                 REGISTER_CALLBACK (serv, "/stop_forget", "f", stop_forget);
476                 REGISTER_CALLBACK (serv, "/set_punch_range", "", set_punch_range);
477                 REGISTER_CALLBACK (serv, "/set_punch_range", "f", set_punch_range);
478                 REGISTER_CALLBACK (serv, "/set_loop_range", "", set_loop_range);
479                 REGISTER_CALLBACK (serv, "/set_loop_range", "f", set_loop_range);
480                 REGISTER_CALLBACK (serv, "/set_session_range", "", set_session_range);
481                 REGISTER_CALLBACK (serv, "/set_session_range", "f", set_session_range);
482                 REGISTER_CALLBACK (serv, "/toggle_monitor_mute", "", toggle_monitor_mute);
483                 REGISTER_CALLBACK (serv, "/toggle_monitor_mute", "f", toggle_monitor_mute);
484                 REGISTER_CALLBACK (serv, "/toggle_monitor_dim", "", toggle_monitor_dim);
485                 REGISTER_CALLBACK (serv, "/toggle_monitor_dim", "f", toggle_monitor_dim);
486                 REGISTER_CALLBACK (serv, "/toggle_monitor_mono", "", toggle_monitor_mono);
487                 REGISTER_CALLBACK (serv, "/toggle_monitor_mono", "f", toggle_monitor_mono);
488                 REGISTER_CALLBACK (serv, "/quick_snapshot_switch", "", quick_snapshot_switch);
489                 REGISTER_CALLBACK (serv, "/quick_snapshot_switch", "f", quick_snapshot_switch);
490                 REGISTER_CALLBACK (serv, "/quick_snapshot_stay", "", quick_snapshot_stay);
491                 REGISTER_CALLBACK (serv, "/quick_snapshot_stay", "f", quick_snapshot_stay);
492                 REGISTER_CALLBACK (serv, "/fit_1_track", "", fit_1_track);
493                 REGISTER_CALLBACK (serv, "/fit_1_track", "f", fit_1_track);
494                 REGISTER_CALLBACK (serv, "/fit_2_tracks", "", fit_2_tracks);
495                 REGISTER_CALLBACK (serv, "/fit_2_tracks", "f", fit_2_tracks);
496                 REGISTER_CALLBACK (serv, "/fit_4_tracks", "", fit_4_tracks);
497                 REGISTER_CALLBACK (serv, "/fit_4_tracks", "f", fit_4_tracks);
498                 REGISTER_CALLBACK (serv, "/fit_8_tracks", "", fit_8_tracks);
499                 REGISTER_CALLBACK (serv, "/fit_8_tracks", "f", fit_8_tracks);
500                 REGISTER_CALLBACK (serv, "/fit_16_tracks", "", fit_16_tracks);
501                 REGISTER_CALLBACK (serv, "/fit_16_tracks", "f", fit_16_tracks);
502                 REGISTER_CALLBACK (serv, "/fit_32_tracks", "", fit_32_tracks);
503                 REGISTER_CALLBACK (serv, "/fit_32_tracks", "f", fit_32_tracks);
504                 REGISTER_CALLBACK (serv, "/fit_all_tracks", "", fit_all_tracks);
505                 REGISTER_CALLBACK (serv, "/fit_all_tracks", "f", fit_all_tracks);
506                 REGISTER_CALLBACK (serv, "/zoom_100_ms", "", zoom_100_ms);
507                 REGISTER_CALLBACK (serv, "/zoom_100_ms", "f", zoom_100_ms);
508                 REGISTER_CALLBACK (serv, "/zoom_1_sec", "", zoom_1_sec);
509                 REGISTER_CALLBACK (serv, "/zoom_1_sec", "f", zoom_1_sec);
510                 REGISTER_CALLBACK (serv, "/zoom_10_sec", "", zoom_10_sec);
511                 REGISTER_CALLBACK (serv, "/zoom_10_sec", "f", zoom_10_sec);
512                 REGISTER_CALLBACK (serv, "/zoom_1_min", "", zoom_1_min);
513                 REGISTER_CALLBACK (serv, "/zoom_1_min", "f", zoom_1_min);
514                 REGISTER_CALLBACK (serv, "/zoom_5_min", "", zoom_5_min);
515                 REGISTER_CALLBACK (serv, "/zoom_5_min", "f", zoom_5_min);
516                 REGISTER_CALLBACK (serv, "/zoom_10_min", "", zoom_10_min);
517                 REGISTER_CALLBACK (serv, "/zoom_10_min", "f", zoom_10_min);
518                 REGISTER_CALLBACK (serv, "/zoom_to_session", "", zoom_to_session);
519                 REGISTER_CALLBACK (serv, "/zoom_to_session", "f", zoom_to_session);
520                 REGISTER_CALLBACK (serv, "/temporal_zoom_in", "f", temporal_zoom_in);
521                 REGISTER_CALLBACK (serv, "/temporal_zoom_in", "", temporal_zoom_in);
522                 REGISTER_CALLBACK (serv, "/temporal_zoom_out", "", temporal_zoom_out);
523                 REGISTER_CALLBACK (serv, "/temporal_zoom_out", "f", temporal_zoom_out);
524                 REGISTER_CALLBACK (serv, "/scroll_up_1_track", "f", scroll_up_1_track);
525                 REGISTER_CALLBACK (serv, "/scroll_up_1_track", "", scroll_up_1_track);
526                 REGISTER_CALLBACK (serv, "/scroll_dn_1_track", "f", scroll_dn_1_track);
527                 REGISTER_CALLBACK (serv, "/scroll_dn_1_track", "", scroll_dn_1_track);
528                 REGISTER_CALLBACK (serv, "/scroll_up_1_page", "f", scroll_up_1_page);
529                 REGISTER_CALLBACK (serv, "/scroll_up_1_page", "", scroll_up_1_page);
530                 REGISTER_CALLBACK (serv, "/scroll_dn_1_page", "f", scroll_dn_1_page);
531                 REGISTER_CALLBACK (serv, "/scroll_dn_1_page", "", scroll_dn_1_page);
532                 REGISTER_CALLBACK (serv, "/bank_up", "", bank_up);
533                 REGISTER_CALLBACK (serv, "/bank_up", "f", bank_up);
534                 REGISTER_CALLBACK (serv, "/bank_down", "", bank_down);
535                 REGISTER_CALLBACK (serv, "/bank_down", "f", bank_down);
536
537                 // controls for "special" strips
538                 REGISTER_CALLBACK (serv, "/master/gain", "f", master_set_gain);
539                 REGISTER_CALLBACK (serv, "/master/fader", "f", master_set_fader);
540                 REGISTER_CALLBACK (serv, "/master/mute", "i", master_set_mute);
541                 REGISTER_CALLBACK (serv, "/master/trimdB", "f", master_set_trim);
542                 REGISTER_CALLBACK (serv, "/master/pan_stereo_position", "f", master_set_pan_stereo_position);
543                 REGISTER_CALLBACK (serv, "/monitor/gain", "f", monitor_set_gain);
544                 REGISTER_CALLBACK (serv, "/monitor/fader", "f", monitor_set_fader);
545                 REGISTER_CALLBACK (serv, "/monitor/mute", "i", monitor_set_mute);
546                 REGISTER_CALLBACK (serv, "/monitor/dim", "i", monitor_set_dim);
547                 REGISTER_CALLBACK (serv, "/monitor/mono", "i", monitor_set_mono);
548
549                 // Controls for the Selected strip
550                 REGISTER_CALLBACK (serv, "/select/recenable", "i", sel_recenable);
551                 REGISTER_CALLBACK (serv, "/select/record_safe", "i", sel_recsafe);
552                 REGISTER_CALLBACK (serv, "/select/mute", "i", sel_mute);
553                 REGISTER_CALLBACK (serv, "/select/solo", "i", sel_solo);
554                 REGISTER_CALLBACK (serv, "/select/solo_iso", "i", sel_solo_iso);
555                 REGISTER_CALLBACK (serv, "/select/solo_safe", "i", sel_solo_safe);
556                 REGISTER_CALLBACK (serv, "/select/monitor_input", "i", sel_monitor_input);
557                 REGISTER_CALLBACK (serv, "/select/monitor_disk", "i", sel_monitor_disk);
558                 REGISTER_CALLBACK (serv, "/select/polarity", "i", sel_phase);
559                 REGISTER_CALLBACK (serv, "/select/gain", "f", sel_gain);
560                 REGISTER_CALLBACK (serv, "/select/fader", "f", sel_fader);
561                 REGISTER_CALLBACK (serv, "/select/trimdB", "f", sel_trim);
562                 REGISTER_CALLBACK (serv, "/select/pan_stereo_position", "f", sel_pan_position);
563                 REGISTER_CALLBACK (serv, "/select/pan_stereo_width", "f", sel_pan_width);
564                 REGISTER_CALLBACK (serv, "/select/send_gain", "if", sel_sendgain);
565                 REGISTER_CALLBACK (serv, "/select/send_fader", "if", sel_sendfader);
566                 REGISTER_CALLBACK (serv, "/select/send_enable", "if", sel_sendenable);
567                 REGISTER_CALLBACK (serv, "/select/master_send_enable", "i", sel_master_send_enable);
568                 REGISTER_CALLBACK (serv, "/select/send_page", "f", sel_send_page);
569                 REGISTER_CALLBACK (serv, "/select/plug_page", "f", sel_plug_page);
570                 REGISTER_CALLBACK (serv, "/select/plugin", "f", sel_plugin);
571                 REGISTER_CALLBACK (serv, "/select/expand", "i", sel_expand);
572                 REGISTER_CALLBACK (serv, "/select/pan_elevation_position", "f", sel_pan_elevation);
573                 REGISTER_CALLBACK (serv, "/select/pan_frontback_position", "f", sel_pan_frontback);
574                 REGISTER_CALLBACK (serv, "/select/pan_lfe_control", "f", sel_pan_lfe);
575                 REGISTER_CALLBACK (serv, "/select/comp_enable", "f", sel_comp_enable);
576                 REGISTER_CALLBACK (serv, "/select/comp_threshold", "f", sel_comp_threshold);
577                 REGISTER_CALLBACK (serv, "/select/comp_speed", "f", sel_comp_speed);
578                 REGISTER_CALLBACK (serv, "/select/comp_mode", "f", sel_comp_mode);
579                 REGISTER_CALLBACK (serv, "/select/comp_makeup", "f", sel_comp_makeup);
580                 REGISTER_CALLBACK (serv, "/select/eq_enable", "f", sel_eq_enable);
581                 REGISTER_CALLBACK (serv, "/select/eq_hpf/freq", "f", sel_eq_hpf_freq);
582                 REGISTER_CALLBACK (serv, "/select/eq_hpf/enable", "f", sel_eq_hpf_enable);
583                 REGISTER_CALLBACK (serv, "/select/eq_hpf/slope", "f", sel_eq_hpf_slope);
584                 REGISTER_CALLBACK (serv, "/select/eq_lpf/freq", "f", sel_eq_lpf_freq);
585                 REGISTER_CALLBACK (serv, "/select/eq_lpf/enable", "f", sel_eq_lpf_enable);
586                 REGISTER_CALLBACK (serv, "/select/eq_lpf/slope", "f", sel_eq_lpf_slope);
587                 REGISTER_CALLBACK (serv, "/select/eq_gain", "if", sel_eq_gain);
588                 REGISTER_CALLBACK (serv, "/select/eq_freq", "if", sel_eq_freq);
589                 REGISTER_CALLBACK (serv, "/select/eq_q", "if", sel_eq_q);
590                 REGISTER_CALLBACK (serv, "/select/eq_shape", "if", sel_eq_shape);
591
592                 /* These commands require the route index in addition to the arg; TouchOSC (et al) can't use these  */
593                 REGISTER_CALLBACK (serv, "/strip/mute", "ii", route_mute);
594                 REGISTER_CALLBACK (serv, "/strip/solo", "ii", route_solo);
595                 REGISTER_CALLBACK (serv, "/strip/solo_iso", "ii", route_solo_iso);
596                 REGISTER_CALLBACK (serv, "/strip/solo_safe", "ii", route_solo_safe);
597                 REGISTER_CALLBACK (serv, "/strip/recenable", "ii", route_recenable);
598                 REGISTER_CALLBACK (serv, "/strip/record_safe", "ii", route_recsafe);
599                 REGISTER_CALLBACK (serv, "/strip/monitor_input", "ii", route_monitor_input);
600                 REGISTER_CALLBACK (serv, "/strip/monitor_disk", "ii", route_monitor_disk);
601                 REGISTER_CALLBACK (serv, "/strip/expand", "ii", strip_expand);
602                 REGISTER_CALLBACK (serv, "/strip/select", "ii", strip_gui_select);
603                 REGISTER_CALLBACK (serv, "/strip/polarity", "ii", strip_phase);
604                 REGISTER_CALLBACK (serv, "/strip/gain", "if", route_set_gain_dB);
605                 REGISTER_CALLBACK (serv, "/strip/fader", "if", route_set_gain_fader);
606                 REGISTER_CALLBACK (serv, "/strip/trimdB", "if", route_set_trim_dB);
607                 REGISTER_CALLBACK (serv, "/strip/pan_stereo_position", "if", route_set_pan_stereo_position);
608                 REGISTER_CALLBACK (serv, "/strip/pan_stereo_width", "if", route_set_pan_stereo_width);
609                 REGISTER_CALLBACK (serv, "/strip/plugin/parameter", "iiif", route_plugin_parameter);
610                 // prints to cerr only
611                 REGISTER_CALLBACK (serv, "/strip/plugin/parameter/print", "iii", route_plugin_parameter_print);
612                 REGISTER_CALLBACK (serv, "/strip/plugin/activate", "ii", route_plugin_activate);
613                 REGISTER_CALLBACK (serv, "/strip/plugin/deactivate", "ii", route_plugin_deactivate);
614                 REGISTER_CALLBACK (serv, "/strip/send/gain", "iif", route_set_send_gain_dB);
615                 REGISTER_CALLBACK (serv, "/strip/send/fader", "iif", route_set_send_fader);
616                 REGISTER_CALLBACK (serv, "/strip/send/enable", "iif", route_set_send_enable);
617                 REGISTER_CALLBACK(serv, "/strip/name", "is", route_rename);
618                 REGISTER_CALLBACK(serv, "/strip/sends", "i", route_get_sends);
619                 REGISTER_CALLBACK(serv, "/strip/receives", "i", route_get_receives);
620                 REGISTER_CALLBACK(serv, "/strip/plugin/list", "i", route_plugin_list);
621                 REGISTER_CALLBACK(serv, "/strip/plugin/descriptor", "ii", route_plugin_descriptor);
622                 REGISTER_CALLBACK(serv, "/strip/plugin/reset", "ii", route_plugin_reset);
623
624                 /* still not-really-standardized query interface */
625                 //REGISTER_CALLBACK (serv, "/ardour/*/#current_value", "", current_value);
626                 //REGISTER_CALLBACK (serv, "/ardour/set", "", set);
627
628                 // un/register_update args= s:ctrl s:returl s:retpath
629                 //lo_server_add_method(serv, "/register_update", "sss", OSC::global_register_update_handler, this);
630                 //lo_server_add_method(serv, "/unregister_update", "sss", OSC::global_unregister_update_handler, this);
631                 //lo_server_add_method(serv, "/register_auto_update", "siss", OSC::global_register_auto_update_handler, this);
632                 //lo_server_add_method(serv, "/unregister_auto_update", "sss", OSC::_global_unregister_auto_update_handler, this);
633
634                 /* this is a special catchall handler,
635                  * register at the end so this is only called if no
636                  * other handler matches (used for debug) */
637                 lo_server_add_method (serv, 0, 0, _catchall, this);
638         }
639 }
640
641 bool
642 OSC::osc_input_handler (IOCondition ioc, lo_server srv)
643 {
644         if (ioc & ~IO_IN) {
645                 return false;
646         }
647
648         if (ioc & IO_IN) {
649                 lo_server_recv (srv);
650         }
651
652         return true;
653 }
654
655 std::string
656 OSC::get_server_url()
657 {
658         string url;
659         char * urlstr;
660
661         if (_osc_server) {
662                 urlstr = lo_server_get_url (_osc_server);
663                 url = urlstr;
664                 free (urlstr);
665         }
666
667         return url;
668 }
669
670 std::string
671 OSC::get_unix_server_url()
672 {
673         string url;
674         char * urlstr;
675
676         if (_osc_unix_server) {
677                 urlstr = lo_server_get_url (_osc_unix_server);
678                 url = urlstr;
679                 free (urlstr);
680         }
681
682         return url;
683 }
684
685 void
686 OSC::gui_changed ()
687 {
688         session->set_dirty();
689 }
690
691 void
692 OSC::listen_to_route (boost::shared_ptr<Stripable> strip, lo_address addr)
693 {
694         if (!strip) {
695                 return;
696         }
697         /* avoid duplicate listens */
698
699         for (RouteObservers::iterator x = route_observers.begin(); x != route_observers.end(); ++x) {
700
701                 OSCRouteObserver* ro;
702
703                 if ((ro = dynamic_cast<OSCRouteObserver*>(*x)) != 0) {
704
705                         int res = strcmp(lo_address_get_url(ro->address()), lo_address_get_url(addr));
706
707                         if (ro->strip() == strip && res == 0) {
708                                 return;
709                         }
710                 }
711         }
712
713         OSCSurface *s = get_surface(addr);
714         uint32_t ssid = get_sid (strip, addr);
715         OSCRouteObserver* o = new OSCRouteObserver (strip, addr, ssid, s);
716         route_observers.push_back (o);
717
718         strip->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::route_lost, this, boost::weak_ptr<Stripable> (strip)), this);
719 }
720
721 void
722 OSC::route_lost (boost::weak_ptr<Stripable> wr)
723 {
724         tick = false;
725         drop_route (wr);
726         bank_dirty = true;
727 }
728
729 void
730 OSC::drop_route (boost::weak_ptr<Stripable> wr)
731 {
732         boost::shared_ptr<Stripable> r = wr.lock ();
733
734         if (!r) {
735                 return;
736         }
737
738         for (RouteObservers::iterator x = route_observers.begin(); x != route_observers.end();) {
739
740                 OSCRouteObserver* rc;
741
742                 if ((rc = dynamic_cast<OSCRouteObserver*>(*x)) != 0) {
743
744                         if (rc->strip() == r) {
745                                 delete *x;
746                                 x = route_observers.erase (x);
747                         } else {
748                                 ++x;
749                         }
750                 } else {
751                         ++x;
752                 }
753         }
754 }
755
756 void
757 OSC::end_listen (boost::shared_ptr<Stripable> r, lo_address addr)
758 {
759         RouteObservers::iterator x;
760
761         // Remove the route observers
762         for (x = route_observers.begin(); x != route_observers.end();) {
763
764                 OSCRouteObserver* ro;
765
766                 if ((ro = dynamic_cast<OSCRouteObserver*>(*x)) != 0) {
767
768                         int res = strcmp(lo_address_get_url(ro->address()), lo_address_get_url(addr));
769
770                         if (ro->strip() == r && res == 0) {
771                                 delete *x;
772                                 x = route_observers.erase (x);
773                         }
774                         else {
775                                 ++x;
776                         }
777                 }
778                 else {
779                         ++x;
780                 }
781         }
782 }
783
784 void
785 OSC::current_value_query (const char* path, size_t len, lo_arg **argv, int argc, lo_message msg)
786 {
787         char* subpath;
788
789         subpath = (char*) malloc (len-15+1);
790         memcpy (subpath, path, len-15);
791         subpath[len-15] = '\0';
792
793         send_current_value (subpath, argv, argc, msg);
794
795         free (subpath);
796 }
797
798 void
799 OSC::send_current_value (const char* path, lo_arg** argv, int argc, lo_message msg)
800 {
801         if (!session) {
802                 return;
803         }
804
805         lo_message reply = lo_message_new ();
806         boost::shared_ptr<Route> r;
807         int id;
808
809         lo_message_add_string (reply, path);
810
811         if (argc == 0) {
812                 lo_message_add_string (reply, "bad syntax");
813         } else {
814                 id = argv[0]->i;
815                 r = session->get_remote_nth_route (id);
816
817                 if (!r) {
818                         lo_message_add_string (reply, "not found");
819                 } else {
820
821                         if (strcmp (path, "/strip/state") == 0) {
822
823                                 if (boost::dynamic_pointer_cast<AudioTrack>(r)) {
824                                         lo_message_add_string (reply, "AT");
825                                 } else if (boost::dynamic_pointer_cast<MidiTrack>(r)) {
826                                         lo_message_add_string (reply, "MT");
827                                 } else {
828                                         lo_message_add_string (reply, "B");
829                                 }
830
831                                 lo_message_add_string (reply, r->name().c_str());
832                                 lo_message_add_int32 (reply, r->n_inputs().n_audio());
833                                 lo_message_add_int32 (reply, r->n_outputs().n_audio());
834                                 lo_message_add_int32 (reply, r->muted());
835                                 lo_message_add_int32 (reply, r->soloed());
836
837                         } else if (strcmp (path, "/strip/mute") == 0) {
838
839                                 lo_message_add_int32 (reply, (float) r->muted());
840
841                         } else if (strcmp (path, "/strip/solo") == 0) {
842
843                                 lo_message_add_int32 (reply, r->soloed());
844                         }
845                 }
846         }
847         OSCSurface *sur = get_surface(get_address (msg));
848
849         if (sur->feedback[14]) {
850                 lo_send_message (get_address (msg), "/reply", reply);
851         } else {
852                 lo_send_message (get_address (msg), "#reply", reply);
853         }
854         lo_message_free (reply);
855 }
856
857 int
858 OSC::_catchall (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data)
859 {
860         return ((OSC*)user_data)->catchall (path, types, argv, argc, data);
861 }
862
863 int
864 OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg)
865 {
866         size_t len;
867         int ret = 1; /* unhandled */
868
869         //cerr << "Received a message, path = " << path << " types = \""
870         //     << (types ? types : "NULL") << '"' << endl;
871
872         /* 15 for /#current_value plus 2 for /<path> */
873
874         len = strlen (path);
875         OSCSurface *sur = get_surface(get_address (msg));
876
877         if (strstr (path, "/automation")) {
878                 ret = set_automation (path, types, argv, argc, msg);
879
880         } else
881         if (strstr (path, "/touch")) {
882                 ret = touch_detect (path, types, argv, argc, msg);
883
884         } else
885         if (len >= 17 && !strcmp (&path[len-15], "/#current_value")) {
886                 current_value_query (path, len, argv, argc, msg);
887                 ret = 0;
888
889         } else
890         if (!strncmp (path, "/cue/", 5)) {
891
892                 ret = cue_parse (path, types, argv, argc, msg);
893
894         } else
895         if (!strncmp (path, "/select/plugin/parameter", 24)) {
896
897                 ret = select_plugin_parameter (path, types, argv, argc, msg);
898
899         } else
900         if (!strncmp (path, "/access_action/", 15)) {
901                 check_surface (msg);
902                 if (!(argc && !argv[0]->i)) {
903                         std::string action_path = path;
904
905                         access_action (action_path.substr(15));
906                 }
907
908                 ret = 0;
909         } else
910         if (strcmp (path, "/strip/listen") == 0) {
911                 check_surface (msg);
912
913                 cerr << "set up listener\n";
914
915                 lo_message reply = lo_message_new ();
916
917                 if (argc <= 0) {
918                         lo_message_add_string (reply, "syntax error");
919                 } else {
920                         for (int n = 0; n < argc; ++n) {
921
922                                 boost::shared_ptr<Route> r = session->get_remote_nth_route (argv[n]->i);
923
924                                 if (!r) {
925                                         lo_message_add_string (reply, "not found");
926                                         cerr << "no such route\n";
927                                         break;
928                                 } else {
929                                         cerr << "add listener\n";
930                                         listen_to_route (r, get_address (msg));
931                                         lo_message_add_int32 (reply, argv[n]->i);
932                                 }
933                         }
934                 }
935
936                 if (sur->feedback[14]) {
937                         lo_send_message (get_address (msg), "/reply", reply);
938                 } else {
939                         lo_send_message (get_address (msg), "#reply", reply);
940                 }
941                 lo_message_free (reply);
942
943                 ret = 0;
944
945         } else
946         if (strcmp (path, "/strip/ignore") == 0) {
947                 check_surface (msg);
948
949                 for (int n = 0; n < argc; ++n) {
950
951                         boost::shared_ptr<Route> r = session->get_remote_nth_route (argv[n]->i);
952
953                         if (r) {
954                                 end_listen (r, get_address (msg));
955                         }
956                 }
957
958                 ret = 0;
959         } else
960         if (!strncmp (path, "/strip/gain/", 12) && strlen (path) > 12) {
961                 // in dB
962                 int ssid = atoi (&path[12]);
963                 ret = route_set_gain_dB (ssid, argv[0]->f, msg);
964         }
965         else if (!strncmp (path, "/strip/fader/", 13) && strlen (path) > 13) {
966                 // in fader position
967                 int ssid = atoi (&path[13]);
968                 ret = route_set_gain_fader (ssid, argv[0]->f, msg);
969         }
970         else if (!strncmp (path, "/strip/db_delta", 15)) {
971                 // in db delta
972                 int ssid;
973                 int ar_off = 0;
974                 float delta;
975                 if (strlen (path) > 15 && argc == 1) {
976                         ssid = atoi (&path[16]);
977                 } else if (argc == 2) {
978                         if (types[0] == 'f') {
979                                 ssid = (int) argv[0]->f;
980                         } else {
981                                 ssid = argv[0]->i;
982                         }
983                         ar_off = 1;
984                 } else {
985                         return -1;
986                 }
987                 if (types[ar_off] == 'f') {
988                         delta = argv[ar_off]->f;
989                 } else {
990                         delta = (float) argv[ar_off]->i;
991                 }
992                 ret = strip_db_delta (ssid, delta, msg);
993         }
994         else if (!strncmp (path, "/strip/trimdB/", 14) && strlen (path) > 14) {
995                 int ssid = atoi (&path[14]);
996                 ret = route_set_trim_dB (ssid, argv[0]->f, msg);
997         }
998         else if (!strncmp (path, "/strip/pan_stereo_position/", 27) && strlen (path) > 27) {
999                 int ssid = atoi (&path[27]);
1000                 ret = route_set_pan_stereo_position (ssid, argv[0]->f, msg);
1001         }
1002         else if (!strncmp (path, "/strip/mute/", 12) && strlen (path) > 12) {
1003                 int ssid = atoi (&path[12]);
1004                 ret = route_mute (ssid, argv[0]->i, msg);
1005         }
1006         else if (!strncmp (path, "/strip/solo/", 12) && strlen (path) > 12) {
1007                 int ssid = atoi (&path[12]);
1008                 ret = route_solo (ssid, argv[0]->i, msg);
1009         }
1010         else if (!strncmp (path, "/strip/monitor_input/", 21) && strlen (path) > 21) {
1011                 int ssid = atoi (&path[21]);
1012                 ret = route_monitor_input (ssid, argv[0]->i, msg);
1013         }
1014         else if (!strncmp (path, "/strip/monitor_disk/", 20) && strlen (path) > 20) {
1015                 int ssid = atoi (&path[20]);
1016                 ret = route_monitor_disk (ssid, argv[0]->i, msg);
1017         }
1018         else if (!strncmp (path, "/strip/recenable/", 17) && strlen (path) > 17) {
1019                 int ssid = atoi (&path[17]);
1020                 ret = route_recenable (ssid, argv[0]->i, msg);
1021         }
1022         else if (!strncmp (path, "/strip/record_safe/", 19) && strlen (path) > 19) {
1023                 int ssid = atoi (&path[19]);
1024                 ret = route_recsafe (ssid, argv[0]->i, msg);
1025         }
1026         else if (!strncmp (path, "/strip/expand/", 14) && strlen (path) > 14) {
1027                 int ssid = atoi (&path[14]);
1028                 ret = strip_expand (ssid, argv[0]->i, msg);
1029         }
1030         else if (!strncmp (path, "/strip/select/", 14) && strlen (path) > 14) {
1031                 int ssid = atoi (&path[14]);
1032                 ret = strip_gui_select (ssid, argv[0]->i, msg);
1033         }
1034         else if (!strncmp (path, "/select/send_gain/", 18) && strlen (path) > 18) {
1035                 int ssid = atoi (&path[18]);
1036                 ret = sel_sendgain (ssid, argv[0]->f, msg);
1037         }
1038         else if (!strncmp (path, "/select/send_fader/", 19) && strlen (path) > 19) {
1039                 int ssid = atoi (&path[19]);
1040                 ret = sel_sendfader (ssid, argv[0]->f, msg);
1041         }
1042         else if (!strncmp (path, "/select/send_enable/", 20) && strlen (path) > 20) {
1043                 int ssid = atoi (&path[20]);
1044                 ret = sel_sendenable (ssid, argv[0]->f, msg);
1045         }
1046         else if (!strncmp (path, "/select/eq_gain/", 16) && strlen (path) > 16) {
1047                 int ssid = atoi (&path[16]);
1048                 ret = sel_eq_gain (ssid, argv[0]->f, msg);
1049         }
1050         else if (!strncmp (path, "/select/eq_freq/", 16) && strlen (path) > 16) {
1051                 int ssid = atoi (&path[16]);
1052                 ret = sel_eq_freq (ssid, argv[0]->f , msg);
1053         }
1054         else if (!strncmp (path, "/select/eq_q/", 13) && strlen (path) > 13) {
1055                 int ssid = atoi (&path[13]);
1056                 ret = sel_eq_q (ssid, argv[0]->f, msg);
1057         }
1058         else if (!strncmp (path, "/select/eq_shape/", 17) && strlen (path) > 17) {
1059                 int ssid = atoi (&path[17]);
1060                 ret = sel_eq_shape (ssid, argv[0]->f, msg);
1061         }
1062         else if (!strncmp (path, "/set_surface", 12)) {
1063                 ret = surface_parse (path, types, argv, argc, msg);
1064         }
1065         if (ret) {
1066                 check_surface (msg);
1067         }
1068
1069         if ((ret && _debugmode != Off)) {
1070                 debugmsg (_("Unhandled OSC message"), path, types, argv, argc);
1071         } else if (!ret && _debugmode == All) {
1072                 debugmsg (_("OSC"), path, types, argv, argc);
1073         }
1074
1075         return ret;
1076 }
1077
1078 void
1079 OSC::debugmsg (const char *prefix, const char *path, const char* types, lo_arg **argv, int argc)
1080 {
1081         std::stringstream ss;
1082         for (int i = 0; i < argc; ++i) {
1083                 lo_type type = (lo_type)types[i];
1084                         ss << " ";
1085                 switch (type) {
1086                         case LO_INT32:
1087                                 ss << "i:" << argv[i]->i;
1088                                 break;
1089                         case LO_FLOAT:
1090                                 ss << "f:" << argv[i]->f;
1091                                 break;
1092                         case LO_DOUBLE:
1093                                 ss << "d:" << argv[i]->d;
1094                                 break;
1095                         case LO_STRING:
1096                                 ss << "s:" << &argv[i]->s;
1097                                 break;
1098                         case LO_INT64:
1099                                 ss << "h:" << argv[i]->h;
1100                                 break;
1101                         case LO_CHAR:
1102                                 ss << "c:" << argv[i]->s;
1103                                 break;
1104                         case LO_TIMETAG:
1105                                 ss << "<Timetag>";
1106                                 break;
1107                         case LO_BLOB:
1108                                 ss << "<BLOB>";
1109                                 break;
1110                         case LO_TRUE:
1111                                 ss << "#T";
1112                                 break;
1113                         case LO_FALSE:
1114                                 ss << "#F";
1115                                 break;
1116                         case LO_NIL:
1117                                 ss << "NIL";
1118                                 break;
1119                         case LO_INFINITUM:
1120                                 ss << "#inf";
1121                                 break;
1122                         case LO_MIDI:
1123                                 ss << "<MIDI>";
1124                                 break;
1125                         case LO_SYMBOL:
1126                                 ss << "<SYMBOL>";
1127                                 break;
1128                         default:
1129                                 ss << "< ?? >";
1130                                 break;
1131                 }
1132         }
1133         PBD::info << prefix << ": " << path << ss.str() << endmsg;
1134 }
1135
1136 // "Application Hook" Handlers //
1137 void
1138 OSC::session_loaded (Session& s)
1139 {
1140 //      lo_address listener = lo_address_new (NULL, "7770");
1141 //      lo_send (listener, "/session/loaded", "ss", s.path().c_str(), s.name().c_str());
1142 }
1143
1144 void
1145 OSC::session_exported (std::string path, std::string name)
1146 {
1147         lo_address listener = lo_address_new (NULL, "7770");
1148         lo_send (listener, "/session/exported", "ss", path.c_str(), name.c_str());
1149         lo_address_free (listener);
1150 }
1151
1152 // end "Application Hook" Handlers //
1153
1154 /* path callbacks */
1155
1156 int
1157 OSC::current_value (const char */*path*/, const char */*types*/, lo_arg **/*argv*/, int /*argc*/, void */*data*/, void* /*user_data*/)
1158 {
1159 #if 0
1160         const char* returl;
1161
1162         if (argc < 3 || types == 0 || strlen (types) < 3 || types[0] != 's' || types[1] != 's' || types[2] != s) {
1163                 return 1;
1164         }
1165
1166         const char *returl = argv[1]->s;
1167         lo_address addr = find_or_cache_addr (returl);
1168
1169         const char *retpath = argv[2]->s;
1170
1171
1172         if (strcmp (argv[0]->s, "transport_frame") == 0) {
1173
1174                 if (session) {
1175                         lo_send (addr, retpath, "i", session->transport_frame());
1176                 }
1177
1178         } else if (strcmp (argv[0]->s, "transport_speed") == 0) {
1179
1180                 if (session) {
1181                         lo_send (addr, retpath, "i", session->transport_frame());
1182                 }
1183
1184         } else if (strcmp (argv[0]->s, "transport_locked") == 0) {
1185
1186                 if (session) {
1187                         lo_send (addr, retpath, "i", session->transport_frame());
1188                 }
1189
1190         } else if (strcmp (argv[0]->s, "punch_in") == 0) {
1191
1192                 if (session) {
1193                         lo_send (addr, retpath, "i", session->transport_frame());
1194                 }
1195
1196         } else if (strcmp (argv[0]->s, "punch_out") == 0) {
1197
1198                 if (session) {
1199                         lo_send (addr, retpath, "i", session->transport_frame());
1200                 }
1201
1202         } else if (strcmp (argv[0]->s, "rec_enable") == 0) {
1203
1204                 if (session) {
1205                         lo_send (addr, retpath, "i", session->transport_frame());
1206                 }
1207
1208         } else {
1209
1210                 /* error */
1211         }
1212 #endif
1213         return 0;
1214 }
1215
1216 void
1217 OSC::routes_list (lo_message msg)
1218 {
1219         if (!session) {
1220                 return;
1221         }
1222         OSCSurface *sur = get_surface(get_address (msg));
1223         sur->no_clear = true;
1224
1225         for (int n = 0; n < (int) sur->nstrips; ++n) {
1226
1227                 boost::shared_ptr<Stripable> s = get_strip (n + 1, get_address (msg));
1228
1229                 if (s) {
1230                         // some things need the route
1231                         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
1232
1233                         lo_message reply = lo_message_new ();
1234
1235                         if (s->presentation_info().flags() & PresentationInfo::AudioTrack) {
1236                                 lo_message_add_string (reply, "AT");
1237                         } else if (s->presentation_info().flags() & PresentationInfo::MidiTrack) {
1238                                 lo_message_add_string (reply, "MT");
1239                         } else if (s->presentation_info().flags() & PresentationInfo::AudioBus) {
1240                                 // r->feeds (session->master_out()) may make more sense
1241                                 if (r->direct_feeds_according_to_reality (session->master_out())) {
1242                                         // this is a bus
1243                                         lo_message_add_string (reply, "B");
1244                                 } else {
1245                                         // this is an Aux out
1246                                         lo_message_add_string (reply, "AX");
1247                                 }
1248                         } else if (s->presentation_info().flags() & PresentationInfo::MidiBus) {
1249                                 lo_message_add_string (reply, "MB");
1250                         } else if (s->presentation_info().flags() & PresentationInfo::VCA) {
1251                                 lo_message_add_string (reply, "V");
1252                         }
1253
1254                         lo_message_add_string (reply, s->name().c_str());
1255                         if (r) {
1256                                 // routes have inputs and outputs
1257                                 lo_message_add_int32 (reply, r->n_inputs().n_audio());
1258                                 lo_message_add_int32 (reply, r->n_outputs().n_audio());
1259                         } else {
1260                                 // non-routes like VCAs don't
1261                                 lo_message_add_int32 (reply, 0);
1262                                 lo_message_add_int32 (reply, 0);
1263                         }
1264                         if (s->mute_control()) {
1265                                 lo_message_add_int32 (reply, s->mute_control()->get_value());
1266                         } else {
1267                                 lo_message_add_int32 (reply, 0);
1268                         }
1269                         if (s->solo_control()) {
1270                                 lo_message_add_int32 (reply, s->solo_control()->get_value());
1271                         } else {
1272                                 lo_message_add_int32 (reply, 0);
1273                         }
1274                         lo_message_add_int32 (reply, n + 1);
1275                         if (s->rec_enable_control()) {
1276                                 lo_message_add_int32 (reply, s->rec_enable_control()->get_value());
1277                         }
1278
1279                         //Automatically listen to stripables listed
1280                         listen_to_route(s, get_address (msg));
1281
1282                         if (sur->feedback[14]) {
1283                                 lo_send_message (get_address (msg), "/reply", reply);
1284                         } else {
1285                                 lo_send_message (get_address (msg), "#reply", reply);
1286                         }
1287                         lo_message_free (reply);
1288                 }
1289         }
1290
1291         // Send end of listing message
1292         lo_message reply = lo_message_new ();
1293
1294         lo_message_add_string (reply, "end_route_list");
1295         lo_message_add_int64 (reply, session->frame_rate());
1296         lo_message_add_int64 (reply, session->current_end_frame());
1297         if (session->monitor_out()) {
1298                 // this session has a monitor section
1299                 lo_message_add_int32 (reply, 1);
1300         } else {
1301                 lo_message_add_int32 (reply, 0);
1302         }
1303
1304         if (sur->feedback[14]) {
1305                 lo_send_message (get_address (msg), "/reply", reply);
1306         } else {
1307                 lo_send_message (get_address (msg), "#reply", reply);
1308         }
1309
1310         lo_message_free (reply);
1311 }
1312
1313 int
1314 OSC::cancel_all_solos ()
1315 {
1316         session->cancel_all_solo ();
1317         return 0;
1318 }
1319
1320 lo_address
1321 OSC::get_address (lo_message msg)
1322 {
1323         if (address_only) {
1324                 lo_address addr = lo_message_get_source (msg);
1325                 string host = lo_address_get_hostname (addr);
1326                 int protocol = lo_address_get_protocol (addr);
1327                 return lo_address_new_with_proto (protocol, host.c_str(), remote_port.c_str());
1328         } else {
1329                 return lo_message_get_source (msg);
1330         }
1331 }
1332
1333 int
1334 OSC::refresh_surface (lo_message msg)
1335 {
1336         if (address_only) {
1337                 // get rid of all surfaces and observers.
1338                 // needs change to only clear those for this address on all ports
1339                 clear_devices();
1340         }
1341         OSCSurface *s = get_surface(get_address (msg));
1342         // restart all observers
1343         set_surface (s->bank_size, (uint32_t) s->strip_types.to_ulong(), (uint32_t) s->feedback.to_ulong(), \
1344                 (uint32_t) s->gainmode, (uint32_t) s->send_page_size, (uint32_t) s->plug_page_size, msg);
1345         return 0;
1346 }
1347
1348 void
1349 OSC::clear_devices ()
1350 {
1351         for (RouteObservers::iterator x = route_observers.begin(); x != route_observers.end();) {
1352
1353                 OSCRouteObserver* rc;
1354
1355                 if ((rc = dynamic_cast<OSCRouteObserver*>(*x)) != 0) {
1356                         delete *x;
1357                         x = route_observers.erase (x);
1358                 } else {
1359                         ++x;
1360                 }
1361                 // slow devices need time to clear buffers
1362                 usleep ((uint32_t) 10);
1363         }
1364         // Should maybe do global_observers too
1365         for (GlobalObservers::iterator x = global_observers.begin(); x != global_observers.end();) {
1366
1367                 OSCGlobalObserver* gc;
1368
1369                 if ((gc = dynamic_cast<OSCGlobalObserver*>(*x)) != 0) {
1370                         delete *x;
1371                         x = global_observers.erase (x);
1372                 } else {
1373                         ++x;
1374                 }
1375         }
1376         // delete select observers
1377         for (uint32_t it = 0; it < _surface.size(); ++it) {
1378                 OSCSurface* sur = &_surface[it];
1379                 OSCSelectObserver* so;
1380                 if ((so = dynamic_cast<OSCSelectObserver*>(sur->sel_obs)) != 0) {
1381                         delete so;
1382                 }
1383         }
1384         // delete cue observers
1385         for (CueObservers::iterator x = cue_observers.begin(); x != cue_observers.end();) {
1386                 OSCCueObserver* co;
1387                 if ((co = dynamic_cast<OSCCueObserver*>(*x)) != 0) {
1388                         delete *x;
1389                         x = cue_observers.erase (x);
1390                 } else {
1391                         ++x;
1392                 }
1393         }
1394
1395         // clear out surfaces
1396         _surface.clear();
1397 }
1398
1399 int
1400 OSC::surface_parse (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg)
1401 {
1402         int ret = 1; /* unhandled */
1403         OSCSurface *sur = get_surface(get_address (msg));
1404         int pi_page = sur->plug_page_size;
1405         int se_page = sur->send_page_size;
1406         int fadermode = sur->gainmode;
1407         int feedback = sur->feedback.to_ulong();
1408         int strip_types = sur->strip_types.to_ulong();
1409         int bank_size = sur->bank_size;
1410
1411
1412         if (!strncmp (path, "/set_surface/feedback", 21)) {
1413                 if (argv[0]->f) {
1414                         ret = set_surface_feedback ((int)argv[0]->f, msg);
1415                 } else {
1416                         ret = set_surface_feedback (argv[0]->i, msg);
1417                 }
1418         }
1419         else if (!strncmp (path, "/set_surface/bank_size", 22)) {
1420                 if (argv[0]->f) {
1421                         ret = set_surface_bank_size ((int)argv[0]->f, msg);
1422                 } else {
1423                         ret = set_surface_bank_size (argv[0]->i, msg);
1424                 }
1425         }
1426         else if (!strncmp (path, "/set_surface/gainmode", 21)) {
1427                 if (argv[0]->f) {
1428                         ret = set_surface_gainmode ((int)argv[0]->f, msg);
1429                 } else {
1430                         ret = set_surface_gainmode (argv[0]->i, msg);
1431                 }
1432         }
1433         else if (!strncmp (path, "/set_surface/strip_types", 24)) {
1434                 if (argv[0]->f) {
1435                         ret = set_surface_strip_types ((int)argv[0]->f, msg);
1436                 } else {
1437                         ret = set_surface_strip_types (argv[0]->i, msg);
1438                 }
1439         }
1440         else if (!strncmp (path, "/set_surface/send_page_size", 27)) {
1441                 if (argv[0]->f) {
1442                         ret = sel_send_pagesize ((int)argv[0]->f, msg);
1443                 } else {
1444                         ret = sel_send_pagesize (argv[0]->i, msg);
1445                 }
1446         }
1447         else if (!strncmp (path, "/set_surface/plugin_page_size", 29)) {
1448                 if (argv[0]->f) {
1449                         ret = sel_plug_pagesize ((int)argv[0]->f, msg);
1450                 } else {
1451                         ret = sel_plug_pagesize (argv[0]->i, msg);
1452                 }
1453         } else if (strlen(path) == 12) {
1454                 // command is in /set_surface iii form
1455                 switch (argc) {
1456                         case 6:
1457                                 if (argv[5]->f) {
1458                                         pi_page = (int) argv[5]->f;
1459                                 } else {
1460                                         pi_page = argv[5]->i;
1461                                 }
1462                         case 5:
1463                                 if (argv[4]->f) {
1464                                         se_page = (int) argv[4]->f;
1465                                 } else {
1466                                         se_page = argv[4]->i;
1467                                 }
1468                         case 4:
1469                                 if (argv[3]->f) {
1470                                         fadermode = (int) argv[3]->f;
1471                                 } else {
1472                                         fadermode = argv[3]->i;
1473                                 }
1474                         case 3:
1475                                 if (argv[2]->f) {
1476                                         feedback = (int) argv[2]->f;
1477                                 } else {
1478                                         feedback = argv[2]->i;
1479                                 }
1480                         case 2:
1481                                 if (argv[1]->f) {
1482                                         strip_types = (int) argv[1]->f;
1483                                 } else {
1484                                         strip_types = argv[1]->i;
1485                                 }
1486                         case 1:
1487                                 if (argv[0]->f) {
1488                                         bank_size = (int) argv[0]->f;
1489                                 } else {
1490                                         bank_size = argv[0]->i;
1491                                 }
1492                                 ret = set_surface (bank_size, strip_types, feedback, fadermode, se_page, pi_page, msg);
1493                                 break;
1494                         case 0:
1495                                 // send current setup
1496                                 {
1497                                         lo_message reply = lo_message_new ();
1498                                         lo_message_add_int32 (reply, bank_size);
1499                                         lo_message_add_int32 (reply, strip_types);
1500                                         lo_message_add_int32 (reply, feedback);
1501                                         lo_message_add_int32 (reply, fadermode);
1502                                         lo_message_add_int32 (reply, se_page);
1503                                         lo_message_add_int32 (reply, pi_page);
1504                                         lo_send_message (get_address (msg), "/set_surface", reply);
1505                                         lo_message_free (reply);
1506                                         return 0;
1507                                 }
1508                                 break;
1509
1510                         default:
1511                                 PBD::warning << "OSC: Too many parameters." << endmsg;
1512                                 return 1;
1513                                 break;
1514                 }
1515         } else if (isdigit(path[13])) {
1516                 // some of our parameters must be "in-lined"
1517                 bank_size = atoi (&path[13]);
1518                 const char * par = strstr (&path[13], "/");
1519                 if (par) {
1520                         strip_types = atoi (&par[1]);
1521                         const char * fb = strstr (&par[1], "/");
1522                         if (fb) {
1523                                 feedback = atoi (&fb[1]);
1524                                 const char * fm = strstr (&fb[1], "/");
1525                                 if (fm) {
1526                                         fadermode = atoi (&fm[1]);
1527                                         const char * sp = strstr (&fm[1], "/");
1528                                         if (sp) {
1529                                                 se_page = atoi (&sp[1]);
1530                                                 const char * pp = strstr (&sp[1], "/");
1531                                                 if (pp) {
1532                                                         pi_page = atoi (&pp[1]);
1533                                                 } else {
1534                                                         if (argv[0]->f) {
1535                                                                 pi_page = (int) argv[0]->f;
1536                                                         } else if (argv[0]->i) {
1537                                                                 pi_page = argv[0]->i;
1538                                                         }
1539                                                 }
1540                                         } else {
1541                                                 if (argv[0]->f) {
1542                                                         se_page = (int) argv[0]->f;
1543                                                 } else if (argv[0]->i) {
1544                                                         se_page = argv[0]->i;
1545                                                 }
1546                                         }
1547                                 } else {
1548                                         if (argv[0]->f) {
1549                                                 fadermode = (int) argv[0]->f;
1550                                         } else if (argv[0]->i) {
1551                                                 fadermode = argv[0]->i;
1552                                         }
1553                                 }
1554                         } else {
1555                                 if (argv[0]->f) {
1556                                         feedback = (int) argv[0]->f;
1557                                 } else if (argv[0]->i) {
1558                                         feedback = argv[0]->i;
1559                                 }
1560                         }
1561                 } else {
1562                         if (argv[0]->f) {
1563                                 strip_types = (int) argv[0]->f;
1564                         } else if (argv[0]->i) {
1565                                 strip_types = argv[0]->i;
1566                         }
1567                 }
1568                 ret = set_surface (bank_size, strip_types, feedback, fadermode, se_page, pi_page, msg);
1569         }
1570         return ret;
1571 }
1572
1573 int
1574 OSC::set_surface (uint32_t b_size, uint32_t strips, uint32_t fb, uint32_t gm, uint32_t se_size, uint32_t pi_size, lo_message msg)
1575 {
1576         OSCSurface *s = get_surface(get_address (msg));
1577         s->bank_size = b_size;
1578         s->strip_types = strips;
1579         s->feedback = fb;
1580         s->gainmode = gm;
1581         s->send_page_size = se_size;
1582         s->plug_page_size = pi_size;
1583         // set bank and strip feedback
1584         set_bank(s->bank, msg);
1585
1586         global_feedback (s->feedback, get_address (msg), s->gainmode);
1587         sel_send_pagesize (se_size, msg);
1588         sel_plug_pagesize (pi_size, msg);
1589         return 0;
1590 }
1591
1592 int
1593 OSC::set_surface_bank_size (uint32_t bs, lo_message msg)
1594 {
1595         OSCSurface *s = get_surface(get_address (msg));
1596         s->bank_size = bs;
1597
1598         // set bank and strip feedback
1599         set_bank(s->bank, msg);
1600         return 0;
1601 }
1602
1603 int
1604 OSC::set_surface_strip_types (uint32_t st, lo_message msg)
1605 {
1606         OSCSurface *s = get_surface(get_address (msg));
1607         s->strip_types = st;
1608
1609         // set bank and strip feedback
1610         set_bank(s->bank, msg);
1611         return 0;
1612 }
1613
1614
1615 int
1616 OSC::set_surface_feedback (uint32_t fb, lo_message msg)
1617 {
1618         OSCSurface *s = get_surface(get_address (msg));
1619         s->feedback = fb;
1620
1621         // set bank and strip feedback
1622         set_bank(s->bank, msg);
1623
1624         // Set global/master feedback
1625         global_feedback (s->feedback, get_address (msg), s->gainmode);
1626         return 0;
1627 }
1628
1629 int
1630 OSC::set_surface_gainmode (uint32_t gm, lo_message msg)
1631 {
1632         OSCSurface *s = get_surface(get_address (msg));
1633         s->gainmode = gm;
1634
1635         // set bank and strip feedback
1636         set_bank(s->bank, msg);
1637
1638         // Set global/master feedback
1639         global_feedback (s->feedback, get_address (msg), s->gainmode);
1640         return 0;
1641 }
1642
1643 int
1644 OSC::check_surface (lo_message msg)
1645 {
1646         if (!session) {
1647                 return -1;
1648         }
1649         get_surface(get_address (msg));
1650         return 0;
1651 }
1652
1653 OSC::OSCSurface *
1654 OSC::get_surface (lo_address addr)
1655 {
1656         string r_url;
1657         char * rurl;
1658         if (address_only) {
1659                 string host = lo_address_get_hostname (addr);
1660                 int protocol = lo_address_get_protocol (addr);
1661                 addr = lo_address_new_with_proto (protocol, host.c_str(), remote_port.c_str());
1662         }
1663
1664         rurl = lo_address_get_url (addr);
1665         r_url = rurl;
1666         free (rurl);
1667         for (uint32_t it = 0; it < _surface.size(); ++it) {
1668                 //find setup for this server
1669                 if (!_surface[it].remote_url.find(r_url)){
1670                         return &_surface[it];
1671                 }
1672         }
1673
1674         // No surface create one with default values
1675         OSCSurface s;
1676         s.remote_url = r_url;
1677         s.no_clear = false;
1678         s.jogmode = JOG;
1679         s.bank = 1;
1680         s.bank_size = default_banksize; // need to find out how many strips there are
1681         s.strip_types = default_strip; // 159 is tracks, busses, and VCAs (no master/monitor)
1682         s.feedback = default_feedback;
1683         s.gainmode = default_gainmode;
1684         s.sel_obs = 0;
1685         s.expand = 0;
1686         s.expand_enable = false;
1687         s.cue = false;
1688         s.aux = 0;
1689         s.strips = get_sorted_stripables(s.strip_types, s.cue);
1690         s.send_page = 1;
1691         s.send_page_size = default_send_size;
1692         s.plug_page = 1;
1693         s.plug_page_size = default_plugin_size;
1694         s.plugin_id = 1;
1695
1696         s.nstrips = s.strips.size();
1697         _surface.push_back (s);
1698         // moved this down here as selection may need s.<anything to do with select> set
1699         if (!_select || (_select != ControlProtocol::first_selected_stripable())) {
1700                 gui_selection_changed();
1701         }
1702
1703         // set bank and strip feedback
1704         _set_bank(s.bank, addr);
1705
1706         // Set global/master feedback
1707         global_feedback (s.feedback, addr, s.gainmode);
1708
1709         return &_surface[_surface.size() - 1];
1710 }
1711
1712 // setup global feedback for a surface
1713 void
1714 OSC::global_feedback (bitset<32> feedback, lo_address addr, uint32_t gainmode)
1715 {
1716         // first destroy global observer for this surface
1717         GlobalObservers::iterator x;
1718         for (x = global_observers.begin(); x != global_observers.end();) {
1719
1720                 OSCGlobalObserver* ro;
1721
1722                 if ((ro = dynamic_cast<OSCGlobalObserver*>(*x)) != 0) {
1723
1724                         int res = strcmp(lo_address_get_url(ro->address()), lo_address_get_url(addr));
1725
1726                         if (res == 0) {
1727                                 delete *x;
1728                                 x = global_observers.erase (x);
1729                         } else {
1730                                 ++x;
1731                         }
1732                 } else {
1733                         ++x;
1734                 }
1735         }
1736         if (feedback[4] || feedback[3] || feedback[5] || feedback[6]) {
1737                 // create a new Global Observer for this surface
1738                 OSCGlobalObserver* o = new OSCGlobalObserver (*session, addr, gainmode, /*s->*/feedback);
1739                 global_observers.push_back (o);
1740         }
1741 }
1742
1743 void
1744 OSC::notify_routes_added (ARDOUR::RouteList &)
1745 {
1746         // not sure if we need this PI change seems to cover
1747         //recalcbanks();
1748 }
1749
1750 void
1751 OSC::notify_vca_added (ARDOUR::VCAList &)
1752 {
1753         // not sure if we need this PI change seems to cover
1754         //recalcbanks();
1755 }
1756
1757 void
1758 OSC::recalcbanks ()
1759 {
1760         tick = false;
1761         bank_dirty = true;
1762 }
1763
1764 void
1765 OSC::_recalcbanks ()
1766 {
1767         if (!_select || (_select != ControlProtocol::first_selected_stripable())) {
1768                 _select = ControlProtocol::first_selected_stripable();
1769         }
1770
1771         // do a set_bank for each surface we know about.
1772         for (uint32_t it = 0; it < _surface.size(); ++it) {
1773                 OSCSurface* sur = &_surface[it];
1774                 // find lo_address
1775                 lo_address addr = lo_address_new_from_url (sur->remote_url.c_str());
1776                 if (sur->cue) {
1777                         _cue_set (sur->aux, addr);
1778                 } else {
1779                         _set_bank (sur->bank, addr);
1780                 }
1781                 if (sur->no_clear) {
1782                         // This surface uses /strip/list tell it routes have changed
1783                         lo_message reply;
1784                         reply = lo_message_new ();
1785                         lo_send_message (addr, "/strip/list", reply);
1786                         lo_message_free (reply);
1787                 }
1788         }
1789 }
1790
1791 /*
1792  * This gets called not only when bank changes but also:
1793  *  - bank size change
1794  *  - feedback change
1795  *  - strip types changes
1796  *  - fadermode changes
1797  *  - stripable creation/deletion/flag
1798  *  - to refresh what is "displayed"
1799  * Basically any time the bank needs to be rebuilt
1800  */
1801 int
1802 OSC::set_bank (uint32_t bank_start, lo_message msg)
1803 {
1804         return _set_bank (bank_start, get_address (msg));
1805 }
1806
1807 // set bank is callable with either message or address
1808 int
1809 OSC::_set_bank (uint32_t bank_start, lo_address addr)
1810 {
1811         if (!session) {
1812                 return -1;
1813         }
1814         // no nstripables yet
1815         if (!session->nroutes()) {
1816                 return -1;
1817         }
1818
1819         OSCSurface *s = get_surface (addr);
1820
1821         // revert any expand to select
1822          s->expand = 0;
1823          s->expand_enable = false;
1824         _strip_select (ControlProtocol::first_selected_stripable(), addr);
1825
1826         // undo all listeners for this url
1827         StripableList stripables;
1828         session->get_stripables (stripables);
1829         for (StripableList::iterator it = stripables.begin(); it != stripables.end(); ++it) {
1830
1831                 boost::shared_ptr<Stripable> stp = *it;
1832                 if (stp) {
1833                         end_listen (stp, addr);
1834                 }
1835                 // slow devices need time to clear buffers
1836                 usleep ((uint32_t) 10);
1837         }
1838
1839         s->strips = get_sorted_stripables(s->strip_types, s->cue);
1840         s->nstrips = s->strips.size();
1841
1842         uint32_t b_size;
1843         if (!s->bank_size) {
1844                 // no banking - bank includes all stripables
1845                 b_size = s->nstrips;
1846         } else {
1847                 b_size = s->bank_size;
1848         }
1849
1850         // Do limits checking
1851         if (bank_start < 1) bank_start = 1;
1852         if (b_size >= s->nstrips)  {
1853                 bank_start = 1;
1854         } else if (bank_start > ((s->nstrips - b_size) + 1)) {
1855                 // top bank is always filled if there are enough strips for at least one bank
1856                 bank_start = (uint32_t)((s->nstrips - b_size) + 1);
1857         }
1858         //save bank after bank limit checks
1859         s->bank = bank_start;
1860
1861         if (s->feedback[0] || s->feedback[1]) {
1862
1863                 for (uint32_t n = bank_start; n < (min ((b_size + bank_start), s->nstrips + 1)); ++n) {
1864                         if (n <= s->strips.size()) {
1865                                 boost::shared_ptr<Stripable> stp = s->strips[n - 1];
1866
1867                                 if (stp) {
1868                                         listen_to_route(stp, addr);
1869                                 }
1870                         }
1871                         // slow devices need time to clear buffers
1872                         usleep ((uint32_t) 20);
1873                 }
1874         }
1875         // light bankup or bankdown buttons if it is possible to bank in that direction
1876         if (s->feedback[4] && !s->no_clear) {
1877                 lo_message reply;
1878                 reply = lo_message_new ();
1879                 if ((s->bank > (s->nstrips - s->bank_size)) || (s->nstrips < s->bank_size)) {
1880                         lo_message_add_int32 (reply, 0);
1881                 } else {
1882                         lo_message_add_int32 (reply, 1);
1883                 }
1884                 lo_send_message (addr, "/bank_up", reply);
1885                 lo_message_free (reply);
1886                 reply = lo_message_new ();
1887                 if (s->bank > 1) {
1888                         lo_message_add_int32 (reply, 1);
1889                 } else {
1890                         lo_message_add_int32 (reply, 0);
1891                 }
1892                 lo_send_message (addr, "/bank_down", reply);
1893                 lo_message_free (reply);
1894         }
1895         bank_dirty = false;
1896         tick = true;
1897         return 0;
1898 }
1899
1900 int
1901 OSC::bank_up (lo_message msg)
1902 {
1903         if (!session) {
1904                 return -1;
1905         }
1906         OSCSurface *s = get_surface(get_address (msg));
1907         set_bank (s->bank + s->bank_size, msg);
1908         return 0;
1909 }
1910
1911 int
1912 OSC::bank_down (lo_message msg)
1913 {
1914         if (!session) {
1915                 return -1;
1916         }
1917         OSCSurface *s = get_surface(get_address (msg));
1918         if (s->bank < s->bank_size) {
1919                 set_bank (1, msg);
1920         } else {
1921                 set_bank (s->bank - s->bank_size, msg);
1922         }
1923         return 0;
1924 }
1925
1926 uint32_t
1927 OSC::get_sid (boost::shared_ptr<ARDOUR::Stripable> strip, lo_address addr)
1928 {
1929         if (!strip) {
1930                 return 0;
1931         }
1932
1933         OSCSurface *s = get_surface(addr);
1934
1935         uint32_t b_size;
1936         if (!s->bank_size) {
1937                 // no banking
1938                 b_size = s->nstrips;
1939         } else {
1940                 b_size = s->bank_size;
1941         }
1942
1943         for (uint32_t n = s->bank; n < (min ((b_size + s->bank), s->nstrips + 1)); ++n) {
1944                 if (n <= s->strips.size()) {
1945                         if (strip == s->strips[n-1]) {
1946                                 return n - s->bank + 1;
1947                         }
1948                 }
1949         }
1950         // failsafe... should never get here.
1951         return 0;
1952 }
1953
1954 boost::shared_ptr<ARDOUR::Stripable>
1955 OSC::get_strip (uint32_t ssid, lo_address addr)
1956 {
1957         OSCSurface *s = get_surface(addr);
1958         if (ssid && ((ssid + s->bank - 2) < s->nstrips)) {
1959                 return s->strips[ssid + s->bank - 2];
1960         }
1961         // guess it is out of range
1962         return boost::shared_ptr<ARDOUR::Stripable>();
1963 }
1964
1965 // send and plugin paging commands
1966 int
1967 OSC::sel_send_pagesize (uint32_t size, lo_message msg)
1968 {
1969         OSCSurface *s = get_surface(get_address (msg));
1970         if  (size != s->send_page_size) {
1971                 s->send_page_size = size;
1972                 s->sel_obs->renew_sends();
1973         }
1974         return 0;
1975 }
1976
1977 int
1978 OSC::sel_send_page (int page, lo_message msg)
1979 {
1980         OSCSurface *s = get_surface(get_address (msg));
1981         s->send_page = s->send_page + page;
1982         s->sel_obs->renew_sends();
1983         return 0;
1984 }
1985
1986 int
1987 OSC::sel_plug_pagesize (uint32_t size, lo_message msg)
1988 {
1989         OSCSurface *s = get_surface(get_address (msg));
1990         if (size != s->plug_page_size) {
1991                 s->plug_page_size = size;
1992                 s->sel_obs->renew_plugin();
1993         }
1994         return 0;
1995 }
1996
1997 int
1998 OSC::sel_plug_page (int page, lo_message msg)
1999 {
2000         OSCSurface *s = get_surface(get_address (msg));
2001         s->plug_page = s->plug_page + page;
2002         s->sel_obs->renew_plugin();
2003         return 0;
2004 }
2005
2006 int
2007 OSC::sel_plugin (int delta, lo_message msg)
2008 {
2009         OSCSurface *sur = get_surface(get_address (msg));
2010         return _sel_plugin (sur->plugin_id + delta, get_address (msg));
2011 }
2012
2013 int
2014 OSC::_sel_plugin (int id, lo_address addr)
2015 {
2016         OSCSurface *sur = get_surface(addr);
2017         boost::shared_ptr<Stripable> s;
2018         if (sur->expand_enable) {
2019                 s = get_strip (sur->expand, addr);
2020         } else {
2021                 s = _select;
2022         }
2023         if (s) {
2024                 boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(s);
2025                 if (!r) {
2026                         return 1;
2027                 }
2028
2029                 // find out how many plugins we have
2030                 bool plugs;
2031                 int nplugs  = 0;
2032                 sur->plugins.clear();
2033                 do {
2034                         plugs = false;
2035                         if (r->nth_plugin (nplugs)) {
2036                                 if (r->nth_plugin(nplugs)->display_to_user()) {
2037 #ifdef MIXBUS
2038                                         // need to check for mixbus channel strips (and exclude them)
2039                                         boost::shared_ptr<Processor> proc = r->nth_plugin (nplugs);
2040                                         boost::shared_ptr<PluginInsert> pi;
2041                                         if ((pi = boost::dynamic_pointer_cast<PluginInsert>(proc))) {
2042
2043                                                 if (!pi->is_channelstrip()) {
2044 #endif
2045                                                         sur->plugins.push_back (nplugs);
2046 #ifdef MIXBUS
2047                                                 }
2048                                         }
2049 #endif
2050                                 }
2051                                 plugs = true;
2052                                 nplugs++;
2053                         }
2054                 } while (plugs);
2055
2056                 // limit plugin_id to actual plugins
2057                 if (!sur->plugins.size()) {
2058                         sur->plugin_id = 0;
2059                         return 0;
2060                 } else if (sur->plugins.size() < (uint32_t) id) {
2061                         sur->plugin_id = sur->plugins.size();
2062                 } else  if (sur->plugins.size() && !id) {
2063                         sur->plugin_id = 1;
2064                 } else {
2065                         sur->plugin_id = id;
2066                 }
2067
2068                 // we have a plugin number now get the processor
2069                 boost::shared_ptr<Processor> proc = r->nth_plugin (sur->plugins[sur->plugin_id - 1]);
2070                 boost::shared_ptr<PluginInsert> pi;
2071                 if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(proc))) {
2072                         PBD::warning << "OSC: Plugin: " << sur->plugin_id << " does not seem to be a plugin" << endmsg;                 
2073                         return 1;
2074                 }
2075                 boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
2076                 bool ok = false;
2077                 // put only input controls into a vector
2078                 sur->plug_params.clear ();
2079                 uint32_t nplug_params  = pip->parameter_count();
2080                 for ( uint32_t ppi = 0;  ppi < nplug_params; ++ppi) {
2081                         uint32_t controlid = pip->nth_parameter(ppi, ok);
2082                         if (!ok) {
2083                                 continue;
2084                         }
2085                         if (pip->parameter_is_input(controlid)) {
2086                                 sur->plug_params.push_back (ppi);
2087                         }
2088                 }
2089
2090                 sur->plug_page = 1;
2091
2092                 if (sur->sel_obs) {
2093                         sur->sel_obs->renew_plugin();
2094                 }
2095                 return 0;
2096         }
2097         return 1;
2098 }
2099
2100 void
2101 OSC::transport_frame (lo_message msg)
2102 {
2103         if (!session) {
2104                 return;
2105         }
2106         check_surface (msg);
2107         framepos_t pos = session->transport_frame ();
2108
2109         lo_message reply = lo_message_new ();
2110         lo_message_add_int64 (reply, pos);
2111
2112         lo_send_message (get_address (msg), "/transport_frame", reply);
2113
2114         lo_message_free (reply);
2115 }
2116
2117 void
2118 OSC::transport_speed (lo_message msg)
2119 {
2120         if (!session) {
2121                 return;
2122         }
2123         check_surface (msg);
2124         double ts = session->transport_speed ();
2125
2126         lo_message reply = lo_message_new ();
2127         lo_message_add_double (reply, ts);
2128
2129         lo_send_message (get_address (msg), "/transport_speed", reply);
2130
2131         lo_message_free (reply);
2132 }
2133
2134 void
2135 OSC::record_enabled (lo_message msg)
2136 {
2137         if (!session) {
2138                 return;
2139         }
2140         check_surface (msg);
2141         int re = (int)session->get_record_enabled ();
2142
2143         lo_message reply = lo_message_new ();
2144         lo_message_add_int32 (reply, re);
2145
2146         lo_send_message (get_address (msg), "/record_enabled", reply);
2147
2148         lo_message_free (reply);
2149 }
2150
2151 int
2152 OSC::scrub (float delta, lo_message msg)
2153 {
2154         if (!session) return -1;
2155         check_surface (msg);
2156
2157         scrub_place = session->transport_frame ();
2158
2159         float speed;
2160
2161         int64_t now = ARDOUR::get_microseconds ();
2162         int64_t diff = now - scrub_time;
2163         if (diff > 35000) {
2164                 // speed 1 (or 0 if jog wheel supports touch)
2165                 speed = delta;
2166         } else if ((diff > 20000) && (fabs(scrub_speed) == 1)) {
2167                 // add some hysteresis to stop excess speed jumps
2168                 speed = delta;
2169         } else {
2170                 speed = (int)(delta * 2);
2171         }
2172         scrub_time = now;
2173         if (scrub_speed == speed) {
2174                 // Already at that speed no change
2175                 return 0;
2176         }
2177         scrub_speed = speed;
2178
2179         if (speed > 0) {
2180                 if (speed == 1) {
2181                         session->request_transport_speed (.5);
2182                 } else {
2183                         session->request_transport_speed (1);
2184                 }
2185         } else if (speed < 0) {
2186                 if (speed == -1) {
2187                         session->request_transport_speed (-.5);
2188                 } else {
2189                         session->request_transport_speed (-1);
2190                 }
2191         } else {
2192                 session->request_transport_speed (0);
2193         }
2194
2195         return 0;
2196 }
2197
2198 int
2199 OSC::jog (float delta, lo_message msg)
2200 {
2201         if (!session) return -1;
2202
2203         OSCSurface *s = get_surface(get_address (msg));
2204
2205         string path = "/jog/mode/name";
2206         switch(s->jogmode)
2207         {
2208                 case JOG  :
2209                         text_message (path, "Jog", get_address (msg));
2210                         if (delta) {
2211                                 jump_by_seconds (delta / 5);
2212                         }
2213                         break;
2214                 case SCRUB:
2215                         text_message (path, "Scrub", get_address (msg));
2216                         scrub (delta, msg);
2217                         break;
2218                 case SHUTTLE:
2219                         text_message (path, "Shuttle", get_address (msg));
2220                         if (delta) {
2221                                 double speed = get_transport_speed ();
2222                                 set_transport_speed (speed + (delta / 8));
2223                         } else {
2224                                 set_transport_speed (0);
2225                         }
2226                         break;
2227                 case SCROLL:
2228                         text_message (path, "Scroll", get_address (msg));
2229                         if (delta > 0) {
2230                                 access_action ("Editor/scroll-forward");
2231                         } else if (delta < 0) {
2232                                 access_action ("Editor/scroll-backward");
2233                         }
2234                         break;
2235                 case TRACK:
2236                         text_message (path, "Track", get_address (msg));
2237                         if (delta > 0) {
2238                                 set_bank (s->bank + 1, msg);
2239                         } else if (delta < 0) {
2240                                 set_bank (s->bank - 1, msg);
2241                         }
2242                         break;
2243                 case BANK:
2244                         text_message (path, "Bank", get_address (msg));
2245                         if (delta > 0) {
2246                                 bank_up (msg);
2247                         } else if (delta < 0) {
2248                                 bank_down (msg);
2249                         }
2250                         break;
2251                 case NUDGE:
2252                         text_message (path, "Nudge", get_address (msg));
2253                         if (delta > 0) {
2254                                 access_action ("Common/nudge-playhead-forward");
2255                         } else if (delta < 0) {
2256                                 access_action ("Common/nudge-playhead-backward");
2257                         }
2258                         break;
2259                 case MARKER:
2260                         text_message (path, "Marker", get_address (msg));
2261                         if (delta > 0) {
2262                                 next_marker ();
2263                         } else if (delta < 0) {
2264                                 prev_marker ();
2265                         }
2266                         break;
2267                 default:
2268                         break;
2269
2270         }
2271         return 0;
2272
2273 }
2274
2275 int
2276 OSC::jog_mode (float mode, lo_message msg)
2277 {
2278         if (!session) return -1;
2279
2280         OSCSurface *s = get_surface(get_address (msg));
2281
2282         switch((uint32_t)mode)
2283         {
2284                 case JOG  :
2285                         s->jogmode = JOG;
2286                         break;
2287                 case SCRUB:
2288                         s->jogmode = SCRUB;
2289                         break;
2290                 case SHUTTLE:
2291                         s->jogmode = SHUTTLE;
2292                         break;
2293                 case SCROLL:
2294                         s->jogmode = SCROLL;
2295                         break;
2296                 case TRACK:
2297                         s->jogmode = TRACK;
2298                         break;
2299                 case BANK:
2300                         s->jogmode = BANK;
2301                         break;
2302                 case NUDGE:
2303                         s->jogmode = NUDGE;
2304                         break;
2305                 case MARKER:
2306                         s->jogmode = MARKER;
2307                         break;
2308                 default:
2309                         PBD::warning << "Jog Mode: " << mode << " is not valid." << endmsg;
2310                         break;
2311         lo_message reply = lo_message_new ();
2312         lo_message_add_int32 (reply, s->jogmode);
2313         lo_send_message (get_address(msg), "/jog/mode", reply);
2314         lo_message_free (reply);
2315
2316         }
2317         jog (0, msg);
2318         return 0;
2319
2320 }
2321
2322 // master and monitor calls
2323 int
2324 OSC::master_set_gain (float dB)
2325 {
2326         if (!session) return -1;
2327         boost::shared_ptr<Stripable> s = session->master_out();
2328         if (s) {
2329                 if (dB < -192) {
2330                         s->gain_control()->set_value (0.0, PBD::Controllable::NoGroup);
2331                 } else {
2332                         s->gain_control()->set_value (dB_to_coefficient (dB), PBD::Controllable::NoGroup);
2333                 }
2334         }
2335         return 0;
2336 }
2337
2338 int
2339 OSC::master_set_fader (float position)
2340 {
2341         if (!session) return -1;
2342         boost::shared_ptr<Stripable> s = session->master_out();
2343         if (s) {
2344                 s->gain_control()->set_value (s->gain_control()->interface_to_internal (position), PBD::Controllable::NoGroup);
2345         }
2346         return 0;
2347 }
2348
2349 int
2350 OSC::master_set_trim (float dB)
2351 {
2352         if (!session) return -1;
2353         boost::shared_ptr<Stripable> s = session->master_out();
2354
2355         if (s) {
2356                 s->trim_control()->set_value (dB_to_coefficient (dB), PBD::Controllable::NoGroup);
2357         }
2358
2359         return 0;
2360 }
2361
2362 int
2363 OSC::master_set_pan_stereo_position (float position, lo_message msg)
2364 {
2365         if (!session) return -1;
2366         OSCSurface *sur = get_surface(get_address (msg));
2367
2368         float endposition = .5;
2369         boost::shared_ptr<Stripable> s = session->master_out();
2370
2371         if (s) {
2372                 if (s->pan_azimuth_control()) {
2373                         s->pan_azimuth_control()->set_value (s->pan_azimuth_control()->interface_to_internal (position), PBD::Controllable::NoGroup);
2374                         endposition = s->pan_azimuth_control()->internal_to_interface (s->pan_azimuth_control()->get_value ());
2375                 }
2376         }
2377
2378         if (sur->feedback[4]) {
2379                 lo_message reply = lo_message_new ();
2380                 lo_message_add_float (reply, endposition);
2381
2382                 lo_send_message (get_address (msg), "/master/pan_stereo_position", reply);
2383                 lo_message_free (reply);
2384         }
2385
2386         return 0;
2387 }
2388
2389 int
2390 OSC::master_set_mute (uint32_t state)
2391 {
2392         if (!session) return -1;
2393
2394         boost::shared_ptr<Stripable> s = session->master_out();
2395
2396         if (s) {
2397                 s->mute_control()->set_value (state, PBD::Controllable::NoGroup);
2398         }
2399
2400         return 0;
2401 }
2402
2403 int
2404 OSC::monitor_set_gain (float dB)
2405 {
2406         if (!session) return -1;
2407         boost::shared_ptr<Stripable> s = session->monitor_out();
2408
2409         if (s) {
2410                 if (dB < -192) {
2411                         s->gain_control()->set_value (0.0, PBD::Controllable::NoGroup);
2412                 } else {
2413                         s->gain_control()->set_value (dB_to_coefficient (dB), PBD::Controllable::NoGroup);
2414                 }
2415         }
2416         return 0;
2417 }
2418
2419 int
2420 OSC::monitor_set_fader (float position)
2421 {
2422         if (!session) return -1;
2423         boost::shared_ptr<Stripable> s = session->monitor_out();
2424         if (s) {
2425                 s->gain_control()->set_value (s->gain_control()->interface_to_internal (position), PBD::Controllable::NoGroup);
2426         }
2427         return 0;
2428 }
2429
2430 int
2431 OSC::monitor_set_mute (uint32_t state)
2432 {
2433         if (!session) return -1;
2434
2435         if (session->monitor_out()) {
2436                 boost::shared_ptr<MonitorProcessor> mon = session->monitor_out()->monitor_control();
2437                 mon->set_cut_all (state);
2438         }
2439         return 0;
2440 }
2441
2442 int
2443 OSC::monitor_set_dim (uint32_t state)
2444 {
2445         if (!session) return -1;
2446
2447         if (session->monitor_out()) {
2448                 boost::shared_ptr<MonitorProcessor> mon = session->monitor_out()->monitor_control();
2449                 mon->set_dim_all (state);
2450         }
2451         return 0;
2452 }
2453
2454 int
2455 OSC::monitor_set_mono (uint32_t state)
2456 {
2457         if (!session) return -1;
2458
2459         if (session->monitor_out()) {
2460                 boost::shared_ptr<MonitorProcessor> mon = session->monitor_out()->monitor_control();
2461                 mon->set_mono (state);
2462         }
2463         return 0;
2464 }
2465
2466 int
2467 OSC::route_get_sends(lo_message msg) {
2468         if (!session) {
2469                 return -1;
2470         }
2471
2472         lo_arg **argv = lo_message_get_argv(msg);
2473
2474         int rid = argv[0]->i;
2475
2476         boost::shared_ptr<Stripable> strip = get_strip(rid, get_address(msg));
2477         if (!strip) {
2478                 return -1;
2479         }
2480
2481         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (strip);
2482         if (!r) {
2483                 return -1;
2484         }
2485
2486         lo_message reply = lo_message_new();
2487         lo_message_add_int32(reply, rid);
2488
2489         int i = 0;
2490         for (;;) {
2491                 boost::shared_ptr<Processor> p = r->nth_send(i++);
2492
2493                 if (!p) {
2494                         break;
2495                 }
2496
2497                 boost::shared_ptr<InternalSend> isend = boost::dynamic_pointer_cast<InternalSend> (p);
2498                 if (isend) {
2499                         lo_message_add_int32(reply, get_sid(isend->target_route(), get_address(msg)));
2500                         lo_message_add_string(reply, isend->name().c_str());
2501                         lo_message_add_int32(reply, i);
2502                         boost::shared_ptr<Amp> a = isend->amp();
2503                         lo_message_add_float(reply, a->gain_control()->internal_to_interface (a->gain_control()->get_value()));
2504                         lo_message_add_int32(reply, p->active() ? 1 : 0);
2505                 }
2506         }
2507         // if used dedicated message path to identify this reply in async operation.
2508         // Naming it #reply wont help the client to identify the content.
2509         lo_send_message(get_address (msg), "/strip/sends", reply);
2510
2511         lo_message_free(reply);
2512
2513         return 0;
2514 }
2515
2516 int
2517 OSC::route_get_receives(lo_message msg) {
2518         if (!session) {
2519                 return -1;
2520         }
2521
2522         lo_arg **argv = lo_message_get_argv(msg);
2523
2524         uint32_t rid = argv[0]->i;
2525
2526
2527         boost::shared_ptr<Stripable> strip = get_strip(rid, get_address(msg));
2528         if (!strip) {
2529                 return -1;
2530         }
2531
2532         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (strip);
2533         if (!r) {
2534                 return -1;
2535         }
2536
2537         boost::shared_ptr<RouteList> route_list = session->get_routes();
2538
2539         lo_message reply = lo_message_new();
2540
2541         for (RouteList::iterator i = route_list->begin(); i != route_list->end(); ++i) {
2542                 boost::shared_ptr<Route> tr = boost::dynamic_pointer_cast<Route> (*i);
2543                 if (!tr) {
2544                         continue;
2545                 }
2546                 int j = 0;
2547
2548                 for (;;) {
2549                         boost::shared_ptr<Processor> p = tr->nth_send(j++);
2550
2551                         if (!p) {
2552                                 break;
2553                         }
2554
2555                         boost::shared_ptr<InternalSend> isend = boost::dynamic_pointer_cast<InternalSend> (p);
2556                         if (isend) {
2557                                 if( isend->target_route()->id() == r->id()){
2558                                         boost::shared_ptr<Amp> a = isend->amp();
2559
2560                                         lo_message_add_int32(reply, get_sid(tr, get_address(msg)));
2561                                         lo_message_add_string(reply, tr->name().c_str());
2562                                         lo_message_add_int32(reply, j);
2563                                         lo_message_add_float(reply, a->gain_control()->internal_to_interface (a->gain_control()->get_value()));
2564                                         lo_message_add_int32(reply, p->active() ? 1 : 0);
2565                                 }
2566                         }
2567                 }
2568         }
2569
2570         // I have used a dedicated message path to identify this reply in async operation.
2571         // Naming it #reply wont help the client to identify the content.
2572         lo_send_message(get_address (msg), "/strip/receives", reply);
2573         lo_message_free(reply);
2574         return 0;
2575 }
2576
2577 // strip calls
2578
2579 int
2580 OSC::set_automation (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg)
2581 {
2582         if (!session) return -1;
2583
2584         int ret = 1;
2585         OSCSurface *sur = get_surface(get_address (msg));
2586         boost::shared_ptr<Stripable> strp = boost::shared_ptr<Stripable>();
2587         uint32_t ctr = 0;
2588         uint32_t aut = 0;
2589         uint32_t ssid;
2590
2591         if (argc) {
2592                 if (argv[argc - 1]->f) {
2593                         aut = (int)argv[argc - 1]->f;
2594                 } else {
2595                         aut = argv[argc - 1]->i;
2596                 }
2597         }
2598
2599         //parse path first to find stripable
2600         if (!strncmp (path, "/strip/", 7)) {
2601                 // find ssid and stripable
2602                 if (argc > 1) {
2603                         if (types[1] == 'f') {
2604                                 ssid = (uint32_t)argv[0]->f;
2605                         } else {
2606                                 ssid = argv[0]->i;
2607                         }
2608                         strp = get_strip (ssid, get_address (msg));
2609                 } else {
2610                         ssid = atoi (&(strrchr (path, '/' ))[1]);
2611                         strp = get_strip (ssid, get_address (msg));
2612                 }
2613                 ctr = 7;
2614         } else if (!strncmp (path, "/select/", 8)) {
2615                 if (sur->expand_enable && sur->expand) {
2616                         strp = get_strip (sur->expand, get_address (msg));
2617                 } else {
2618                         strp = ControlProtocol::first_selected_stripable();
2619                 }
2620                 ctr = 8;
2621         } else {
2622                 return ret;
2623         }
2624         if (strp) {
2625                 boost::shared_ptr<AutomationControl> control = boost::shared_ptr<AutomationControl>();
2626                 // other automatable controls can be added by repeating the next 6.5 lines
2627                 if ((!strncmp (&path[ctr], "fader", 5)) || (!strncmp (&path[ctr], "gain", 4))) {
2628                         if (strp->gain_control ()) {
2629                                 control = strp->gain_control ();
2630                         } else {
2631                                 PBD::warning << "No fader for this strip" << endmsg;
2632                         }
2633                 } else {
2634                         PBD::warning << "Automation not available for " << path << endmsg;
2635                 }
2636
2637                 if (control) {
2638
2639                         switch (aut) {
2640                                 case 0:
2641                                         control->set_automation_state (ARDOUR::Off);
2642                                         ret = 0;
2643                                         break;
2644                                 case 1:
2645                                         control->set_automation_state (ARDOUR::Play);
2646                                         ret = 0;
2647                                         break;
2648                                 case 2:
2649                                         control->set_automation_state (ARDOUR::Write);
2650                                         ret = 0;
2651                                         break;
2652                                 case 3:
2653                                         control->set_automation_state (ARDOUR::Touch);
2654                                         ret = 0;
2655                                         break;
2656                                 default:
2657                                         break;
2658                         }
2659                 }
2660         }
2661
2662         return ret;
2663 }
2664
2665 int
2666 OSC::touch_detect (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg)
2667 {
2668         if (!session) return -1;
2669
2670         int ret = 1;
2671         OSCSurface *sur = get_surface(get_address (msg));
2672         boost::shared_ptr<Stripable> strp = boost::shared_ptr<Stripable>();
2673         uint32_t ctr = 0;
2674         uint32_t touch = 0;
2675         uint32_t ssid;
2676
2677         if (argc) {
2678                 if (argv[argc - 1]->f) {
2679                         touch = (int)argv[argc - 1]->f;
2680                 } else {
2681                         touch = argv[argc - 1]->i;
2682                 }
2683         }
2684
2685         //parse path first to find stripable
2686         if (!strncmp (path, "/strip/", 7)) {
2687                 // find ssid and stripable
2688                 if (argc > 1) {
2689                         if (types[0] == 'f') {
2690                                 ssid = (uint32_t)argv[0]->f;
2691                         } else {
2692                                 ssid = argv[0]->i;
2693                         }
2694                         strp = get_strip (ssid, get_address (msg));
2695                 } else {
2696                         ssid = atoi (&(strrchr (path, '/' ))[1]);
2697                         strp = get_strip (ssid, get_address (msg));
2698                 }
2699                 ctr = 7;
2700         } else if (!strncmp (path, "/select/", 8)) {
2701                 if (sur->expand_enable && sur->expand) {
2702                         strp = get_strip (sur->expand, get_address (msg));
2703                 } else {
2704                         strp = ControlProtocol::first_selected_stripable();
2705                 }
2706                 ctr = 8;
2707         } else {
2708                 return ret;
2709         }
2710         if (strp) {
2711                 boost::shared_ptr<AutomationControl> control = boost::shared_ptr<AutomationControl>();
2712                 // other automatable controls can be added by repeating the next 6.5 lines
2713                 if ((!strncmp (&path[ctr], "fader", 5)) || (!strncmp (&path[ctr], "gain", 4))) {
2714                         if (strp->gain_control ()) {
2715                                 control = strp->gain_control ();
2716                         } else {
2717                                 PBD::warning << "No fader for this strip" << endmsg;
2718                         }
2719                 } else {
2720                         PBD::warning << "Automation not available for " << path << endmsg;
2721                 }
2722
2723                 if (control) {
2724                         if (touch) {
2725                                 //start touch
2726                                 if (control->automation_state() == Touch && !control->touching ()) {
2727                                         control->start_touch (control->session().transport_frame());
2728                                 }
2729                                 ret = 0;
2730                         } else {
2731                                 // end touch
2732                                 control->stop_touch (true, control->session().transport_frame());
2733                                 ret = 0;
2734                         }
2735                         // just in case some crazy surface starts sending control values before touch
2736                         FakeTouchMap::iterator x = _touch_timeout.find(control);
2737                         if (x != _touch_timeout.end()) {
2738                                 _touch_timeout.erase (x);
2739                         }
2740                 }
2741         }
2742
2743         return ret;
2744 }
2745
2746 int
2747 OSC::fake_touch (boost::shared_ptr<ARDOUR::AutomationControl> ctrl)
2748 {
2749         if (ctrl) {
2750                 //start touch
2751                 if (ctrl->automation_state() == Touch && !ctrl->touching ()) {
2752                 ctrl->start_touch (ctrl->session().transport_frame());
2753                 _touch_timeout[ctrl] = 10;
2754                 }
2755         }
2756
2757         return 0;
2758 }
2759
2760 int
2761 OSC::route_mute (int ssid, int yn, lo_message msg)
2762 {
2763         if (!session) return -1;
2764         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
2765
2766         if (s) {
2767                 if (s->mute_control()) {
2768                         s->mute_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2769                         return 0;
2770                 }
2771         }
2772
2773         return route_send_fail ("mute", ssid, 0, get_address (msg));
2774 }
2775
2776 int
2777 OSC::sel_mute (uint32_t yn, lo_message msg)
2778 {
2779         OSCSurface *sur = get_surface(get_address (msg));
2780         boost::shared_ptr<Stripable> s;
2781         if (sur->expand_enable) {
2782                 s = get_strip (sur->expand, get_address (msg));
2783         } else {
2784                 s = _select;
2785         }
2786         if (s) {
2787                 if (s->mute_control()) {
2788                         s->mute_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2789                         return 0;
2790                 }
2791         }
2792         return sel_fail ("mute", 0, get_address (msg));
2793 }
2794
2795 int
2796 OSC::route_solo (int ssid, int yn, lo_message msg)
2797 {
2798         if (!session) return -1;
2799         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
2800
2801         if (s) {
2802                 if (s->solo_control()) {
2803                         s->solo_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2804                 }
2805         }
2806
2807         return route_send_fail ("solo", ssid, 0, get_address (msg));
2808 }
2809
2810 int
2811 OSC::route_solo_iso (int ssid, int yn, lo_message msg)
2812 {
2813         if (!session) return -1;
2814         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
2815
2816         if (s) {
2817                 if (s->solo_isolate_control()) {
2818                         s->solo_isolate_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2819                         return 0;
2820                 }
2821         }
2822
2823         return route_send_fail ("solo_iso", ssid, 0, get_address (msg));
2824 }
2825
2826 int
2827 OSC::route_solo_safe (int ssid, int yn, lo_message msg)
2828 {
2829         if (!session) return -1;
2830         boost::shared_ptr<Stripable> s = get_strip (ssid, lo_message_get_source (msg));
2831
2832         if (s) {
2833                 if (s->solo_safe_control()) {
2834                         s->solo_safe_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2835                         return 0;
2836                 }
2837         }
2838
2839         return route_send_fail ("solo_safe", ssid, 0, get_address (msg));
2840 }
2841
2842 int
2843 OSC::sel_solo (uint32_t yn, lo_message msg)
2844 {
2845         OSCSurface *sur = get_surface(get_address (msg));
2846         boost::shared_ptr<Stripable> s;
2847         if (sur->expand_enable) {
2848                 s = get_strip (sur->expand, get_address (msg));
2849         } else {
2850                 s = _select;
2851         }
2852         if (s) {
2853                 if (s->solo_control()) {
2854                         session->set_control (s->solo_control(), yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2855                 }
2856         }
2857         return sel_fail ("solo", 0, get_address (msg));
2858 }
2859
2860 int
2861 OSC::sel_solo_iso (uint32_t yn, lo_message msg)
2862 {
2863         OSCSurface *sur = get_surface(get_address (msg));
2864         boost::shared_ptr<Stripable> s;
2865         if (sur->expand_enable) {
2866                 s = get_strip (sur->expand, get_address (msg));
2867         } else {
2868                 s = _select;
2869         }
2870         if (s) {
2871                 if (s->solo_isolate_control()) {
2872                         s->solo_isolate_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2873                         return 0;
2874                 }
2875         }
2876         return sel_fail ("solo_iso", 0, get_address (msg));
2877 }
2878
2879 int
2880 OSC::sel_solo_safe (uint32_t yn, lo_message msg)
2881 {
2882         OSCSurface *sur = get_surface(get_address (msg));
2883         boost::shared_ptr<Stripable> s;
2884         if (sur->expand_enable) {
2885                 s = get_strip (sur->expand, get_address (msg));
2886         } else {
2887                 s = _select;
2888         }
2889         if (s) {
2890                 if (s->solo_safe_control()) {
2891                         s->solo_safe_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2892                         return 0;
2893                 }
2894         }
2895         return sel_fail ("solo_safe", 0, get_address (msg));
2896 }
2897
2898 int
2899 OSC::sel_recenable (uint32_t yn, lo_message msg)
2900 {
2901         OSCSurface *sur = get_surface(get_address (msg));
2902         boost::shared_ptr<Stripable> s;
2903         if (sur->expand_enable) {
2904                 s = get_strip (sur->expand, get_address (msg));
2905         } else {
2906                 s = _select;
2907         }
2908         if (s) {
2909                 if (s->rec_enable_control()) {
2910                         s->rec_enable_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2911                         if (s->rec_enable_control()->get_value()) {
2912                                 return 0;
2913                         }
2914                 }
2915         }
2916         return sel_fail ("recenable", 0, get_address (msg));
2917 }
2918
2919 int
2920 OSC::route_recenable (int ssid, int yn, lo_message msg)
2921 {
2922         if (!session) return -1;
2923         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
2924
2925         if (s) {
2926                 if (s->rec_enable_control()) {
2927                         s->rec_enable_control()->set_value (yn, PBD::Controllable::UseGroup);
2928                         if (s->rec_enable_control()->get_value()) {
2929                                 return 0;
2930                         }
2931                 }
2932         }
2933         return route_send_fail ("recenable", ssid, 0, get_address (msg));
2934 }
2935
2936 int
2937 OSC::route_rename(int ssid, char *newname, lo_message msg) {
2938     if (!session) {
2939         return -1;
2940     }
2941
2942     boost::shared_ptr<Stripable> s = get_strip(ssid, get_address(msg));
2943
2944     if (s) {
2945         s->set_name(std::string(newname));
2946     }
2947
2948     return 0;
2949 }
2950
2951 int
2952 OSC::sel_recsafe (uint32_t yn, lo_message msg)
2953 {
2954         OSCSurface *sur = get_surface(get_address (msg));
2955         boost::shared_ptr<Stripable> s;
2956         if (sur->expand_enable) {
2957                 s = get_strip (sur->expand, get_address (msg));
2958         } else {
2959                 s = _select;
2960         }
2961         if (s) {
2962                 if (s->rec_safe_control()) {
2963                         s->rec_safe_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2964                         if (s->rec_safe_control()->get_value()) {
2965                                 return 0;
2966                         }
2967                 }
2968         }
2969         return sel_fail ("record_safe", 0, get_address (msg));
2970 }
2971
2972 int
2973 OSC::route_recsafe (int ssid, int yn, lo_message msg)
2974 {
2975         if (!session) return -1;
2976         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
2977         if (s) {
2978                 if (s->rec_safe_control()) {
2979                         s->rec_safe_control()->set_value (yn, PBD::Controllable::UseGroup);
2980                         if (s->rec_safe_control()->get_value()) {
2981                                 return 0;
2982                         }
2983                 }
2984         }
2985         return route_send_fail ("record_safe", ssid, 0,get_address (msg));
2986 }
2987
2988 int
2989 OSC::route_monitor_input (int ssid, int yn, lo_message msg)
2990 {
2991         if (!session) return -1;
2992         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
2993
2994         if (s) {
2995                 boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (s);
2996                 if (track) {
2997                         if (track->monitoring_control()) {
2998                                 track->monitoring_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2999                                 return 0;
3000                         }
3001                 }
3002         }
3003
3004         return route_send_fail ("monitor_input", ssid, 0, get_address (msg));
3005 }
3006
3007 int
3008 OSC::sel_monitor_input (uint32_t yn, lo_message msg)
3009 {
3010         OSCSurface *sur = get_surface(get_address (msg));
3011         boost::shared_ptr<Stripable> s;
3012         if (sur->expand_enable) {
3013                 s = get_strip (sur->expand, get_address (msg));
3014         } else {
3015                 s = _select;
3016         }
3017         if (s) {
3018                 boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (s);
3019                 if (track) {
3020                         if (track->monitoring_control()) {
3021                                 track->monitoring_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
3022                                 return 0;
3023                         }
3024                 }
3025         }
3026         return sel_fail ("monitor_input", 0, get_address (msg));
3027 }
3028
3029 int
3030 OSC::route_monitor_disk (int ssid, int yn, lo_message msg)
3031 {
3032         if (!session) return -1;
3033         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3034
3035         if (s) {
3036                 boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (s);
3037                 if (track) {
3038                         if (track->monitoring_control()) {
3039                                 track->monitoring_control()->set_value (yn ? 2.0 : 0.0, PBD::Controllable::NoGroup);
3040                                 return 0;
3041                         }
3042                 }
3043         }
3044
3045         return route_send_fail ("monitor_disk", ssid, 0, get_address (msg));
3046 }
3047
3048 int
3049 OSC::sel_monitor_disk (uint32_t yn, lo_message msg)
3050 {
3051         OSCSurface *sur = get_surface(get_address (msg));
3052         boost::shared_ptr<Stripable> s;
3053         if (sur->expand_enable) {
3054                 s = get_strip (sur->expand, get_address (msg));
3055         } else {
3056                 s = _select;
3057         }
3058         if (s) {
3059                 boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (s);
3060                 if (track) {
3061                         if (track->monitoring_control()) {
3062                                 track->monitoring_control()->set_value (yn ? 2.0 : 0.0, PBD::Controllable::NoGroup);
3063                                 return 0;
3064                         }
3065                 }
3066         }
3067         return sel_fail ("monitor_disk", 0, get_address (msg));
3068 }
3069
3070
3071 int
3072 OSC::strip_phase (int ssid, int yn, lo_message msg)
3073 {
3074         if (!session) return -1;
3075         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3076
3077         if (s) {
3078                 if (s->phase_control()) {
3079                         s->phase_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
3080                         return 0;
3081                 }
3082         }
3083
3084         return route_send_fail ("polarity", ssid, 0, get_address (msg));
3085 }
3086
3087 int
3088 OSC::sel_phase (uint32_t yn, lo_message msg)
3089 {
3090         OSCSurface *sur = get_surface(get_address (msg));
3091         boost::shared_ptr<Stripable> s;
3092         if (sur->expand_enable) {
3093                 s = get_strip (sur->expand, get_address (msg));
3094         } else {
3095                 s = _select;
3096         }
3097         if (s) {
3098                 if (s->phase_control()) {
3099                         s->phase_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
3100                         return 0;
3101                 }
3102         }
3103         return sel_fail ("polarity", 0, get_address (msg));
3104 }
3105
3106 int
3107 OSC::strip_expand (int ssid, int yn, lo_message msg)
3108 {
3109         OSCSurface *sur = get_surface(get_address (msg));
3110         sur->expand_enable = (bool) yn;
3111         sur->expand = ssid;
3112         boost::shared_ptr<Stripable> s;
3113         if (yn) {
3114                 s = get_strip (ssid, get_address (msg));
3115         } else {
3116                 s = ControlProtocol::first_selected_stripable();
3117         }
3118
3119         return _strip_select (s, get_address (msg));
3120 }
3121
3122 int
3123 OSC::_strip_select (boost::shared_ptr<Stripable> s, lo_address addr)
3124 {
3125         if (!session) {
3126                 return -1;
3127         }
3128         OSCSurface *sur = get_surface(addr);
3129         if (sur->sel_obs) {
3130                 delete sur->sel_obs;
3131                 sur->sel_obs = 0;
3132         }
3133         bool feedback_on = sur->feedback.to_ulong();
3134         if (s && feedback_on) {
3135                 OSCSelectObserver* sel_fb = new OSCSelectObserver (s, addr, sur);
3136                 s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this);
3137                 sur->sel_obs = sel_fb;
3138         } else if (sur->expand_enable) {
3139                 // expand doesn't point to a stripable, turn it off and use select
3140                 sur->expand = 0;
3141                 sur->expand_enable = false;
3142                 if (_select && feedback_on) {
3143                         s = _select;
3144                         OSCSelectObserver* sel_fb = new OSCSelectObserver (s, addr, sur);
3145                         s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this);
3146                         sur->sel_obs = sel_fb;
3147                 }
3148         } else if (feedback_on) {
3149                 route_send_fail ("select", sur->expand, 0 , addr);
3150         }
3151         // need to set monitor for processor changed signal
3152         // detecting processor changes requires cast to route
3153         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(s);
3154         if (r) {
3155                 r->processors_changed.connect  (sur->proc_connection, MISSING_INVALIDATOR, boost::bind (&OSC::processor_changed, this, addr), this);
3156                 processor_changed (addr);
3157         }
3158
3159         if (!feedback_on) {
3160                 return 0;
3161         }
3162         //update buttons on surface
3163         int b_s = sur->bank_size;
3164         if (!b_s) { // bank size 0 means we need to know how many strips there are.
3165                 b_s = sur->nstrips;
3166         }
3167         for (int i = 1;  i <= b_s; i++) {
3168                 string path = "expand";
3169
3170                 if ((i == (int) sur->expand) && sur->expand_enable) {
3171                         lo_message reply = lo_message_new ();
3172                         if (sur->feedback[2]) {
3173                                 ostringstream os;
3174                                 os << "/strip/" << path << "/" << i;
3175                                 path = os.str();
3176                         } else {
3177                                 ostringstream os;
3178                                 os << "/strip/" << path;
3179                                 path = os.str();
3180                                 lo_message_add_int32 (reply, i);
3181                         }
3182                         lo_message_add_float (reply, (float) 1);
3183
3184                         lo_send_message (addr, path.c_str(), reply);
3185                         lo_message_free (reply);
3186                         reply = lo_message_new ();
3187                         lo_message_add_float (reply, 1.0);
3188                         lo_send_message (addr, "/select/expand", reply);
3189                         lo_message_free (reply);
3190
3191                 } else {
3192                         lo_message reply = lo_message_new ();
3193                         lo_message_add_int32 (reply, i);
3194                         lo_message_add_float (reply, 0.0);
3195                         lo_send_message (addr, "/strip/expand", reply);
3196                         lo_message_free (reply);
3197                 }
3198         }
3199         if (!sur->expand_enable) {
3200                 lo_message reply = lo_message_new ();
3201                 lo_message_add_float (reply, 0.0);
3202                 lo_send_message (addr, "/select/expand", reply);
3203                 lo_message_free (reply);
3204         }
3205
3206         return 0;
3207 }
3208
3209 void
3210 OSC::processor_changed (lo_address addr)
3211 {
3212         OSCSurface *sur = get_surface (addr);
3213         sur->proc_connection.disconnect ();
3214         _sel_plugin (sur->plugin_id, addr);
3215         if (sur->sel_obs) {
3216                 sur->sel_obs->renew_sends ();
3217                 sur->sel_obs->eq_restart (-1);
3218         }
3219 }
3220
3221 int
3222 OSC::strip_gui_select (int ssid, int yn, lo_message msg)
3223 {
3224         //ignore button release
3225         if (!yn) return 0;
3226
3227         if (!session) {
3228                 return -1;
3229         }
3230         OSCSurface *sur = get_surface(get_address (msg));
3231         sur->expand_enable = false;
3232         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3233         if (s) {
3234                 SetStripableSelection (s);
3235         } else {
3236                 if ((int) (sur->feedback.to_ulong())) {
3237                         route_send_fail ("select", ssid, 0, get_address (msg));
3238                 }
3239         }
3240
3241         return 0;
3242 }
3243
3244 int
3245 OSC::sel_expand (uint32_t state, lo_message msg)
3246 {
3247         OSCSurface *sur = get_surface(get_address (msg));
3248         boost::shared_ptr<Stripable> s;
3249         sur->expand_enable = (bool) state;
3250         if (state && sur->expand) {
3251                 s = get_strip (sur->expand, get_address (msg));
3252         } else {
3253                 s = ControlProtocol::first_selected_stripable();
3254         }
3255
3256         return _strip_select (s, get_address (msg));
3257 }
3258
3259 int
3260 OSC::route_set_gain_abs (int ssid, float level, lo_message msg)
3261 {
3262         if (!session) return -1;
3263         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3264
3265         if (s) {
3266                 if (s->gain_control()) {
3267                         fake_touch (s->gain_control());
3268                         s->gain_control()->set_value (level, PBD::Controllable::NoGroup);
3269                 } else {
3270                         return 1;
3271                 }
3272         } else {
3273                 return 1;
3274         }
3275
3276         return 0;
3277 }
3278
3279 int
3280 OSC::route_set_gain_dB (int ssid, float dB, lo_message msg)
3281 {
3282         if (!session) {
3283                 route_send_fail ("gain", ssid, -193, get_address (msg));
3284                 return -1;
3285         }
3286         int ret;
3287         if (dB < -192) {
3288                 ret = route_set_gain_abs (ssid, 0.0, msg);
3289         } else {
3290                 ret = route_set_gain_abs (ssid, dB_to_coefficient (dB), msg);
3291         }
3292         if (ret != 0) {
3293                 return route_send_fail ("gain", ssid, -193, get_address (msg));
3294         }
3295         return 0;
3296 }
3297
3298 int
3299 OSC::sel_gain (float val, lo_message msg)
3300 {
3301         OSCSurface *sur = get_surface(get_address (msg));
3302         boost::shared_ptr<Stripable> s;
3303         if (sur->expand_enable) {
3304                 s = get_strip (sur->expand, get_address (msg));
3305         } else {
3306                 s = _select;
3307         }
3308         if (s) {
3309                 float abs;
3310                 if (val < -192) {
3311                         abs = 0;
3312                 } else {
3313                         abs = dB_to_coefficient (val);
3314                 }
3315                 if (s->gain_control()) {
3316                         fake_touch (s->gain_control());
3317                         s->gain_control()->set_value (abs, PBD::Controllable::NoGroup);
3318                         return 0;
3319                 }
3320         }
3321         return sel_fail ("gain", -193, get_address (msg));
3322 }
3323
3324 int
3325 OSC::route_set_gain_fader (int ssid, float pos, lo_message msg)
3326 {
3327         if (!session) {
3328                 return -1;
3329         }
3330         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3331
3332         if (s) {
3333                 if (s->gain_control()) {
3334                         fake_touch (s->gain_control());
3335                         s->gain_control()->set_value (s->gain_control()->interface_to_internal (pos), PBD::Controllable::NoGroup);
3336                 } else {
3337                         return route_send_fail ("fader", ssid, 0, get_address (msg));
3338                 }
3339         } else {
3340                 return route_send_fail ("fader", ssid, 0, get_address (msg));
3341         }
3342         return 0;
3343 }
3344
3345 int
3346 OSC::strip_db_delta (int ssid, float delta, lo_message msg)
3347 {
3348         if (!session) return -1;
3349         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3350         if (s) {
3351                 float db = accurate_coefficient_to_dB (s->gain_control()->get_value()) + delta;
3352                 float abs;
3353                 if (db < -192) {
3354                         abs = 0;
3355                 } else {
3356                         abs = dB_to_coefficient (db);
3357                 }
3358                 s->gain_control()->set_value (abs, PBD::Controllable::NoGroup);
3359                 return 0;
3360         }
3361         return -1;
3362 }
3363
3364 int
3365 OSC::sel_fader (float val, lo_message msg)
3366 {
3367         OSCSurface *sur = get_surface(get_address (msg));
3368         boost::shared_ptr<Stripable> s;
3369         if (sur->expand_enable) {
3370                 s = get_strip (sur->expand, get_address (msg));
3371         } else {
3372                 s = _select;
3373         }
3374         if (s) {
3375                 if (s->gain_control()) {
3376                         fake_touch (s->gain_control());
3377                         s->gain_control()->set_value (s->gain_control()->interface_to_internal (val), PBD::Controllable::NoGroup);
3378                         return 0;
3379                 }
3380         }
3381         return sel_fail ("fader", 0, get_address (msg));
3382 }
3383
3384 int
3385 OSC::route_set_trim_abs (int ssid, float level, lo_message msg)
3386 {
3387         if (!session) return -1;
3388         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3389
3390         if (s) {
3391                 if (s->trim_control()) {
3392                         s->trim_control()->set_value (level, PBD::Controllable::NoGroup);
3393                         return 0;
3394                 }
3395
3396         }
3397
3398         return -1;
3399 }
3400
3401 int
3402 OSC::route_set_trim_dB (int ssid, float dB, lo_message msg)
3403 {
3404         int ret;
3405         ret = route_set_trim_abs(ssid, dB_to_coefficient (dB), msg);
3406         if (ret != 0) {
3407                 return route_send_fail ("trimdB", ssid, 0, get_address (msg));
3408         }
3409
3410 return 0;
3411 }
3412
3413 int
3414 OSC::sel_trim (float val, lo_message msg)
3415 {
3416         OSCSurface *sur = get_surface(get_address (msg));
3417         boost::shared_ptr<Stripable> s;
3418         if (sur->expand_enable) {
3419                 s = get_strip (sur->expand, get_address (msg));
3420         } else {
3421                 s = _select;
3422         }
3423         if (s) {
3424                 if (s->trim_control()) {
3425                         s->trim_control()->set_value (dB_to_coefficient (val), PBD::Controllable::NoGroup);
3426                         return 0;
3427                 }
3428         }
3429         return sel_fail ("trimdB", 0, get_address (msg));
3430 }
3431
3432 int
3433 OSC::sel_pan_position (float val, lo_message msg)
3434 {
3435         OSCSurface *sur = get_surface(get_address (msg));
3436         boost::shared_ptr<Stripable> s;
3437         if (sur->expand_enable) {
3438                 s = get_strip (sur->expand, get_address (msg));
3439         } else {
3440                 s = _select;
3441         }
3442         if (s) {
3443                 if(s->pan_azimuth_control()) {
3444                         s->pan_azimuth_control()->set_value (s->pan_azimuth_control()->interface_to_internal (val), PBD::Controllable::NoGroup);
3445                         return 0;
3446                 }
3447         }
3448         return sel_fail ("pan_stereo_position", 0.5, get_address (msg));
3449 }
3450
3451 int
3452 OSC::sel_pan_width (float val, lo_message msg)
3453 {
3454         OSCSurface *sur = get_surface(get_address (msg));
3455         boost::shared_ptr<Stripable> s;
3456         if (sur->expand_enable) {
3457                 s = get_strip (sur->expand, get_address (msg));
3458         } else {
3459                 s = _select;
3460         }
3461         if (s) {
3462                 if (s->pan_width_control()) {
3463                         s->pan_width_control()->set_value (s->pan_width_control()->interface_to_internal (val), PBD::Controllable::NoGroup);
3464                         return 0;
3465                 }
3466         }
3467         return sel_fail ("pan_stereo_width", 1, get_address (msg));
3468 }
3469
3470 int
3471 OSC::route_set_pan_stereo_position (int ssid, float pos, lo_message msg)
3472 {
3473         if (!session) return -1;
3474         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3475
3476         if (s) {
3477                 if(s->pan_azimuth_control()) {
3478                         s->pan_azimuth_control()->set_value (s->pan_azimuth_control()->interface_to_internal (pos), PBD::Controllable::NoGroup);
3479                         return 0;
3480                 }
3481         }
3482
3483         return route_send_fail ("pan_stereo_position", ssid, 0.5, get_address (msg));
3484 }
3485
3486 int
3487 OSC::route_set_pan_stereo_width (int ssid, float pos, lo_message msg)
3488 {
3489         if (!session) return -1;
3490         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3491
3492         if (s) {
3493                 if (s->pan_width_control()) {
3494                         s->pan_width_control()->set_value (pos, PBD::Controllable::NoGroup);
3495                         return 0;
3496                 }
3497         }
3498
3499         return route_send_fail ("pan_stereo_width", ssid, 1, get_address (msg));
3500 }
3501
3502 int
3503 OSC::route_set_send_gain_dB (int ssid, int id, float val, lo_message msg)
3504 {
3505         if (!session) {
3506                 return -1;
3507         }
3508         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3509         float abs;
3510         if (s) {
3511                 if (id > 0) {
3512                         --id;
3513                 }
3514 #ifdef MIXBUS
3515                 abs = val;
3516 #else
3517                 if (val < -192) {
3518                         abs = 0;
3519                 } else {
3520                         abs = dB_to_coefficient (val);
3521                 }
3522 #endif
3523                 if (s->send_level_controllable (id)) {
3524                         s->send_level_controllable (id)->set_value (abs, PBD::Controllable::NoGroup);
3525                         return 0;
3526                 }
3527         }
3528         return 0;
3529 }
3530
3531 int
3532 OSC::route_set_send_fader (int ssid, int id, float val, lo_message msg)
3533 {
3534         if (!session) {
3535                 return -1;
3536         }
3537         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3538         float abs;
3539         if (s) {
3540
3541                 if (id > 0) {
3542                         --id;
3543                 }
3544
3545                 if (s->send_level_controllable (id)) {
3546                         abs = s->send_level_controllable(id)->interface_to_internal (val);
3547                         s->send_level_controllable (id)->set_value (abs, PBD::Controllable::NoGroup);
3548                         return 0;
3549                 }
3550         }
3551         return 0;
3552 }
3553
3554 int
3555 OSC::sel_sendgain (int id, float val, lo_message msg)
3556 {
3557         OSCSurface *sur = get_surface(get_address (msg));
3558         if (sur->send_page_size && (id > (int)sur->send_page_size)) {
3559                 return sel_send_fail ("send_gain", id, -193, get_address (msg));
3560         }
3561         boost::shared_ptr<Stripable> s;
3562         if (sur->expand_enable) {
3563                 s = get_strip (sur->expand, get_address (msg));
3564         } else {
3565                 s = _select;
3566         }
3567         float abs;
3568         int send_id;
3569         if (s) {
3570                 if (id > 0) {
3571                         send_id = id - 1;
3572                 }
3573 #ifdef MIXBUS
3574                 abs = val;
3575 #else
3576                 if (val < -192) {
3577                         abs = 0;
3578                 } else {
3579                         abs = dB_to_coefficient (val);
3580                 }
3581 #endif
3582                 if (sur->send_page_size) {
3583                         send_id = send_id + ((sur->send_page - 1) * sur->send_page_size);
3584                 }
3585                 if (s->send_level_controllable (send_id)) {
3586                         s->send_level_controllable (send_id)->set_value (abs, PBD::Controllable::NoGroup);
3587                         return 0;
3588                 }
3589         }
3590         return sel_send_fail ("send_gain", id, -193, get_address (msg));
3591 }
3592
3593 int
3594 OSC::sel_sendfader (int id, float val, lo_message msg)
3595 {
3596         OSCSurface *sur = get_surface(get_address (msg));
3597         if (sur->send_page_size && (id > (int)sur->send_page_size)) {
3598                 return sel_send_fail ("send_fader", id, 0, get_address (msg));
3599         }
3600         boost::shared_ptr<Stripable> s;
3601         if (sur->expand_enable) {
3602                 s = get_strip (sur->expand, get_address (msg));
3603         } else {
3604                 s = _select;
3605         }
3606         float abs;
3607         int send_id;
3608         if (s) {
3609
3610                 if (id > 0) {
3611                         send_id = id - 1;
3612                 }
3613                 if (sur->send_page_size) {
3614                         send_id = send_id + ((sur->send_page - 1) * sur->send_page_size);
3615                 }
3616
3617                 if (s->send_level_controllable (send_id)) {
3618                         abs = s->send_level_controllable(send_id)->interface_to_internal (val);
3619                         s->send_level_controllable (send_id)->set_value (abs, PBD::Controllable::NoGroup);
3620                         return 0;
3621                 }
3622         }
3623         return sel_send_fail ("send_fader", id, 0, get_address (msg));
3624 }
3625
3626 int
3627 OSC::route_set_send_enable (int ssid, int sid, float val, lo_message msg)
3628 {
3629         if (!session) {
3630                 return -1;
3631         }
3632         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3633
3634         if (s) {
3635
3636                 /* revert to zero-based counting */
3637
3638                 if (sid > 0) {
3639                         --sid;
3640                 }
3641
3642                 if (s->send_enable_controllable (sid)) {
3643                         s->send_enable_controllable (sid)->set_value (val, PBD::Controllable::NoGroup);
3644                         return 0;
3645                 }
3646
3647                 if (s->send_level_controllable (sid)) {
3648                         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
3649                         if (!r) {
3650                                 return 0;
3651                         }
3652                         boost::shared_ptr<Send> snd = boost::dynamic_pointer_cast<Send> (r->nth_send(sid));
3653                         if (snd) {
3654                                 if (val) {
3655                                         snd->activate();
3656                                 } else {
3657                                         snd->deactivate();
3658                                 }
3659                         }
3660                         return 0;
3661                 }
3662
3663         }
3664
3665         return -1;
3666 }
3667
3668 int
3669 OSC::sel_sendenable (int id, float val, lo_message msg)
3670 {
3671         OSCSurface *sur = get_surface(get_address (msg));
3672         if (sur->send_page_size && (id > (int)sur->send_page_size)) {
3673                 return sel_send_fail ("send_enable", id, 0, get_address (msg));
3674         }
3675         boost::shared_ptr<Stripable> s;
3676         if (sur->expand_enable) {
3677                 s = get_strip (sur->expand, get_address (msg));
3678         } else {
3679                 s = _select;
3680         }
3681         int send_id;
3682         if (s) {
3683                 if (id > 0) {
3684                         send_id = id - 1;
3685                 }
3686                 if (sur->send_page_size) {
3687                         send_id = send_id + ((sur->send_page - 1) * sur->send_page_size);
3688                 }
3689                 if (s->send_enable_controllable (send_id)) {
3690                         s->send_enable_controllable (send_id)->set_value (val, PBD::Controllable::NoGroup);
3691                         return 0;
3692                 }
3693                 if (s->send_level_controllable (send_id)) {
3694                         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
3695                         if (!r) {
3696                                 // should never get here
3697                                 return sel_send_fail ("send_enable", id, 0, get_address (msg));
3698                         }
3699                         boost::shared_ptr<Send> snd = boost::dynamic_pointer_cast<Send> (r->nth_send(send_id));
3700                         if (snd) {
3701                                 if (val) {
3702                                         snd->activate();
3703                                 } else {
3704                                         snd->deactivate();
3705                                 }
3706                         }
3707                         return 0;
3708                 }
3709         }
3710         return sel_send_fail ("send_enable", id, 0, get_address (msg));
3711 }
3712
3713 int
3714 OSC::sel_master_send_enable (int state, lo_message msg)
3715 {
3716         OSCSurface *sur = get_surface(get_address (msg));
3717         boost::shared_ptr<Stripable> s;
3718         if (sur->expand_enable) {
3719                 s = get_strip (sur->expand, get_address (msg));
3720         } else {
3721                 s = _select;
3722         }
3723         if (s) {
3724                 if (s->master_send_enable_controllable ()) {
3725                         s->master_send_enable_controllable()->set_value (state, PBD::Controllable::NoGroup);
3726                         return 0;
3727                 }
3728         }
3729         return cue_float_message ("/select/master_send_enable", 0, get_address(msg));
3730 }
3731
3732 int
3733 OSC::select_plugin_parameter (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg) {
3734         OSCSurface *sur = get_surface(get_address (msg));
3735         int paid;
3736         int piid = sur->plugin_id;
3737         float value = 0;
3738         if (argc > 1) {
3739                 // no inline args
3740                 if (argc == 2) {
3741                         // change parameter in already selected plugin
3742                         if (argv[0]->f) {
3743                                 paid = (int) argv[0]->f;
3744                         } else {
3745                                 paid = argv[0]->i;
3746                         }
3747                         value = argv[1]->f;
3748                 } else if (argc == 3) {
3749                         if (argv[0]->f) {
3750                                 piid = (int) argv[0]->f;
3751                         } else {
3752                                 piid = argv[0]->i;
3753                         }
3754                         _sel_plugin (piid, get_address (msg));
3755                         if (argv[1]->f) {
3756                                 paid = (int) argv[1]->f;
3757                         } else {
3758                                 paid = argv[1]->i;
3759                         }
3760                         value = argv[2]->f;
3761                 } else if (argc > 3) {
3762                         PBD::warning << "OSC: Too many parameters: " << argc << endmsg;
3763                         return -1;
3764                 }
3765         } else if (argc) {
3766                 const char * par = strstr (&path[25], "/");
3767                 if (par) {
3768                         piid = atoi (&path[25]);
3769                         _sel_plugin (piid, msg);
3770                         paid = atoi (&par[1]);
3771                         value = argv[0]->f;
3772                         // we have plugin id too
3773                 } else {
3774                         // just parameter
3775                         paid = atoi (&path[25]);
3776                         value = argv[0]->f;
3777                 }
3778         } else {
3779                 PBD::warning << "OSC: Must have parameters." << endmsg;
3780                 return -1;
3781         }
3782         if (piid != sur->plugin_id) {
3783                 // if the user is sending to a non-existant plugin, don't adjust one we do have
3784                 PBD::warning << "OSC: plugin: " << piid << " out of range" << endmsg;
3785                 return -1;
3786         }
3787         if (sur->plug_page_size && (paid > (int)sur->plug_page_size)) {
3788                 return sel_send_fail ("plugin/parameter", paid, 0, get_address (msg));
3789         }
3790         boost::shared_ptr<Stripable> s;
3791         if (sur->expand_enable) {
3792                 s = get_strip (sur->expand, get_address (msg));
3793         } else {
3794                 s = _select;
3795         }
3796         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(s);
3797         if (!r) {
3798                 return 1;
3799         }
3800
3801         boost::shared_ptr<Processor> proc = r->nth_plugin (sur->plugins[sur->plugin_id - 1]);
3802         boost::shared_ptr<PluginInsert> pi;
3803         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(proc))) {
3804                 return 1;
3805         }
3806         boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
3807         // paid is paged parameter convert to absolute
3808         int parid = paid + (int)(sur->plug_page_size * (sur->plug_page - 1));
3809         if (parid > (int) sur->plug_params.size ()) {
3810                 if (sur->feedback[13]) {
3811                         sel_send_fail ("plugin/parameter", paid, 0, get_address (msg));
3812                 }
3813                 return 0;
3814         }
3815
3816         bool ok = false;
3817         uint32_t controlid = pip->nth_parameter(sur->plug_params[parid - 1], ok);
3818         if (!ok) {
3819                 return 1;
3820         }
3821         ParameterDescriptor pd;
3822         pip->get_parameter_descriptor(controlid, pd);
3823         if ( pip->parameter_is_input(controlid) || pip->parameter_is_control(controlid) ) {
3824                 boost::shared_ptr<AutomationControl> c = pi->automation_control(Evoral::Parameter(PluginAutomation, 0, controlid));
3825                 if (c) {
3826                         if (pd.integer_step && pd.upper == 1) {
3827                                 if (c->get_value () && value < 1.0) {
3828                                         c->set_value (0, PBD::Controllable::NoGroup);
3829                                 } else if (!c->get_value () && value) {
3830                                         c->set_value (1, PBD::Controllable::NoGroup);
3831                                 }
3832                         } else {
3833                                 c->set_value (c->interface_to_internal (value), PBD::Controllable::NoGroup);
3834                         }
3835                         return 0;
3836                 }
3837         }
3838         return 1;
3839 }
3840
3841 int
3842 OSC::route_plugin_list (int ssid, lo_message msg) {
3843         if (!session) {
3844                 return -1;
3845         }
3846
3847         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(get_strip (ssid, get_address (msg)));
3848
3849         if (!r) {
3850                 PBD::error << "OSC: Invalid Remote Control ID '" << ssid << "'" << endmsg;
3851                 return -1;
3852         }
3853         int piid = 0;
3854
3855         lo_message reply = lo_message_new ();
3856         lo_message_add_int32 (reply, ssid);
3857
3858
3859         for (;;) {
3860                 boost::shared_ptr<Processor> redi = r->nth_plugin(piid);
3861                 if ( !redi ) {
3862                         break;
3863                 }
3864
3865                 boost::shared_ptr<PluginInsert> pi;
3866
3867                 if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
3868                         PBD::error << "OSC: given processor # " << piid << " on RID '" << ssid << "' is not a Plugin." << endmsg;
3869                         continue;
3870                 }
3871                 lo_message_add_int32 (reply, piid + 1);
3872
3873                 boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
3874                 lo_message_add_string (reply, pip->name());
3875
3876                 piid++;
3877         }
3878
3879         lo_send_message (get_address (msg), "/strip/plugin/list", reply);
3880         lo_message_free (reply);
3881         return 0;
3882 }
3883
3884 int
3885 OSC::route_plugin_descriptor (int ssid, int piid, lo_message msg) {
3886         if (!session) {
3887                 return -1;
3888         }
3889
3890         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(get_strip (ssid, get_address (msg)));
3891
3892         if (!r) {
3893                 PBD::error << "OSC: Invalid Remote Control ID '" << ssid << "'" << endmsg;
3894                 return -1;
3895         }
3896
3897         boost::shared_ptr<Processor> redi = r->nth_plugin(piid - 1);
3898
3899         if (!redi) {
3900                 PBD::error << "OSC: cannot find plugin # " << piid << " for RID '" << ssid << "'" << endmsg;
3901                 return -1;
3902         }
3903
3904         boost::shared_ptr<PluginInsert> pi;
3905
3906         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
3907                 PBD::error << "OSC: given processor # " << piid << " on RID '" << ssid << "' is not a Plugin." << endmsg;
3908                 return -1;
3909         }
3910
3911         boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
3912         bool ok = false;
3913
3914         lo_message reply = lo_message_new();
3915         lo_message_add_int32 (reply, ssid);
3916         lo_message_add_int32 (reply, piid);
3917         lo_message_add_string (reply, pip->name());
3918         for ( uint32_t ppi = 0; ppi < pip->parameter_count(); ppi++) {
3919
3920                 uint32_t controlid = pip->nth_parameter(ppi, ok);
3921                 if (!ok) {
3922                         continue;
3923                 }
3924                 if ( pip->parameter_is_input(controlid) || pip->parameter_is_control(controlid) ) {
3925                         boost::shared_ptr<AutomationControl> c = pi->automation_control(Evoral::Parameter(PluginAutomation, 0, controlid));
3926
3927                                 lo_message_add_int32 (reply, ppi + 1);
3928                                 ParameterDescriptor pd;
3929                                 pi->plugin()->get_parameter_descriptor(controlid, pd);
3930                                 lo_message_add_string (reply, pd.label.c_str());
3931
3932                                 // I've combined those binary descriptor parts in a bit-field to reduce lilo message elements
3933                                 int flags = 0;
3934                                 flags |= pd.enumeration ? 1 : 0;
3935                                 flags |= pd.integer_step ? 2 : 0;
3936                                 flags |= pd.logarithmic ? 4 : 0;
3937                                 flags |= pd.sr_dependent ? 32 : 0;
3938                                 flags |= pd.toggled ? 64 : 0;
3939                                 flags |= c != NULL ? 128 : 0; // bit 7 indicates in input control
3940                                 lo_message_add_int32 (reply, flags);
3941
3942                                 lo_message_add_int32 (reply, pd.datatype);
3943                                 lo_message_add_float (reply, pd.lower);
3944                                 lo_message_add_float (reply, pd.upper);
3945                                 lo_message_add_string (reply, pd.print_fmt.c_str());
3946                                 if ( pd.scale_points ) {
3947                                         lo_message_add_int32 (reply, pd.scale_points->size());
3948                                         for ( ARDOUR::ScalePoints::const_iterator i = pd.scale_points->begin(); i != pd.scale_points->end(); ++i) {
3949                                                 lo_message_add_int32 (reply, i->second);
3950                                                 lo_message_add_string (reply, ((std::string)i->first).c_str());
3951                                         }
3952                                 }
3953                                 else {
3954                                         lo_message_add_int32 (reply, 0);
3955                                 }
3956                                 if ( c ) {
3957                                         lo_message_add_double (reply, c->get_value());
3958                                 }
3959                                 else {
3960                                         lo_message_add_double (reply, 0);
3961                         }
3962                 }
3963         }
3964
3965         lo_send_message (get_address (msg), "/strip/plugin/descriptor", reply);
3966         lo_message_free (reply);
3967
3968         return 0;
3969 }
3970
3971 int
3972 OSC::route_plugin_reset (int ssid, int piid, lo_message msg) {
3973         if (!session) {
3974                 return -1;
3975         }
3976
3977         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(get_strip (ssid, get_address (msg)));
3978
3979         if (!r) {
3980                 PBD::error << "OSC: Invalid Remote Control ID '" << ssid << "'" << endmsg;
3981                 return -1;
3982         }
3983
3984         boost::shared_ptr<Processor> redi = r->nth_plugin(piid - 1);
3985
3986         if (!redi) {
3987                 PBD::error << "OSC: cannot find plugin # " << piid << " for RID '" << ssid << "'" << endmsg;
3988                 return -1;
3989         }
3990
3991         boost::shared_ptr<PluginInsert> pi;
3992
3993         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
3994                 PBD::error << "OSC: given processor # " << piid << " on RID '" << ssid << "' is not a Plugin." << endmsg;
3995                 return -1;
3996         }
3997
3998         pi->reset_parameters_to_default ();
3999
4000         return 0;
4001 }
4002
4003 int
4004 OSC::route_plugin_parameter (int ssid, int piid, int par, float val, lo_message msg)
4005 {
4006         if (!session)
4007                 return -1;
4008         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
4009
4010         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
4011
4012         if (!r) {
4013                 PBD::error << "OSC: Invalid Remote Control ID '" << ssid << "'" << endmsg;
4014                 return -1;
4015         }
4016
4017         boost::shared_ptr<Processor> redi=r->nth_plugin (piid - 1);
4018
4019         if (!redi) {
4020                 PBD::error << "OSC: cannot find plugin # " << piid << " for RID '" << ssid << "'" << endmsg;
4021                 return -1;
4022         }
4023
4024         boost::shared_ptr<PluginInsert> pi;
4025
4026         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
4027                 PBD::error << "OSC: given processor # " << piid << " on RID '" << ssid << "' is not a Plugin." << endmsg;
4028                 return -1;
4029         }
4030
4031         boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
4032         bool ok=false;
4033
4034         uint32_t controlid = pip->nth_parameter (par - 1,ok);
4035
4036         if (!ok) {
4037                 PBD::error << "OSC: Cannot find parameter # " << par <<  " for plugin # " << piid << " on RID '" << ssid << "'" << endmsg;
4038                 return -1;
4039         }
4040
4041         if (!pip->parameter_is_input(controlid)) {
4042                 PBD::error << "OSC: Parameter # " << par <<  " for plugin # " << piid << " on RID '" << ssid << "' is not a control input" << endmsg;
4043                 return -1;
4044         }
4045
4046         ParameterDescriptor pd;
4047         pi->plugin()->get_parameter_descriptor (controlid,pd);
4048
4049         if (val >= pd.lower && val <= pd.upper) {
4050
4051                 boost::shared_ptr<AutomationControl> c = pi->automation_control (Evoral::Parameter(PluginAutomation, 0, controlid));
4052                 // cerr << "parameter:" << redi->describe_parameter(controlid) << " val:" << val << "\n";
4053                 c->set_value (val, PBD::Controllable::NoGroup);
4054         } else {
4055                 PBD::warning << "OSC: Parameter # " << par <<  " for plugin # " << piid << " on RID '" << ssid << "' is out of range" << endmsg;
4056                 PBD::info << "OSC: Valid range min=" << pd.lower << " max=" << pd.upper << endmsg;
4057         }
4058
4059         return 0;
4060 }
4061
4062 //prints to cerr only
4063 int
4064 OSC::route_plugin_parameter_print (int ssid, int piid, int par, lo_message msg)
4065 {
4066         if (!session) {
4067                 return -1;
4068         }
4069         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
4070
4071         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
4072
4073         if (!r) {
4074                 return -1;
4075         }
4076
4077         boost::shared_ptr<Processor> redi=r->nth_plugin (piid - 1);
4078
4079         if (!redi) {
4080                 return -1;
4081         }
4082
4083         boost::shared_ptr<PluginInsert> pi;
4084
4085         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
4086                 return -1;
4087         }
4088
4089         boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
4090         bool ok=false;
4091
4092         uint32_t controlid = pip->nth_parameter (par - 1,ok);
4093
4094         if (!ok) {
4095                 return -1;
4096         }
4097
4098         ParameterDescriptor pd;
4099
4100         if (pi->plugin()->get_parameter_descriptor (controlid, pd) == 0) {
4101                 boost::shared_ptr<AutomationControl> c = pi->automation_control (Evoral::Parameter(PluginAutomation, 0, controlid));
4102
4103                 cerr << "parameter:     " << pd.label  << "\n";
4104                 if (c) {
4105                         cerr << "current value: " << c->get_value () << "\n";
4106                 } else {
4107                         cerr << "current value not available, control does not exist\n";
4108                 }
4109                 cerr << "lower value:   " << pd.lower << "\n";
4110                 cerr << "upper value:   " << pd.upper << "\n";
4111         }
4112
4113         return 0;
4114 }
4115
4116 int
4117 OSC::route_plugin_activate (int ssid, int piid, lo_message msg)
4118 {
4119         if (!session)
4120                 return -1;
4121         boost::shared_ptr<Stripable> s = get_strip (ssid, lo_message_get_source (msg));
4122
4123         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
4124
4125         if (!r) {
4126                 PBD::error << "OSC: Invalid Remote Control ID '" << ssid << "'" << endmsg;
4127                 return -1;
4128         }
4129
4130         boost::shared_ptr<Processor> redi=r->nth_plugin (piid - 1);
4131
4132         if (!redi) {
4133                 PBD::error << "OSC: cannot find plugin # " << piid << " for RID '" << ssid << "'" << endmsg;
4134                 return -1;
4135         }
4136
4137         boost::shared_ptr<PluginInsert> pi;
4138
4139         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
4140                 PBD::error << "OSC: given processor # " << piid << " on RID '" << ssid << "' is not a Plugin." << endmsg;
4141                 return -1;
4142         }
4143
4144         boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
4145         pi->activate();
4146
4147         return 0;
4148 }
4149
4150 int
4151 OSC::route_plugin_deactivate (int ssid, int piid, lo_message msg)
4152 {
4153         if (!session)
4154                 return -1;
4155         boost::shared_ptr<Stripable> s = get_strip (ssid, lo_message_get_source (msg));
4156
4157         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
4158
4159         if (!r) {
4160                 PBD::error << "OSC: Invalid Remote Control ID '" << ssid << "'" << endmsg;
4161                 return -1;
4162         }
4163
4164         boost::shared_ptr<Processor> redi=r->nth_plugin (piid - 1);
4165
4166         if (!redi) {
4167                 PBD::error << "OSC: cannot find plugin # " << piid << " for RID '" << ssid << "'" << endmsg;
4168                 return -1;
4169         }
4170
4171         boost::shared_ptr<PluginInsert> pi;
4172
4173         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
4174                 PBD::error << "OSC: given processor # " << piid << " on RID '" << ssid << "' is not a Plugin." << endmsg;
4175                 return -1;
4176         }
4177
4178         boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
4179         pi->deactivate();
4180
4181         return 0;
4182 }
4183
4184 // select
4185
4186 int
4187 OSC::sel_pan_elevation (float val, lo_message msg)
4188 {
4189         OSCSurface *sur = get_surface(get_address (msg));
4190         boost::shared_ptr<Stripable> s;
4191         if (sur->expand_enable) {
4192                 s = get_strip (sur->expand, get_address (msg));
4193         } else {
4194                 s = _select;
4195         }
4196         if (s) {
4197                 if (s->pan_elevation_control()) {
4198                         s->pan_elevation_control()->set_value (s->pan_elevation_control()->interface_to_internal (val), PBD::Controllable::NoGroup);
4199                         return 0;
4200                 }
4201         }
4202         return sel_fail ("pan_elevation_position", 0, get_address (msg));
4203 }
4204
4205 int
4206 OSC::sel_pan_frontback (float val, lo_message msg)
4207 {
4208         OSCSurface *sur = get_surface(get_address (msg));
4209         boost::shared_ptr<Stripable> s;
4210         if (sur->expand_enable) {
4211                 s = get_strip (sur->expand, get_address (msg));
4212         } else {
4213                 s = _select;
4214         }
4215         if (s) {
4216                 if (s->pan_frontback_control()) {
4217                         s->pan_frontback_control()->set_value (s->pan_frontback_control()->interface_to_internal (val), PBD::Controllable::NoGroup);
4218                         return 0;
4219                 }
4220         }
4221         return sel_fail ("pan_frontback_position", 0.5, get_address (msg));
4222 }
4223
4224 int
4225 OSC::sel_pan_lfe (float val, lo_message msg)
4226 {
4227         OSCSurface *sur = get_surface(get_address (msg));
4228         boost::shared_ptr<Stripable> s;
4229         if (sur->expand_enable) {
4230                 s = get_strip (sur->expand, get_address (msg));
4231         } else {
4232                 s = _select;
4233         }
4234         if (s) {
4235                 if (s->pan_lfe_control()) {
4236                         s->pan_lfe_control()->set_value (s->pan_lfe_control()->interface_to_internal (val), PBD::Controllable::NoGroup);
4237                         return 0;
4238                 }
4239         }
4240         return sel_fail ("pan_lfe_control", 0, get_address (msg));
4241 }
4242
4243 // compressor control
4244 int
4245 OSC::sel_comp_enable (float val, lo_message msg)
4246 {
4247         OSCSurface *sur = get_surface(get_address (msg));
4248         boost::shared_ptr<Stripable> s;
4249         if (sur->expand_enable) {
4250                 s = get_strip (sur->expand, get_address (msg));
4251         } else {
4252                 s = _select;
4253         }
4254         if (s) {
4255                 if (s->comp_enable_controllable()) {
4256                         s->comp_enable_controllable()->set_value (s->comp_enable_controllable()->interface_to_internal (val), PBD::Controllable::NoGroup);
4257                         return 0;
4258                 }
4259         }
4260         return sel_fail ("comp_enable", 0, get_address (msg));
4261 }
4262
4263 int
4264 OSC::sel_comp_threshold (float val, lo_message msg)
4265 {
4266         OSCSurface *sur = get_surface(get_address (msg));
4267         boost::shared_ptr<Stripable> s;
4268         if (sur->expand_enable) {
4269                 s = get_strip (sur->expand, get_address (msg));
4270         } else {
4271                 s = _select;
4272         }
4273         if (s) {
4274                 if (s->comp_threshold_controllable()) {
4275                         s->comp_threshold_controllable()->set_value (s->comp_threshold_controllable()->interface_to_internal (val), PBD::Controllable::NoGroup);
4276                         return 0;
4277                 }
4278         }
4279         return sel_fail ("comp_threshold", 0, get_address (msg));
4280 }
4281
4282 int
4283 OSC::sel_comp_speed (float val, lo_message msg)
4284 {
4285         OSCSurface *sur = get_surface(get_address (msg));
4286         boost::shared_ptr<Stripable> s;
4287         if (sur->expand_enable) {
4288                 s = get_strip (sur->expand, get_address (msg));
4289         } else {
4290                 s = _select;
4291         }
4292         if (s) {
4293                 if (s->comp_speed_controllable()) {
4294                         s->comp_speed_controllable()->set_value (s->comp_speed_controllable()->interface_to_internal (val), PBD::Controllable::NoGroup);
4295                         return 0;
4296                 }
4297         }
4298         return sel_fail ("comp_speed", 0, get_address (msg));
4299 }
4300
4301 int
4302 OSC::sel_comp_mode (float val, lo_message msg)
4303 {
4304         OSCSurface *sur = get_surface(get_address (msg));
4305         boost::shared_ptr<Stripable> s;
4306         if (sur->expand_enable) {
4307                 s = get_strip (sur->expand, get_address (msg));
4308         } else {
4309                 s = _select;
4310         }
4311         if (s) {
4312                 if (s->comp_mode_controllable()) {
4313                         s->comp_mode_controllable()->set_value (s->comp_mode_controllable()->interface_to_internal (val), PBD::Controllable::NoGroup);
4314                         return 0;
4315                 }
4316         }
4317         return sel_fail ("comp_mode", 0, get_address (msg));
4318 }
4319
4320 int
4321 OSC::sel_comp_makeup (float val, lo_message msg)
4322 {
4323         OSCSurface *sur = get_surface(get_address (msg));
4324         boost::shared_ptr<Stripable> s;
4325         if (sur->expand_enable) {
4326                 s = get_strip (sur->expand, get_address (msg));
4327         } else {
4328                 s = _select;
4329         }
4330         if (s) {
4331                 if (s->comp_makeup_controllable()) {
4332                         s->comp_makeup_controllable()->set_value (s->comp_makeup_controllable()->interface_to_internal (val), PBD::Controllable::NoGroup);
4333                         return 0;
4334                 }
4335         }
4336         return sel_fail ("comp_makeup", 0, get_address (msg));
4337 }
4338
4339 // EQ control
4340
4341 int
4342 OSC::sel_eq_enable (float val, lo_message msg)
4343 {
4344         OSCSurface *sur = get_surface(get_address (msg));
4345         boost::shared_ptr<Stripable> s;
4346         if (sur->expand_enable) {
4347                 s = get_strip (sur->expand, get_address (msg));
4348         } else {
4349                 s = _select;
4350         }
4351         if (s) {
4352                 if (s->eq_enable_controllable()) {
4353                         s->eq_enable_controllable()->set_value (s->eq_enable_controllable()->interface_to_internal (val), PBD::Controllable::NoGroup);
4354                         return 0;
4355                 }
4356         }
4357         return sel_fail ("eq_enable", 0, get_address (msg));
4358 }
4359
4360 int
4361 OSC::sel_eq_hpf_freq (float val, lo_message msg)
4362 {
4363         OSCSurface *sur = get_surface(get_address (msg));
4364         boost::shared_ptr<Stripable> s;
4365         if (sur->expand_enable) {
4366                 s = get_strip (sur->expand, get_address (msg));
4367         } else {
4368                 s = _select;
4369         }
4370         if (s) {
4371                 if (s->filter_freq_controllable(true)) {
4372                         s->filter_freq_controllable(true)->set_value (s->filter_freq_controllable(true)->interface_to_internal (val), PBD::Controllable::NoGroup);
4373                         return 0;
4374                 }
4375         }
4376         return sel_fail ("eq_hpf/freq", 0, get_address (msg));
4377 }
4378
4379 int
4380 OSC::sel_eq_lpf_freq (float val, lo_message msg)
4381 {
4382         OSCSurface *sur = get_surface(get_address (msg));
4383         boost::shared_ptr<Stripable> s;
4384         if (sur->expand_enable) {
4385                 s = get_strip (sur->expand, get_address (msg));
4386         } else {
4387                 s = _select;
4388         }
4389         if (s) {
4390                 if (s->filter_freq_controllable(false)) {
4391                         s->filter_freq_controllable(false)->set_value (s->filter_freq_controllable(false)->interface_to_internal (val), PBD::Controllable::NoGroup);
4392                         return 0;
4393                 }
4394         }
4395         return sel_fail ("eq_lpf/freq", 0, get_address (msg));
4396 }
4397
4398 int
4399 OSC::sel_eq_hpf_enable (float val, lo_message msg)
4400 {
4401         OSCSurface *sur = get_surface(get_address (msg));
4402         boost::shared_ptr<Stripable> s;
4403         if (sur->expand_enable) {
4404                 s = get_strip (sur->expand, get_address (msg));
4405         } else {
4406                 s = _select;
4407         }
4408         if (s) {
4409                 if (s->filter_enable_controllable(true)) {
4410                         s->filter_enable_controllable(true)->set_value (s->filter_enable_controllable(true)->interface_to_internal (val), PBD::Controllable::NoGroup);
4411                         return 0;
4412                 }
4413         }
4414         return sel_fail ("eq_hpf/enable", 0, get_address (msg));
4415 }
4416
4417 int
4418 OSC::sel_eq_lpf_enable (float val, lo_message msg)
4419 {
4420         OSCSurface *sur = get_surface(get_address (msg));
4421         boost::shared_ptr<Stripable> s;
4422         if (sur->expand_enable) {
4423                 s = get_strip (sur->expand, get_address (msg));
4424         } else {
4425                 s = _select;
4426         }
4427         if (s) {
4428                 if (s->filter_enable_controllable(false)) {
4429                         s->filter_enable_controllable(false)->set_value (s->filter_enable_controllable(false)->interface_to_internal (val), PBD::Controllable::NoGroup);
4430                         return 0;
4431                 }
4432         }
4433         return sel_fail ("eq_lpf/enable", 0, get_address (msg));
4434 }
4435
4436 int
4437 OSC::sel_eq_hpf_slope (float val, lo_message msg)
4438 {
4439         OSCSurface *sur = get_surface(get_address (msg));
4440         boost::shared_ptr<Stripable> s;
4441         if (sur->expand_enable) {
4442                 s = get_strip (sur->expand, get_address (msg));
4443         } else {
4444                 s = _select;
4445         }
4446         if (s) {
4447                 if (s->filter_slope_controllable(true)) {
4448                         s->filter_slope_controllable(true)->set_value (s->filter_slope_controllable(true)->interface_to_internal (val), PBD::Controllable::NoGroup);
4449                         return 0;
4450                 }
4451         }
4452         return sel_fail ("eq_hpf/slope", 0, get_address (msg));
4453 }
4454
4455 int
4456 OSC::sel_eq_lpf_slope (float val, lo_message msg)
4457 {
4458         OSCSurface *sur = get_surface(get_address (msg));
4459         boost::shared_ptr<Stripable> s;
4460         if (sur->expand_enable) {
4461                 s = get_strip (sur->expand, get_address (msg));
4462         } else {
4463                 s = _select;
4464         }
4465         if (s) {
4466                 if (s->filter_slope_controllable(false)) {
4467                         s->filter_slope_controllable(false)->set_value (s->filter_slope_controllable(false)->interface_to_internal (val), PBD::Controllable::NoGroup);
4468                         return 0;
4469                 }
4470         }
4471         return sel_fail ("eq_lpf/slope", 0, get_address (msg));
4472 }
4473
4474 int
4475 OSC::sel_eq_gain (int id, float val, lo_message msg)
4476 {
4477         OSCSurface *sur = get_surface(get_address (msg));
4478         boost::shared_ptr<Stripable> s;
4479         if (sur->expand_enable) {
4480                 s = get_strip (sur->expand, get_address (msg));
4481         } else {
4482                 s = _select;
4483         }
4484         if (s) {
4485                 if (id > 0) {
4486                         --id;
4487                 }
4488                 if (s->eq_gain_controllable (id)) {
4489                         s->eq_gain_controllable (id)->set_value (s->eq_gain_controllable(id)->interface_to_internal (val), PBD::Controllable::NoGroup);
4490                         return 0;
4491                 }
4492         }
4493         return sel_send_fail ("eq_gain", id + 1, 0, get_address (msg));
4494 }
4495
4496 int
4497 OSC::sel_eq_freq (int id, float val, lo_message msg)
4498 {
4499         OSCSurface *sur = get_surface(get_address (msg));
4500         boost::shared_ptr<Stripable> s;
4501         if (sur->expand_enable) {
4502                 s = get_strip (sur->expand, get_address (msg));
4503         } else {
4504                 s = _select;
4505         }
4506         if (s) {
4507                 if (id > 0) {
4508                         --id;
4509                 }
4510                 if (s->eq_freq_controllable (id)) {
4511                         s->eq_freq_controllable (id)->set_value (s->eq_freq_controllable(id)->interface_to_internal (val), PBD::Controllable::NoGroup);
4512                         return 0;
4513                 }
4514         }
4515         return sel_send_fail ("eq_freq", id + 1, 0, get_address (msg));
4516 }
4517
4518 int
4519 OSC::sel_eq_q (int id, float val, lo_message msg)
4520 {
4521         OSCSurface *sur = get_surface(get_address (msg));
4522         boost::shared_ptr<Stripable> s;
4523         if (sur->expand_enable) {
4524                 s = get_strip (sur->expand, get_address (msg));
4525         } else {
4526                 s = _select;
4527         }
4528         if (s) {
4529                 if (id > 0) {
4530                         --id;
4531                 }
4532                 if (s->eq_q_controllable (id)) {
4533                         s->eq_q_controllable (id)->set_value (s->eq_q_controllable(id)->interface_to_internal (val), PBD::Controllable::NoGroup);
4534                         return 0;
4535                 }
4536         }
4537         return sel_send_fail ("eq_q", id + 1, 0, get_address (msg));
4538 }
4539
4540 int
4541 OSC::sel_eq_shape (int id, float val, lo_message msg)
4542 {
4543         OSCSurface *sur = get_surface(get_address (msg));
4544         boost::shared_ptr<Stripable> s;
4545         if (sur->expand_enable) {
4546                 s = get_strip (sur->expand, get_address (msg));
4547         } else {
4548                 s = _select;
4549         }
4550         if (s) {
4551                 if (id > 0) {
4552                         --id;
4553                 }
4554                 if (s->eq_shape_controllable (id)) {
4555                         s->eq_shape_controllable (id)->set_value (s->eq_shape_controllable(id)->interface_to_internal (val), PBD::Controllable::NoGroup);
4556                         return 0;
4557                 }
4558         }
4559         return sel_send_fail ("eq_shape", id + 1, 0, get_address (msg));
4560 }
4561
4562 void
4563 OSC::gui_selection_changed ()
4564 {
4565         boost::shared_ptr<Stripable> strip = ControlProtocol::first_selected_stripable();
4566
4567         if (strip) {
4568                 _select = strip;
4569                 for (uint32_t it = 0; it < _surface.size(); ++it) {
4570                         OSCSurface* sur = &_surface[it];
4571                         if(!sur->expand_enable) {
4572                                 lo_address addr = lo_address_new_from_url (sur->remote_url.c_str());
4573                                 _strip_select (strip, addr);
4574                         }
4575                 }
4576         }
4577 }
4578
4579 // timer callbacks
4580 bool
4581 OSC::periodic (void)
4582 {
4583         if (!tick) {
4584                 Glib::usleep(100); // let flurry of signals subside
4585                 if (global_init) {
4586                         for (uint32_t it = 0; it < _surface.size(); it++) {
4587                                 OSCSurface* sur = &_surface[it];
4588                                 lo_address addr = lo_address_new_from_url (sur->remote_url.c_str());
4589                                 global_feedback (sur->feedback, addr, sur->gainmode);
4590                         }
4591                         global_init = false;
4592                         tick = true;
4593                 }
4594                 if (bank_dirty) {
4595                         _recalcbanks ();
4596                         bank_dirty = false;
4597                         tick = true;
4598                 }
4599         }
4600
4601         if (scrub_speed != 0) {
4602                 // for those jog wheels that don't have 0 on release (touch), time out.
4603                 int64_t now = ARDOUR::get_microseconds ();
4604                 int64_t diff = now - scrub_time;
4605                 if (diff > 120000) {
4606                         scrub_speed = 0;
4607                         session->request_transport_speed (0);
4608                         // locate to the place PH was at last tick
4609                         session->request_locate (scrub_place, false);
4610                 }
4611         }
4612
4613         for (GlobalObservers::iterator x = global_observers.begin(); x != global_observers.end(); x++) {
4614
4615                 OSCGlobalObserver* go;
4616
4617                 if ((go = dynamic_cast<OSCGlobalObserver*>(*x)) != 0) {
4618                         go->tick();
4619                 }
4620         }
4621         for (RouteObservers::iterator x = route_observers.begin(); x != route_observers.end(); x++) {
4622
4623                 OSCRouteObserver* ro;
4624
4625                 if ((ro = dynamic_cast<OSCRouteObserver*>(*x)) != 0) {
4626                         ro->tick();
4627                 }
4628         }
4629         for (uint32_t it = 0; it < _surface.size(); it++) {
4630                 OSCSurface* sur = &_surface[it];
4631                 OSCSelectObserver* so;
4632                 if ((so = dynamic_cast<OSCSelectObserver*>(sur->sel_obs)) != 0) {
4633                         so->tick();
4634                 }
4635         }
4636         for (CueObservers::iterator x = cue_observers.begin(); x != cue_observers.end(); x++) {
4637
4638                 OSCCueObserver* co;
4639
4640                 if ((co = dynamic_cast<OSCCueObserver*>(*x)) != 0) {
4641                         co->tick();
4642                 }
4643         }
4644         for (FakeTouchMap::iterator x = _touch_timeout.begin(); x != _touch_timeout.end();) {
4645                 _touch_timeout[(*x).first] = (*x).second - 1;
4646                 if (!(*x).second) {
4647                         boost::shared_ptr<ARDOUR::AutomationControl> ctrl = (*x).first;
4648                         // turn touch off
4649                         ctrl->stop_touch (true, ctrl->session().transport_frame());
4650                         _touch_timeout.erase (x++);
4651                 } else {
4652                         x++;
4653                 }
4654         }
4655         return true;
4656 }
4657
4658 int
4659 OSC::route_send_fail (string path, uint32_t ssid, float val, lo_address addr)
4660 {
4661         OSCSurface *sur = get_surface(addr);
4662
4663         ostringstream os;
4664         lo_message reply;
4665         if (ssid) {
4666                 reply = lo_message_new ();
4667                 if (sur->feedback[2]) {
4668                         os << "/strip/" << path << "/" << ssid;
4669                 } else {
4670                         os << "/strip/" << path;
4671                         lo_message_add_int32 (reply, ssid);
4672                 }
4673                 string str_pth = os.str();
4674                 lo_message_add_float (reply, (float) val);
4675
4676                 lo_send_message (addr, str_pth.c_str(), reply);
4677                 lo_message_free (reply);
4678         }
4679         if ((_select == get_strip (ssid, addr)) || ((sur->expand == ssid) && (sur->expand_enable))) {
4680                 os.str("");
4681                 os << "/select/" << path;
4682                 string sel_pth = os.str();
4683                 reply = lo_message_new ();
4684                 lo_message_add_float (reply, (float) val);
4685                 lo_send_message (addr, sel_pth.c_str(), reply);
4686                 lo_message_free (reply);
4687         }
4688
4689         return 0;
4690 }
4691
4692 int
4693 OSC::sel_fail (string path, float val, lo_address addr)
4694 {
4695         ostringstream os;
4696         os.str("");
4697         os << "/select/" << path;
4698         string sel_pth = os.str();
4699         lo_message reply = lo_message_new ();
4700         lo_message_add_float (reply, (float) val);
4701         lo_send_message (addr, sel_pth.c_str(), reply);
4702         lo_message_free (reply);
4703
4704         return 0;
4705 }
4706
4707 int
4708 OSC::sel_send_fail (string path, uint32_t id, float val, lo_address addr)
4709 {
4710         OSCSurface *sur = get_surface(addr);
4711
4712         ostringstream os;
4713         lo_message reply;
4714         reply = lo_message_new ();
4715         if (sur->feedback[2]) {
4716                 os << "/select/" << path << "/" << id;
4717         } else {
4718                 os << "/select/" << path;
4719                 lo_message_add_int32 (reply, id);
4720         }
4721         string str_pth = os.str();
4722         lo_message_add_float (reply, (float) val);
4723
4724         lo_send_message (addr, str_pth.c_str(), reply);
4725         lo_message_free (reply);
4726
4727         return 0;
4728 }
4729
4730 XMLNode&
4731 OSC::get_state ()
4732 {
4733         XMLNode& node (ControlProtocol::get_state());
4734         node.set_property ("debugmode", (int32_t) _debugmode); // TODO: enum2str
4735         node.set_property ("address-only", address_only);
4736         node.set_property ("remote-port", remote_port);
4737         node.set_property ("banksize", default_banksize);
4738         node.set_property ("striptypes", default_strip);
4739         node.set_property ("feedback", default_feedback);
4740         node.set_property ("gainmode", default_gainmode);
4741         node.set_property ("send-page-size", default_send_size);
4742         node.set_property ("plug-page-size", default_plugin_size);
4743         if (_surface.size()) {
4744                 XMLNode* config = new XMLNode (X_("Configurations"));
4745                 for (uint32_t it = 0; it < _surface.size(); ++it) {
4746                         OSCSurface* sur = &_surface[it];
4747                         XMLNode* devnode = new XMLNode (X_("Configuration"));
4748                         devnode->set_property (X_("url"), sur->remote_url);
4749                         devnode->set_property (X_("bank-size"), sur->bank_size);
4750                         devnode->set_property (X_("strip-types"), (uint64_t)sur->strip_types.to_ulong());
4751                         devnode->set_property (X_("feedback"), (uint64_t)sur->feedback.to_ulong());
4752                         devnode->set_property (X_("gainmode"), sur->gainmode);
4753                         devnode->set_property (X_("send-page-size"), sur->send_page_size);
4754                         devnode->set_property (X_("plug-page-size"), sur->plug_page_size);
4755                         devnode->set_property (X_("no-clear"), sur->no_clear);
4756                         devnode->set_property (X_("cue"), sur->cue);
4757                         devnode->set_property (X_("aux"), sur->aux);
4758                         config->add_child_nocopy (*devnode);
4759                 }
4760                 node.add_child_nocopy (*config);
4761         }
4762         return node;
4763 }
4764
4765 int
4766 OSC::set_state (const XMLNode& node, int version)
4767 {
4768         if (ControlProtocol::set_state (node, version)) {
4769                 return -1;
4770         }
4771         int32_t debugmode;
4772         if (node.get_property (X_("debugmode"), debugmode)) {
4773                 _debugmode = OSCDebugMode (debugmode);
4774         }
4775
4776         node.get_property (X_("address-only"), address_only);
4777         node.get_property (X_("remote-port"), remote_port);
4778         node.get_property (X_("banksize"), default_banksize);
4779         node.get_property (X_("striptypes"), default_strip);
4780         node.get_property (X_("feedback"), default_feedback);
4781         node.get_property (X_("gainmode"), default_gainmode);
4782         node.get_property (X_("send-page-size"), default_send_size);
4783         node.get_property (X_("plugin-page-size"), default_plugin_size);
4784
4785         XMLNode* cnode = node.child (X_("Configurations"));
4786
4787         if (cnode) {
4788                 XMLNodeList const& devices = cnode->children();
4789                 for (XMLNodeList::const_iterator d = devices.begin(); d != devices.end(); ++d) {
4790                         OSCSurface s;
4791                         if (!(*d)->get_property (X_("url"), s.remote_url)) {
4792                                 continue;
4793                         }
4794
4795                         bank_dirty = true;
4796
4797                         (*d)->get_property (X_("bank-size"), s.bank_size);
4798
4799                         uint64_t bits;
4800                         if ((*d)->get_property (X_ ("strip-types"), bits)) {
4801                                 s.strip_types = bits;
4802                         }
4803                         if ((*d)->get_property (X_("feedback"), bits)) {
4804                                 s.feedback = bits;
4805                         }
4806                         (*d)->get_property (X_("gainmode"), s.gainmode);
4807
4808                         (*d)->get_property (X_("send-page-size"), s.send_page_size);
4809                         (*d)->get_property (X_("plug-page-size"), s.plug_page_size);
4810                         (*d)->get_property (X_("no-clear"), s.no_clear);
4811                         (*d)->get_property (X_("cue"), s.cue);
4812                         (*d)->get_property (X_("aux"), s.aux);
4813                         s.bank = 1;
4814                         s.sel_obs = 0;
4815                         s.expand = 0;
4816                         s.expand_enable = false;
4817                         s.strips = get_sorted_stripables (s.strip_types, s.cue);
4818                         s.nstrips = s.strips.size ();
4819                         s.jogmode = JOG;
4820                         _surface.push_back (s);
4821                 }
4822         }
4823         global_init = true;
4824         tick = false;
4825
4826         return 0;
4827 }
4828
4829 // predicate for sort call in get_sorted_stripables
4830 struct StripableByPresentationOrder
4831 {
4832         bool operator () (const boost::shared_ptr<Stripable> & a, const boost::shared_ptr<Stripable> & b) const
4833         {
4834                 return a->presentation_info().order() < b->presentation_info().order();
4835         }
4836
4837         bool operator () (const Stripable & a, const Stripable & b) const
4838         {
4839                 return a.presentation_info().order() < b.presentation_info().order();
4840         }
4841
4842         bool operator () (const Stripable * a, const Stripable * b) const
4843         {
4844                 return a->presentation_info().order() < b->presentation_info().order();
4845         }
4846 };
4847
4848 OSC::Sorted
4849 OSC::get_sorted_stripables(std::bitset<32> types, bool cue)
4850 {
4851         Sorted sorted;
4852
4853         // fetch all stripables
4854         StripableList stripables;
4855
4856         session->get_stripables (stripables);
4857
4858         // Look for stripables that match bit in sur->strip_types
4859         for (StripableList::iterator it = stripables.begin(); it != stripables.end(); ++it) {
4860
4861                 boost::shared_ptr<Stripable> s = *it;
4862                 if ((!cue) && (!types[9]) && (s->presentation_info().flags() & PresentationInfo::Hidden)) {
4863                         // do nothing... skip it
4864                 } else {
4865
4866                         if (types[0] && (s->presentation_info().flags() & PresentationInfo::AudioTrack)) {
4867                                 sorted.push_back (s);
4868                         } else
4869                         if (types[1] && (s->presentation_info().flags() & PresentationInfo::MidiTrack)) {
4870                                 sorted.push_back (s);
4871                         } else
4872                         if ((s->presentation_info().flags() & PresentationInfo::AudioBus)) {
4873                                 boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
4874                                 // r->feeds (session->master_out()) may make more sense
4875                                 if (r->direct_feeds_according_to_reality (session->master_out())) {
4876                                         // this is a bus
4877                                         if (types[2]) {
4878                                                 sorted.push_back (s);
4879                                         }
4880                                 } else {
4881                                         // this is an Aux out
4882                                         if (types[7]) {
4883                                                 sorted.push_back (s);
4884                                         }
4885                                 }
4886                         } else if (types[3] && (s->presentation_info().flags() & PresentationInfo::MidiBus)) {
4887                                 sorted.push_back (s);
4888                         } else if (types[4] && (s->presentation_info().flags() & PresentationInfo::VCA)) {
4889                                 sorted.push_back (s);
4890                         } else if (types[8] && (s->is_selected())) {
4891                                 sorted.push_back (s);
4892                         } else if (types[9] && (s->presentation_info().flags() & PresentationInfo::Hidden)) {
4893                                 sorted.push_back (s);
4894                         }
4895 #ifdef MIXBUS
4896                         else if (types[2]) {
4897                                 if (Profile->get_mixbus()) {
4898                                         if (s->mixbus()) {
4899                                                 sorted.push_back (s);
4900                                         }
4901                                 }
4902                         }
4903 #endif
4904                 }
4905         }
4906         sort (sorted.begin(), sorted.end(), StripableByPresentationOrder());
4907         // Master/Monitor might be anywhere... we put them at the end - Sorry ;)
4908         if (types[5]) {
4909                 sorted.push_back (session->master_out());
4910         }
4911         if (types[6]) {
4912                 sorted.push_back (session->monitor_out());
4913         }
4914         return sorted;
4915 }
4916
4917 int
4918 OSC::cue_parse (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg)
4919 {
4920         int ret = 1; /* unhandled */
4921
4922         if (!strncmp (path, "/cue/aux", 8)) {
4923                 // set our Aux bus
4924                 ret = cue_set (argv[0]->i, msg);
4925         }
4926         else if (!strncmp (path, "/cue/connect", 12)) {
4927                 // Connect to default Aux bus
4928                 if ((!argc) || argv[0]->i) {
4929                         ret = cue_set (1, msg);
4930                 }
4931         }
4932         else if (!strncmp (path, "/cue/next_aux", 13)) {
4933                 // switch to next Aux bus
4934                 if ((!argc) || argv[0]->i) {
4935                         ret = cue_next (msg);
4936                 }
4937         }
4938         else if (!strncmp (path, "/cue/previous_aux", 17)) {
4939                 // switch to previous Aux bus
4940                 if ((!argc) || argv[0]->i) {
4941                         ret = cue_previous (msg);
4942                 }
4943         }
4944         else if (!strncmp (path, "/cue/send/fader/", 16) && strlen (path) > 16) {
4945                 int id = atoi (&path[16]);
4946                 ret = cue_send_fader (id, argv[0]->f, msg);
4947         }
4948         else if (!strncmp (path, "/cue/send/enable/", 17) && strlen (path) > 17) {
4949                 int id = atoi (&path[17]);
4950                 ret = cue_send_enable (id, argv[0]->f, msg);
4951         }
4952         else if (!strncmp (path, "/cue/fader", 10)) {
4953                 ret = cue_aux_fader (argv[0]->f, msg);
4954         }
4955         else if (!strncmp (path, "/cue/mute", 9)) {
4956                 ret = cue_aux_mute (argv[0]->f, msg);
4957         }
4958
4959         return ret;
4960 }
4961
4962 int
4963 OSC::cue_set (uint32_t aux, lo_message msg)
4964 {
4965         return _cue_set (aux, get_address (msg));
4966 }
4967
4968 int
4969 OSC::_cue_set (uint32_t aux, lo_address addr)
4970 {
4971         int ret = 1;
4972         OSCSurface *s = get_surface(addr);
4973         s->bank_size = 0;
4974         s->strip_types = 128;
4975         s->feedback = 0;
4976         s->gainmode = 1;
4977         s->cue = true;
4978         s->strips = get_sorted_stripables(s->strip_types, s->cue);
4979
4980         s->nstrips = s->strips.size();
4981
4982         if (aux < 1) {
4983                 aux = 1;
4984         } else if (aux > s->nstrips) {
4985                 aux = s->nstrips;
4986         }
4987         s->aux = aux;
4988
4989         // get rid of any old CueObsevers for this address
4990         //cueobserver_connections.drop_connections ();
4991         CueObservers::iterator x;
4992         for (x = cue_observers.begin(); x != cue_observers.end();) {
4993
4994                 OSCCueObserver* co;
4995
4996                 if ((co = dynamic_cast<OSCCueObserver*>(*x)) != 0) {
4997
4998                         int res = strcmp(lo_address_get_url(co->address()), lo_address_get_url(addr));
4999
5000                         if (res == 0) {
5001                                 delete *x;
5002                                 x = cue_observers.erase (x);
5003                         } else {
5004                                 ++x;
5005                         }
5006                 } else {
5007                         ++x;
5008                 }
5009         }
5010
5011         // get a list of Auxes
5012         for (uint32_t n = 0; n < s->nstrips; ++n) {
5013                 boost::shared_ptr<Stripable> stp = s->strips[n];
5014                 if (stp) {
5015                         text_message (string_compose ("/cue/name/%1", n+1), stp->name(), addr);
5016                         if (aux == n+1) {
5017                                 // aux must be at least one
5018                                 // need a signal if aux vanishes
5019                                 stp->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::_cue_set, this, aux, addr), this);
5020
5021                                 // make a list of stripables with sends that go to this bus
5022                                 s->sends = cue_get_sorted_stripables(stp, aux, addr);
5023                                 // start cue observer
5024                                 OSCCueObserver* co = new OSCCueObserver (stp, s->sends, addr);
5025                                 cue_observers.push_back (co);
5026                                 ret = 0;
5027                         }
5028
5029                 }
5030         }
5031
5032         return ret;
5033 }
5034
5035 int
5036 OSC::cue_next (lo_message msg)
5037 {
5038         OSCSurface *s = get_surface(get_address (msg));
5039         int ret = 1;
5040
5041         if (!s->cue) {
5042                 ret = cue_set (1, msg);
5043         }
5044         if (s->aux < s->nstrips) {
5045                 ret = cue_set (s->aux + 1, msg);
5046         } else {
5047                 ret = cue_set (s->nstrips, msg);
5048         }
5049         return ret;
5050 }
5051
5052 int
5053 OSC::cue_previous (lo_message msg)
5054 {
5055         OSCSurface *s = get_surface(get_address (msg));
5056         int ret = 1;
5057         if (!s->cue) {
5058                 ret = cue_set (1, msg);
5059         }
5060         if (s->aux > 1) {
5061                 ret = cue_set (s->aux - 1, msg);
5062         }
5063         return ret;
5064 }
5065
5066 boost::shared_ptr<Send>
5067 OSC::cue_get_send (uint32_t id, lo_address addr)
5068 {
5069         OSCSurface *s = get_surface(addr);
5070         if (id && s->aux > 0 && id <= s->sends.size()) {
5071                 boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s->sends[id - 1]);
5072                 boost::shared_ptr<Stripable> aux = get_strip (s->aux, addr);
5073                 if (r && aux) {
5074                         return r->internal_send_for (boost::dynamic_pointer_cast<Route> (aux));
5075                 }
5076         }
5077         return boost::shared_ptr<Send>();
5078
5079 }
5080
5081 int
5082 OSC::cue_aux_fader (float position, lo_message msg)
5083 {
5084         if (!session) return -1;
5085
5086         OSCSurface *sur = get_surface(get_address (msg));
5087         if (sur->cue) {
5088                 if (sur->aux) {
5089                         boost::shared_ptr<Stripable> s = get_strip (sur->aux, get_address (msg));
5090
5091                         if (s) {
5092                                 if (s->gain_control()) {
5093                                         s->gain_control()->set_value (s->gain_control()->interface_to_internal (position), PBD::Controllable::NoGroup);
5094                                         return 0;
5095                                 }
5096                         }
5097                 }
5098         }
5099         cue_float_message ("/cue/fader", 0, get_address (msg));
5100         return -1;
5101 }
5102
5103 int
5104 OSC::cue_aux_mute (float state, lo_message msg)
5105 {
5106         if (!session) return -1;
5107
5108         OSCSurface *sur = get_surface(get_address (msg));
5109         if (sur->cue) {
5110                 if (sur->aux) {
5111                         boost::shared_ptr<Stripable> s = get_strip (sur->aux, get_address (msg));
5112                         if (s) {
5113                                 if (s->mute_control()) {
5114                                         s->mute_control()->set_value (state ? 1.0 : 0.0, PBD::Controllable::NoGroup);
5115                                         return 0;
5116                                 }
5117                         }
5118                 }
5119         }
5120         cue_float_message ("/cue/mute", 0, get_address (msg));
5121         return -1;
5122 }
5123
5124 int
5125 OSC::cue_send_fader (uint32_t id, float val, lo_message msg)
5126 {
5127         if (!session) {
5128                 return -1;
5129         }
5130         boost::shared_ptr<Send> s = cue_get_send (id, get_address (msg));
5131         if (s) {
5132                 if (s->gain_control()) {
5133                         s->gain_control()->set_value (s->gain_control()->interface_to_internal(val), PBD::Controllable::NoGroup);
5134                         return 0;
5135                 }
5136         }
5137         cue_float_message (string_compose ("/cue/send/fader/%1", id), 0, get_address (msg));
5138         return -1;
5139 }
5140
5141 int
5142 OSC::cue_send_enable (uint32_t id, float state, lo_message msg)
5143 {
5144         if (!session)
5145                 return -1;
5146         boost::shared_ptr<Send> s = cue_get_send (id, get_address (msg));
5147         if (s) {
5148                 if (state) {
5149                         s->activate ();
5150                 } else {
5151                         s->deactivate ();
5152                 }
5153                 return 0;
5154         }
5155         cue_float_message (string_compose ("/cue/send/enable/%1", id), 0, get_address (msg));
5156         return -1;
5157 }
5158
5159 int
5160 OSC::cue_float_message (string path, float val, lo_address addr)
5161 {
5162
5163         lo_message reply;
5164         reply = lo_message_new ();
5165         lo_message_add_float (reply, (float) val);
5166
5167         lo_send_message (addr, path.c_str(), reply);
5168         lo_message_free (reply);
5169
5170         return 0;
5171 }
5172
5173 int
5174 OSC::text_message (string path, string val, lo_address addr)
5175 {
5176
5177         lo_message reply;
5178         reply = lo_message_new ();
5179         lo_message_add_string (reply, val.c_str());
5180
5181         lo_send_message (addr, path.c_str(), reply);
5182         lo_message_free (reply);
5183
5184         return 0;
5185 }
5186
5187
5188 // we have to have a sorted list of stripables that have sends pointed at our aux
5189 // we can use the one in osc.cc to get an aux list
5190 OSC::Sorted
5191 OSC::cue_get_sorted_stripables(boost::shared_ptr<Stripable> aux, uint32_t id, lo_message msg)
5192 {
5193         Sorted sorted;
5194         cueobserver_connections.drop_connections ();
5195         // fetch all stripables
5196         StripableList stripables;
5197
5198         session->get_stripables (stripables);
5199
5200         // Look for stripables that have a send to aux
5201         for (StripableList::iterator it = stripables.begin(); it != stripables.end(); ++it) {
5202
5203                 boost::shared_ptr<Stripable> s = *it;
5204                 // we only want routes
5205                 boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
5206                 if (r) {
5207                         r->processors_changed.connect  (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this);
5208                         boost::shared_ptr<Send> snd = r->internal_send_for (boost::dynamic_pointer_cast<Route> (aux));
5209                         if (snd) { // test for send to aux
5210                                 sorted.push_back (s);
5211                                 s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::cue_set, this, id, msg), this);
5212                         }
5213                 }
5214
5215
5216         }
5217         sort (sorted.begin(), sorted.end(), StripableByPresentationOrder());
5218
5219         return sorted;
5220 }
5221