OSC: Allow /bank_up to accept -1 as well as 1 so encoder can work.
[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_delta);
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_delta (float delta, lo_message msg)
1913 {
1914         if (!session) {
1915                 return -1;
1916         }
1917         OSCSurface *s = get_surface(get_address (msg));
1918         uint32_t new_bank = s->bank + (s->bank_size * (int) delta);
1919         if ((int)new_bank < 1) {
1920                 new_bank = 1;
1921         }
1922         if (new_bank != s->bank) {
1923                 set_bank (new_bank, msg);
1924         }
1925         return 0;
1926 }
1927
1928 int
1929 OSC::bank_down (lo_message msg)
1930 {
1931         if (!session) {
1932                 return -1;
1933         }
1934         OSCSurface *s = get_surface(get_address (msg));
1935         if (s->bank < s->bank_size) {
1936                 set_bank (1, msg);
1937         } else {
1938                 set_bank (s->bank - s->bank_size, msg);
1939         }
1940         return 0;
1941 }
1942
1943 uint32_t
1944 OSC::get_sid (boost::shared_ptr<ARDOUR::Stripable> strip, lo_address addr)
1945 {
1946         if (!strip) {
1947                 return 0;
1948         }
1949
1950         OSCSurface *s = get_surface(addr);
1951
1952         uint32_t b_size;
1953         if (!s->bank_size) {
1954                 // no banking
1955                 b_size = s->nstrips;
1956         } else {
1957                 b_size = s->bank_size;
1958         }
1959
1960         for (uint32_t n = s->bank; n < (min ((b_size + s->bank), s->nstrips + 1)); ++n) {
1961                 if (n <= s->strips.size()) {
1962                         if (strip == s->strips[n-1]) {
1963                                 return n - s->bank + 1;
1964                         }
1965                 }
1966         }
1967         // failsafe... should never get here.
1968         return 0;
1969 }
1970
1971 boost::shared_ptr<ARDOUR::Stripable>
1972 OSC::get_strip (uint32_t ssid, lo_address addr)
1973 {
1974         OSCSurface *s = get_surface(addr);
1975         if (ssid && ((ssid + s->bank - 2) < s->nstrips)) {
1976                 return s->strips[ssid + s->bank - 2];
1977         }
1978         // guess it is out of range
1979         return boost::shared_ptr<ARDOUR::Stripable>();
1980 }
1981
1982 // send and plugin paging commands
1983 int
1984 OSC::sel_send_pagesize (uint32_t size, lo_message msg)
1985 {
1986         OSCSurface *s = get_surface(get_address (msg));
1987         if  (size != s->send_page_size) {
1988                 s->send_page_size = size;
1989                 s->sel_obs->renew_sends();
1990         }
1991         return 0;
1992 }
1993
1994 int
1995 OSC::sel_send_page (int page, lo_message msg)
1996 {
1997         OSCSurface *s = get_surface(get_address (msg));
1998         s->send_page = s->send_page + page;
1999         s->sel_obs->renew_sends();
2000         return 0;
2001 }
2002
2003 int
2004 OSC::sel_plug_pagesize (uint32_t size, lo_message msg)
2005 {
2006         OSCSurface *s = get_surface(get_address (msg));
2007         if (size != s->plug_page_size) {
2008                 s->plug_page_size = size;
2009                 s->sel_obs->renew_plugin();
2010         }
2011         return 0;
2012 }
2013
2014 int
2015 OSC::sel_plug_page (int page, lo_message msg)
2016 {
2017         OSCSurface *s = get_surface(get_address (msg));
2018         s->plug_page = s->plug_page + page;
2019         s->sel_obs->renew_plugin();
2020         return 0;
2021 }
2022
2023 int
2024 OSC::sel_plugin (int delta, lo_message msg)
2025 {
2026         OSCSurface *sur = get_surface(get_address (msg));
2027         return _sel_plugin (sur->plugin_id + delta, get_address (msg));
2028 }
2029
2030 int
2031 OSC::_sel_plugin (int id, lo_address addr)
2032 {
2033         OSCSurface *sur = get_surface(addr);
2034         boost::shared_ptr<Stripable> s;
2035         if (sur->expand_enable) {
2036                 s = get_strip (sur->expand, addr);
2037         } else {
2038                 s = _select;
2039         }
2040         if (s) {
2041                 boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(s);
2042                 if (!r) {
2043                         return 1;
2044                 }
2045
2046                 // find out how many plugins we have
2047                 bool plugs;
2048                 int nplugs  = 0;
2049                 sur->plugins.clear();
2050                 do {
2051                         plugs = false;
2052                         if (r->nth_plugin (nplugs)) {
2053                                 if (r->nth_plugin(nplugs)->display_to_user()) {
2054 #ifdef MIXBUS
2055                                         // need to check for mixbus channel strips (and exclude them)
2056                                         boost::shared_ptr<Processor> proc = r->nth_plugin (nplugs);
2057                                         boost::shared_ptr<PluginInsert> pi;
2058                                         if ((pi = boost::dynamic_pointer_cast<PluginInsert>(proc))) {
2059
2060                                                 if (!pi->is_channelstrip()) {
2061 #endif
2062                                                         sur->plugins.push_back (nplugs);
2063 #ifdef MIXBUS
2064                                                 }
2065                                         }
2066 #endif
2067                                 }
2068                                 plugs = true;
2069                                 nplugs++;
2070                         }
2071                 } while (plugs);
2072
2073                 // limit plugin_id to actual plugins
2074                 if (!sur->plugins.size()) {
2075                         sur->plugin_id = 0;
2076                         return 0;
2077                 } else if (sur->plugins.size() < (uint32_t) id) {
2078                         sur->plugin_id = sur->plugins.size();
2079                 } else  if (sur->plugins.size() && !id) {
2080                         sur->plugin_id = 1;
2081                 } else {
2082                         sur->plugin_id = id;
2083                 }
2084
2085                 // we have a plugin number now get the processor
2086                 boost::shared_ptr<Processor> proc = r->nth_plugin (sur->plugins[sur->plugin_id - 1]);
2087                 boost::shared_ptr<PluginInsert> pi;
2088                 if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(proc))) {
2089                         PBD::warning << "OSC: Plugin: " << sur->plugin_id << " does not seem to be a plugin" << endmsg;                 
2090                         return 1;
2091                 }
2092                 boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
2093                 bool ok = false;
2094                 // put only input controls into a vector
2095                 sur->plug_params.clear ();
2096                 uint32_t nplug_params  = pip->parameter_count();
2097                 for ( uint32_t ppi = 0;  ppi < nplug_params; ++ppi) {
2098                         uint32_t controlid = pip->nth_parameter(ppi, ok);
2099                         if (!ok) {
2100                                 continue;
2101                         }
2102                         if (pip->parameter_is_input(controlid)) {
2103                                 sur->plug_params.push_back (ppi);
2104                         }
2105                 }
2106
2107                 sur->plug_page = 1;
2108
2109                 if (sur->sel_obs) {
2110                         sur->sel_obs->renew_plugin();
2111                 }
2112                 return 0;
2113         }
2114         return 1;
2115 }
2116
2117 void
2118 OSC::transport_frame (lo_message msg)
2119 {
2120         if (!session) {
2121                 return;
2122         }
2123         check_surface (msg);
2124         framepos_t pos = session->transport_frame ();
2125
2126         lo_message reply = lo_message_new ();
2127         lo_message_add_int64 (reply, pos);
2128
2129         lo_send_message (get_address (msg), "/transport_frame", reply);
2130
2131         lo_message_free (reply);
2132 }
2133
2134 void
2135 OSC::transport_speed (lo_message msg)
2136 {
2137         if (!session) {
2138                 return;
2139         }
2140         check_surface (msg);
2141         double ts = session->transport_speed ();
2142
2143         lo_message reply = lo_message_new ();
2144         lo_message_add_double (reply, ts);
2145
2146         lo_send_message (get_address (msg), "/transport_speed", reply);
2147
2148         lo_message_free (reply);
2149 }
2150
2151 void
2152 OSC::record_enabled (lo_message msg)
2153 {
2154         if (!session) {
2155                 return;
2156         }
2157         check_surface (msg);
2158         int re = (int)session->get_record_enabled ();
2159
2160         lo_message reply = lo_message_new ();
2161         lo_message_add_int32 (reply, re);
2162
2163         lo_send_message (get_address (msg), "/record_enabled", reply);
2164
2165         lo_message_free (reply);
2166 }
2167
2168 int
2169 OSC::scrub (float delta, lo_message msg)
2170 {
2171         if (!session) return -1;
2172         check_surface (msg);
2173
2174         scrub_place = session->transport_frame ();
2175
2176         float speed;
2177
2178         int64_t now = ARDOUR::get_microseconds ();
2179         int64_t diff = now - scrub_time;
2180         if (diff > 35000) {
2181                 // speed 1 (or 0 if jog wheel supports touch)
2182                 speed = delta;
2183         } else if ((diff > 20000) && (fabs(scrub_speed) == 1)) {
2184                 // add some hysteresis to stop excess speed jumps
2185                 speed = delta;
2186         } else {
2187                 speed = (int)(delta * 2);
2188         }
2189         scrub_time = now;
2190         if (scrub_speed == speed) {
2191                 // Already at that speed no change
2192                 return 0;
2193         }
2194         scrub_speed = speed;
2195
2196         if (speed > 0) {
2197                 if (speed == 1) {
2198                         session->request_transport_speed (.5);
2199                 } else {
2200                         session->request_transport_speed (1);
2201                 }
2202         } else if (speed < 0) {
2203                 if (speed == -1) {
2204                         session->request_transport_speed (-.5);
2205                 } else {
2206                         session->request_transport_speed (-1);
2207                 }
2208         } else {
2209                 session->request_transport_speed (0);
2210         }
2211
2212         return 0;
2213 }
2214
2215 int
2216 OSC::jog (float delta, lo_message msg)
2217 {
2218         if (!session) return -1;
2219
2220         OSCSurface *s = get_surface(get_address (msg));
2221
2222         string path = "/jog/mode/name";
2223         switch(s->jogmode)
2224         {
2225                 case JOG  :
2226                         text_message (path, "Jog", get_address (msg));
2227                         if (delta) {
2228                                 jump_by_seconds (delta / 5);
2229                         }
2230                         break;
2231                 case SCRUB:
2232                         text_message (path, "Scrub", get_address (msg));
2233                         scrub (delta, msg);
2234                         break;
2235                 case SHUTTLE:
2236                         text_message (path, "Shuttle", get_address (msg));
2237                         if (delta) {
2238                                 double speed = get_transport_speed ();
2239                                 set_transport_speed (speed + (delta / 8));
2240                         } else {
2241                                 set_transport_speed (0);
2242                         }
2243                         break;
2244                 case SCROLL:
2245                         text_message (path, "Scroll", get_address (msg));
2246                         if (delta > 0) {
2247                                 access_action ("Editor/scroll-forward");
2248                         } else if (delta < 0) {
2249                                 access_action ("Editor/scroll-backward");
2250                         }
2251                         break;
2252                 case TRACK:
2253                         text_message (path, "Track", get_address (msg));
2254                         if (delta > 0) {
2255                                 set_bank (s->bank + 1, msg);
2256                         } else if (delta < 0) {
2257                                 set_bank (s->bank - 1, msg);
2258                         }
2259                         break;
2260                 case BANK:
2261                         text_message (path, "Bank", get_address (msg));
2262                         if (delta > 0) {
2263                                 bank_up (msg);
2264                         } else if (delta < 0) {
2265                                 bank_down (msg);
2266                         }
2267                         break;
2268                 case NUDGE:
2269                         text_message (path, "Nudge", get_address (msg));
2270                         if (delta > 0) {
2271                                 access_action ("Common/nudge-playhead-forward");
2272                         } else if (delta < 0) {
2273                                 access_action ("Common/nudge-playhead-backward");
2274                         }
2275                         break;
2276                 case MARKER:
2277                         text_message (path, "Marker", get_address (msg));
2278                         if (delta > 0) {
2279                                 next_marker ();
2280                         } else if (delta < 0) {
2281                                 prev_marker ();
2282                         }
2283                         break;
2284                 default:
2285                         break;
2286
2287         }
2288         return 0;
2289
2290 }
2291
2292 int
2293 OSC::jog_mode (float mode, lo_message msg)
2294 {
2295         if (!session) return -1;
2296
2297         OSCSurface *s = get_surface(get_address (msg));
2298
2299         switch((uint32_t)mode)
2300         {
2301                 case JOG  :
2302                         s->jogmode = JOG;
2303                         break;
2304                 case SCRUB:
2305                         s->jogmode = SCRUB;
2306                         break;
2307                 case SHUTTLE:
2308                         s->jogmode = SHUTTLE;
2309                         break;
2310                 case SCROLL:
2311                         s->jogmode = SCROLL;
2312                         break;
2313                 case TRACK:
2314                         s->jogmode = TRACK;
2315                         break;
2316                 case BANK:
2317                         s->jogmode = BANK;
2318                         break;
2319                 case NUDGE:
2320                         s->jogmode = NUDGE;
2321                         break;
2322                 case MARKER:
2323                         s->jogmode = MARKER;
2324                         break;
2325                 default:
2326                         PBD::warning << "Jog Mode: " << mode << " is not valid." << endmsg;
2327                         break;
2328         lo_message reply = lo_message_new ();
2329         lo_message_add_int32 (reply, s->jogmode);
2330         lo_send_message (get_address(msg), "/jog/mode", reply);
2331         lo_message_free (reply);
2332
2333         }
2334         jog (0, msg);
2335         return 0;
2336
2337 }
2338
2339 // master and monitor calls
2340 int
2341 OSC::master_set_gain (float dB)
2342 {
2343         if (!session) return -1;
2344         boost::shared_ptr<Stripable> s = session->master_out();
2345         if (s) {
2346                 if (dB < -192) {
2347                         s->gain_control()->set_value (0.0, PBD::Controllable::NoGroup);
2348                 } else {
2349                         s->gain_control()->set_value (dB_to_coefficient (dB), PBD::Controllable::NoGroup);
2350                 }
2351         }
2352         return 0;
2353 }
2354
2355 int
2356 OSC::master_set_fader (float position)
2357 {
2358         if (!session) return -1;
2359         boost::shared_ptr<Stripable> s = session->master_out();
2360         if (s) {
2361                 s->gain_control()->set_value (s->gain_control()->interface_to_internal (position), PBD::Controllable::NoGroup);
2362         }
2363         return 0;
2364 }
2365
2366 int
2367 OSC::master_set_trim (float dB)
2368 {
2369         if (!session) return -1;
2370         boost::shared_ptr<Stripable> s = session->master_out();
2371
2372         if (s) {
2373                 s->trim_control()->set_value (dB_to_coefficient (dB), PBD::Controllable::NoGroup);
2374         }
2375
2376         return 0;
2377 }
2378
2379 int
2380 OSC::master_set_pan_stereo_position (float position, lo_message msg)
2381 {
2382         if (!session) return -1;
2383         OSCSurface *sur = get_surface(get_address (msg));
2384
2385         float endposition = .5;
2386         boost::shared_ptr<Stripable> s = session->master_out();
2387
2388         if (s) {
2389                 if (s->pan_azimuth_control()) {
2390                         s->pan_azimuth_control()->set_value (s->pan_azimuth_control()->interface_to_internal (position), PBD::Controllable::NoGroup);
2391                         endposition = s->pan_azimuth_control()->internal_to_interface (s->pan_azimuth_control()->get_value ());
2392                 }
2393         }
2394
2395         if (sur->feedback[4]) {
2396                 lo_message reply = lo_message_new ();
2397                 lo_message_add_float (reply, endposition);
2398
2399                 lo_send_message (get_address (msg), "/master/pan_stereo_position", reply);
2400                 lo_message_free (reply);
2401         }
2402
2403         return 0;
2404 }
2405
2406 int
2407 OSC::master_set_mute (uint32_t state)
2408 {
2409         if (!session) return -1;
2410
2411         boost::shared_ptr<Stripable> s = session->master_out();
2412
2413         if (s) {
2414                 s->mute_control()->set_value (state, PBD::Controllable::NoGroup);
2415         }
2416
2417         return 0;
2418 }
2419
2420 int
2421 OSC::monitor_set_gain (float dB)
2422 {
2423         if (!session) return -1;
2424         boost::shared_ptr<Stripable> s = session->monitor_out();
2425
2426         if (s) {
2427                 if (dB < -192) {
2428                         s->gain_control()->set_value (0.0, PBD::Controllable::NoGroup);
2429                 } else {
2430                         s->gain_control()->set_value (dB_to_coefficient (dB), PBD::Controllable::NoGroup);
2431                 }
2432         }
2433         return 0;
2434 }
2435
2436 int
2437 OSC::monitor_set_fader (float position)
2438 {
2439         if (!session) return -1;
2440         boost::shared_ptr<Stripable> s = session->monitor_out();
2441         if (s) {
2442                 s->gain_control()->set_value (s->gain_control()->interface_to_internal (position), PBD::Controllable::NoGroup);
2443         }
2444         return 0;
2445 }
2446
2447 int
2448 OSC::monitor_set_mute (uint32_t state)
2449 {
2450         if (!session) return -1;
2451
2452         if (session->monitor_out()) {
2453                 boost::shared_ptr<MonitorProcessor> mon = session->monitor_out()->monitor_control();
2454                 mon->set_cut_all (state);
2455         }
2456         return 0;
2457 }
2458
2459 int
2460 OSC::monitor_set_dim (uint32_t state)
2461 {
2462         if (!session) return -1;
2463
2464         if (session->monitor_out()) {
2465                 boost::shared_ptr<MonitorProcessor> mon = session->monitor_out()->monitor_control();
2466                 mon->set_dim_all (state);
2467         }
2468         return 0;
2469 }
2470
2471 int
2472 OSC::monitor_set_mono (uint32_t state)
2473 {
2474         if (!session) return -1;
2475
2476         if (session->monitor_out()) {
2477                 boost::shared_ptr<MonitorProcessor> mon = session->monitor_out()->monitor_control();
2478                 mon->set_mono (state);
2479         }
2480         return 0;
2481 }
2482
2483 int
2484 OSC::route_get_sends(lo_message msg) {
2485         if (!session) {
2486                 return -1;
2487         }
2488
2489         lo_arg **argv = lo_message_get_argv(msg);
2490
2491         int rid = argv[0]->i;
2492
2493         boost::shared_ptr<Stripable> strip = get_strip(rid, get_address(msg));
2494         if (!strip) {
2495                 return -1;
2496         }
2497
2498         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (strip);
2499         if (!r) {
2500                 return -1;
2501         }
2502
2503         lo_message reply = lo_message_new();
2504         lo_message_add_int32(reply, rid);
2505
2506         int i = 0;
2507         for (;;) {
2508                 boost::shared_ptr<Processor> p = r->nth_send(i++);
2509
2510                 if (!p) {
2511                         break;
2512                 }
2513
2514                 boost::shared_ptr<InternalSend> isend = boost::dynamic_pointer_cast<InternalSend> (p);
2515                 if (isend) {
2516                         lo_message_add_int32(reply, get_sid(isend->target_route(), get_address(msg)));
2517                         lo_message_add_string(reply, isend->name().c_str());
2518                         lo_message_add_int32(reply, i);
2519                         boost::shared_ptr<Amp> a = isend->amp();
2520                         lo_message_add_float(reply, a->gain_control()->internal_to_interface (a->gain_control()->get_value()));
2521                         lo_message_add_int32(reply, p->active() ? 1 : 0);
2522                 }
2523         }
2524         // if used dedicated message path to identify this reply in async operation.
2525         // Naming it #reply wont help the client to identify the content.
2526         lo_send_message(get_address (msg), "/strip/sends", reply);
2527
2528         lo_message_free(reply);
2529
2530         return 0;
2531 }
2532
2533 int
2534 OSC::route_get_receives(lo_message msg) {
2535         if (!session) {
2536                 return -1;
2537         }
2538
2539         lo_arg **argv = lo_message_get_argv(msg);
2540
2541         uint32_t rid = argv[0]->i;
2542
2543
2544         boost::shared_ptr<Stripable> strip = get_strip(rid, get_address(msg));
2545         if (!strip) {
2546                 return -1;
2547         }
2548
2549         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (strip);
2550         if (!r) {
2551                 return -1;
2552         }
2553
2554         boost::shared_ptr<RouteList> route_list = session->get_routes();
2555
2556         lo_message reply = lo_message_new();
2557
2558         for (RouteList::iterator i = route_list->begin(); i != route_list->end(); ++i) {
2559                 boost::shared_ptr<Route> tr = boost::dynamic_pointer_cast<Route> (*i);
2560                 if (!tr) {
2561                         continue;
2562                 }
2563                 int j = 0;
2564
2565                 for (;;) {
2566                         boost::shared_ptr<Processor> p = tr->nth_send(j++);
2567
2568                         if (!p) {
2569                                 break;
2570                         }
2571
2572                         boost::shared_ptr<InternalSend> isend = boost::dynamic_pointer_cast<InternalSend> (p);
2573                         if (isend) {
2574                                 if( isend->target_route()->id() == r->id()){
2575                                         boost::shared_ptr<Amp> a = isend->amp();
2576
2577                                         lo_message_add_int32(reply, get_sid(tr, get_address(msg)));
2578                                         lo_message_add_string(reply, tr->name().c_str());
2579                                         lo_message_add_int32(reply, j);
2580                                         lo_message_add_float(reply, a->gain_control()->internal_to_interface (a->gain_control()->get_value()));
2581                                         lo_message_add_int32(reply, p->active() ? 1 : 0);
2582                                 }
2583                         }
2584                 }
2585         }
2586
2587         // I have used a dedicated message path to identify this reply in async operation.
2588         // Naming it #reply wont help the client to identify the content.
2589         lo_send_message(get_address (msg), "/strip/receives", reply);
2590         lo_message_free(reply);
2591         return 0;
2592 }
2593
2594 // strip calls
2595
2596 int
2597 OSC::set_automation (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg)
2598 {
2599         if (!session) return -1;
2600
2601         int ret = 1;
2602         OSCSurface *sur = get_surface(get_address (msg));
2603         boost::shared_ptr<Stripable> strp = boost::shared_ptr<Stripable>();
2604         uint32_t ctr = 0;
2605         uint32_t aut = 0;
2606         uint32_t ssid;
2607
2608         if (argc) {
2609                 if (argv[argc - 1]->f) {
2610                         aut = (int)argv[argc - 1]->f;
2611                 } else {
2612                         aut = argv[argc - 1]->i;
2613                 }
2614         }
2615
2616         //parse path first to find stripable
2617         if (!strncmp (path, "/strip/", 7)) {
2618                 // find ssid and stripable
2619                 if (argc > 1) {
2620                         if (types[1] == 'f') {
2621                                 ssid = (uint32_t)argv[0]->f;
2622                         } else {
2623                                 ssid = argv[0]->i;
2624                         }
2625                         strp = get_strip (ssid, get_address (msg));
2626                 } else {
2627                         ssid = atoi (&(strrchr (path, '/' ))[1]);
2628                         strp = get_strip (ssid, get_address (msg));
2629                 }
2630                 ctr = 7;
2631         } else if (!strncmp (path, "/select/", 8)) {
2632                 if (sur->expand_enable && sur->expand) {
2633                         strp = get_strip (sur->expand, get_address (msg));
2634                 } else {
2635                         strp = ControlProtocol::first_selected_stripable();
2636                 }
2637                 ctr = 8;
2638         } else {
2639                 return ret;
2640         }
2641         if (strp) {
2642                 boost::shared_ptr<AutomationControl> control = boost::shared_ptr<AutomationControl>();
2643                 // other automatable controls can be added by repeating the next 6.5 lines
2644                 if ((!strncmp (&path[ctr], "fader", 5)) || (!strncmp (&path[ctr], "gain", 4))) {
2645                         if (strp->gain_control ()) {
2646                                 control = strp->gain_control ();
2647                         } else {
2648                                 PBD::warning << "No fader for this strip" << endmsg;
2649                         }
2650                 } else {
2651                         PBD::warning << "Automation not available for " << path << endmsg;
2652                 }
2653
2654                 if (control) {
2655
2656                         switch (aut) {
2657                                 case 0:
2658                                         control->set_automation_state (ARDOUR::Off);
2659                                         ret = 0;
2660                                         break;
2661                                 case 1:
2662                                         control->set_automation_state (ARDOUR::Play);
2663                                         ret = 0;
2664                                         break;
2665                                 case 2:
2666                                         control->set_automation_state (ARDOUR::Write);
2667                                         ret = 0;
2668                                         break;
2669                                 case 3:
2670                                         control->set_automation_state (ARDOUR::Touch);
2671                                         ret = 0;
2672                                         break;
2673                                 default:
2674                                         break;
2675                         }
2676                 }
2677         }
2678
2679         return ret;
2680 }
2681
2682 int
2683 OSC::touch_detect (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg)
2684 {
2685         if (!session) return -1;
2686
2687         int ret = 1;
2688         OSCSurface *sur = get_surface(get_address (msg));
2689         boost::shared_ptr<Stripable> strp = boost::shared_ptr<Stripable>();
2690         uint32_t ctr = 0;
2691         uint32_t touch = 0;
2692         uint32_t ssid;
2693
2694         if (argc) {
2695                 if (argv[argc - 1]->f) {
2696                         touch = (int)argv[argc - 1]->f;
2697                 } else {
2698                         touch = argv[argc - 1]->i;
2699                 }
2700         }
2701
2702         //parse path first to find stripable
2703         if (!strncmp (path, "/strip/", 7)) {
2704                 // find ssid and stripable
2705                 if (argc > 1) {
2706                         if (types[0] == 'f') {
2707                                 ssid = (uint32_t)argv[0]->f;
2708                         } else {
2709                                 ssid = argv[0]->i;
2710                         }
2711                         strp = get_strip (ssid, get_address (msg));
2712                 } else {
2713                         ssid = atoi (&(strrchr (path, '/' ))[1]);
2714                         strp = get_strip (ssid, get_address (msg));
2715                 }
2716                 ctr = 7;
2717         } else if (!strncmp (path, "/select/", 8)) {
2718                 if (sur->expand_enable && sur->expand) {
2719                         strp = get_strip (sur->expand, get_address (msg));
2720                 } else {
2721                         strp = ControlProtocol::first_selected_stripable();
2722                 }
2723                 ctr = 8;
2724         } else {
2725                 return ret;
2726         }
2727         if (strp) {
2728                 boost::shared_ptr<AutomationControl> control = boost::shared_ptr<AutomationControl>();
2729                 // other automatable controls can be added by repeating the next 6.5 lines
2730                 if ((!strncmp (&path[ctr], "fader", 5)) || (!strncmp (&path[ctr], "gain", 4))) {
2731                         if (strp->gain_control ()) {
2732                                 control = strp->gain_control ();
2733                         } else {
2734                                 PBD::warning << "No fader for this strip" << endmsg;
2735                         }
2736                 } else {
2737                         PBD::warning << "Automation not available for " << path << endmsg;
2738                 }
2739
2740                 if (control) {
2741                         if (touch) {
2742                                 //start touch
2743                                 if (control->automation_state() == Touch && !control->touching ()) {
2744                                         control->start_touch (control->session().transport_frame());
2745                                 }
2746                                 ret = 0;
2747                         } else {
2748                                 // end touch
2749                                 control->stop_touch (true, control->session().transport_frame());
2750                                 ret = 0;
2751                         }
2752                         // just in case some crazy surface starts sending control values before touch
2753                         FakeTouchMap::iterator x = _touch_timeout.find(control);
2754                         if (x != _touch_timeout.end()) {
2755                                 _touch_timeout.erase (x);
2756                         }
2757                 }
2758         }
2759
2760         return ret;
2761 }
2762
2763 int
2764 OSC::fake_touch (boost::shared_ptr<ARDOUR::AutomationControl> ctrl)
2765 {
2766         if (ctrl) {
2767                 //start touch
2768                 if (ctrl->automation_state() == Touch && !ctrl->touching ()) {
2769                 ctrl->start_touch (ctrl->session().transport_frame());
2770                 _touch_timeout[ctrl] = 10;
2771                 }
2772         }
2773
2774         return 0;
2775 }
2776
2777 int
2778 OSC::route_mute (int ssid, int yn, lo_message msg)
2779 {
2780         if (!session) return -1;
2781         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
2782
2783         if (s) {
2784                 if (s->mute_control()) {
2785                         s->mute_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2786                         return 0;
2787                 }
2788         }
2789
2790         return route_send_fail ("mute", ssid, 0, get_address (msg));
2791 }
2792
2793 int
2794 OSC::sel_mute (uint32_t yn, lo_message msg)
2795 {
2796         OSCSurface *sur = get_surface(get_address (msg));
2797         boost::shared_ptr<Stripable> s;
2798         if (sur->expand_enable) {
2799                 s = get_strip (sur->expand, get_address (msg));
2800         } else {
2801                 s = _select;
2802         }
2803         if (s) {
2804                 if (s->mute_control()) {
2805                         s->mute_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2806                         return 0;
2807                 }
2808         }
2809         return sel_fail ("mute", 0, get_address (msg));
2810 }
2811
2812 int
2813 OSC::route_solo (int ssid, int yn, lo_message msg)
2814 {
2815         if (!session) return -1;
2816         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
2817
2818         if (s) {
2819                 if (s->solo_control()) {
2820                         s->solo_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2821                 }
2822         }
2823
2824         return route_send_fail ("solo", ssid, 0, get_address (msg));
2825 }
2826
2827 int
2828 OSC::route_solo_iso (int ssid, int yn, lo_message msg)
2829 {
2830         if (!session) return -1;
2831         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
2832
2833         if (s) {
2834                 if (s->solo_isolate_control()) {
2835                         s->solo_isolate_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2836                         return 0;
2837                 }
2838         }
2839
2840         return route_send_fail ("solo_iso", ssid, 0, get_address (msg));
2841 }
2842
2843 int
2844 OSC::route_solo_safe (int ssid, int yn, lo_message msg)
2845 {
2846         if (!session) return -1;
2847         boost::shared_ptr<Stripable> s = get_strip (ssid, lo_message_get_source (msg));
2848
2849         if (s) {
2850                 if (s->solo_safe_control()) {
2851                         s->solo_safe_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2852                         return 0;
2853                 }
2854         }
2855
2856         return route_send_fail ("solo_safe", ssid, 0, get_address (msg));
2857 }
2858
2859 int
2860 OSC::sel_solo (uint32_t yn, lo_message msg)
2861 {
2862         OSCSurface *sur = get_surface(get_address (msg));
2863         boost::shared_ptr<Stripable> s;
2864         if (sur->expand_enable) {
2865                 s = get_strip (sur->expand, get_address (msg));
2866         } else {
2867                 s = _select;
2868         }
2869         if (s) {
2870                 if (s->solo_control()) {
2871                         session->set_control (s->solo_control(), yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2872                 }
2873         }
2874         return sel_fail ("solo", 0, get_address (msg));
2875 }
2876
2877 int
2878 OSC::sel_solo_iso (uint32_t yn, lo_message msg)
2879 {
2880         OSCSurface *sur = get_surface(get_address (msg));
2881         boost::shared_ptr<Stripable> s;
2882         if (sur->expand_enable) {
2883                 s = get_strip (sur->expand, get_address (msg));
2884         } else {
2885                 s = _select;
2886         }
2887         if (s) {
2888                 if (s->solo_isolate_control()) {
2889                         s->solo_isolate_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2890                         return 0;
2891                 }
2892         }
2893         return sel_fail ("solo_iso", 0, get_address (msg));
2894 }
2895
2896 int
2897 OSC::sel_solo_safe (uint32_t yn, lo_message msg)
2898 {
2899         OSCSurface *sur = get_surface(get_address (msg));
2900         boost::shared_ptr<Stripable> s;
2901         if (sur->expand_enable) {
2902                 s = get_strip (sur->expand, get_address (msg));
2903         } else {
2904                 s = _select;
2905         }
2906         if (s) {
2907                 if (s->solo_safe_control()) {
2908                         s->solo_safe_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2909                         return 0;
2910                 }
2911         }
2912         return sel_fail ("solo_safe", 0, get_address (msg));
2913 }
2914
2915 int
2916 OSC::sel_recenable (uint32_t yn, lo_message msg)
2917 {
2918         OSCSurface *sur = get_surface(get_address (msg));
2919         boost::shared_ptr<Stripable> s;
2920         if (sur->expand_enable) {
2921                 s = get_strip (sur->expand, get_address (msg));
2922         } else {
2923                 s = _select;
2924         }
2925         if (s) {
2926                 if (s->rec_enable_control()) {
2927                         s->rec_enable_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2928                         if (s->rec_enable_control()->get_value()) {
2929                                 return 0;
2930                         }
2931                 }
2932         }
2933         return sel_fail ("recenable", 0, get_address (msg));
2934 }
2935
2936 int
2937 OSC::route_recenable (int ssid, int yn, lo_message msg)
2938 {
2939         if (!session) return -1;
2940         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
2941
2942         if (s) {
2943                 if (s->rec_enable_control()) {
2944                         s->rec_enable_control()->set_value (yn, PBD::Controllable::UseGroup);
2945                         if (s->rec_enable_control()->get_value()) {
2946                                 return 0;
2947                         }
2948                 }
2949         }
2950         return route_send_fail ("recenable", ssid, 0, get_address (msg));
2951 }
2952
2953 int
2954 OSC::route_rename(int ssid, char *newname, lo_message msg) {
2955     if (!session) {
2956         return -1;
2957     }
2958
2959     boost::shared_ptr<Stripable> s = get_strip(ssid, get_address(msg));
2960
2961     if (s) {
2962         s->set_name(std::string(newname));
2963     }
2964
2965     return 0;
2966 }
2967
2968 int
2969 OSC::sel_recsafe (uint32_t yn, lo_message msg)
2970 {
2971         OSCSurface *sur = get_surface(get_address (msg));
2972         boost::shared_ptr<Stripable> s;
2973         if (sur->expand_enable) {
2974                 s = get_strip (sur->expand, get_address (msg));
2975         } else {
2976                 s = _select;
2977         }
2978         if (s) {
2979                 if (s->rec_safe_control()) {
2980                         s->rec_safe_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
2981                         if (s->rec_safe_control()->get_value()) {
2982                                 return 0;
2983                         }
2984                 }
2985         }
2986         return sel_fail ("record_safe", 0, get_address (msg));
2987 }
2988
2989 int
2990 OSC::route_recsafe (int ssid, int yn, lo_message msg)
2991 {
2992         if (!session) return -1;
2993         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
2994         if (s) {
2995                 if (s->rec_safe_control()) {
2996                         s->rec_safe_control()->set_value (yn, PBD::Controllable::UseGroup);
2997                         if (s->rec_safe_control()->get_value()) {
2998                                 return 0;
2999                         }
3000                 }
3001         }
3002         return route_send_fail ("record_safe", ssid, 0,get_address (msg));
3003 }
3004
3005 int
3006 OSC::route_monitor_input (int ssid, int yn, lo_message msg)
3007 {
3008         if (!session) return -1;
3009         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3010
3011         if (s) {
3012                 boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (s);
3013                 if (track) {
3014                         if (track->monitoring_control()) {
3015                                 track->monitoring_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
3016                                 return 0;
3017                         }
3018                 }
3019         }
3020
3021         return route_send_fail ("monitor_input", ssid, 0, get_address (msg));
3022 }
3023
3024 int
3025 OSC::sel_monitor_input (uint32_t yn, lo_message msg)
3026 {
3027         OSCSurface *sur = get_surface(get_address (msg));
3028         boost::shared_ptr<Stripable> s;
3029         if (sur->expand_enable) {
3030                 s = get_strip (sur->expand, get_address (msg));
3031         } else {
3032                 s = _select;
3033         }
3034         if (s) {
3035                 boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (s);
3036                 if (track) {
3037                         if (track->monitoring_control()) {
3038                                 track->monitoring_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
3039                                 return 0;
3040                         }
3041                 }
3042         }
3043         return sel_fail ("monitor_input", 0, get_address (msg));
3044 }
3045
3046 int
3047 OSC::route_monitor_disk (int ssid, int yn, lo_message msg)
3048 {
3049         if (!session) return -1;
3050         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3051
3052         if (s) {
3053                 boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (s);
3054                 if (track) {
3055                         if (track->monitoring_control()) {
3056                                 track->monitoring_control()->set_value (yn ? 2.0 : 0.0, PBD::Controllable::NoGroup);
3057                                 return 0;
3058                         }
3059                 }
3060         }
3061
3062         return route_send_fail ("monitor_disk", ssid, 0, get_address (msg));
3063 }
3064
3065 int
3066 OSC::sel_monitor_disk (uint32_t yn, lo_message msg)
3067 {
3068         OSCSurface *sur = get_surface(get_address (msg));
3069         boost::shared_ptr<Stripable> s;
3070         if (sur->expand_enable) {
3071                 s = get_strip (sur->expand, get_address (msg));
3072         } else {
3073                 s = _select;
3074         }
3075         if (s) {
3076                 boost::shared_ptr<Track> track = boost::dynamic_pointer_cast<Track> (s);
3077                 if (track) {
3078                         if (track->monitoring_control()) {
3079                                 track->monitoring_control()->set_value (yn ? 2.0 : 0.0, PBD::Controllable::NoGroup);
3080                                 return 0;
3081                         }
3082                 }
3083         }
3084         return sel_fail ("monitor_disk", 0, get_address (msg));
3085 }
3086
3087
3088 int
3089 OSC::strip_phase (int ssid, int yn, lo_message msg)
3090 {
3091         if (!session) return -1;
3092         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3093
3094         if (s) {
3095                 if (s->phase_control()) {
3096                         s->phase_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
3097                         return 0;
3098                 }
3099         }
3100
3101         return route_send_fail ("polarity", ssid, 0, get_address (msg));
3102 }
3103
3104 int
3105 OSC::sel_phase (uint32_t yn, lo_message msg)
3106 {
3107         OSCSurface *sur = get_surface(get_address (msg));
3108         boost::shared_ptr<Stripable> s;
3109         if (sur->expand_enable) {
3110                 s = get_strip (sur->expand, get_address (msg));
3111         } else {
3112                 s = _select;
3113         }
3114         if (s) {
3115                 if (s->phase_control()) {
3116                         s->phase_control()->set_value (yn ? 1.0 : 0.0, PBD::Controllable::NoGroup);
3117                         return 0;
3118                 }
3119         }
3120         return sel_fail ("polarity", 0, get_address (msg));
3121 }
3122
3123 int
3124 OSC::strip_expand (int ssid, int yn, lo_message msg)
3125 {
3126         OSCSurface *sur = get_surface(get_address (msg));
3127         sur->expand_enable = (bool) yn;
3128         sur->expand = ssid;
3129         boost::shared_ptr<Stripable> s;
3130         if (yn) {
3131                 s = get_strip (ssid, get_address (msg));
3132         } else {
3133                 s = ControlProtocol::first_selected_stripable();
3134         }
3135
3136         return _strip_select (s, get_address (msg));
3137 }
3138
3139 int
3140 OSC::_strip_select (boost::shared_ptr<Stripable> s, lo_address addr)
3141 {
3142         if (!session) {
3143                 return -1;
3144         }
3145         OSCSurface *sur = get_surface(addr);
3146         if (sur->sel_obs) {
3147                 delete sur->sel_obs;
3148                 sur->sel_obs = 0;
3149         }
3150         bool feedback_on = sur->feedback.to_ulong();
3151         if (s && feedback_on) {
3152                 OSCSelectObserver* sel_fb = new OSCSelectObserver (s, addr, sur);
3153                 s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this);
3154                 sur->sel_obs = sel_fb;
3155         } else if (sur->expand_enable) {
3156                 // expand doesn't point to a stripable, turn it off and use select
3157                 sur->expand = 0;
3158                 sur->expand_enable = false;
3159                 if (_select && feedback_on) {
3160                         s = _select;
3161                         OSCSelectObserver* sel_fb = new OSCSelectObserver (s, addr, sur);
3162                         s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this);
3163                         sur->sel_obs = sel_fb;
3164                 }
3165         } else if (feedback_on) {
3166                 route_send_fail ("select", sur->expand, 0 , addr);
3167         }
3168         // need to set monitor for processor changed signal
3169         // detecting processor changes requires cast to route
3170         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(s);
3171         if (r) {
3172                 r->processors_changed.connect  (sur->proc_connection, MISSING_INVALIDATOR, boost::bind (&OSC::processor_changed, this, addr), this);
3173                 processor_changed (addr);
3174         }
3175
3176         if (!feedback_on) {
3177                 return 0;
3178         }
3179         //update buttons on surface
3180         int b_s = sur->bank_size;
3181         if (!b_s) { // bank size 0 means we need to know how many strips there are.
3182                 b_s = sur->nstrips;
3183         }
3184         for (int i = 1;  i <= b_s; i++) {
3185                 string path = "expand";
3186
3187                 if ((i == (int) sur->expand) && sur->expand_enable) {
3188                         lo_message reply = lo_message_new ();
3189                         if (sur->feedback[2]) {
3190                                 ostringstream os;
3191                                 os << "/strip/" << path << "/" << i;
3192                                 path = os.str();
3193                         } else {
3194                                 ostringstream os;
3195                                 os << "/strip/" << path;
3196                                 path = os.str();
3197                                 lo_message_add_int32 (reply, i);
3198                         }
3199                         lo_message_add_float (reply, (float) 1);
3200
3201                         lo_send_message (addr, path.c_str(), reply);
3202                         lo_message_free (reply);
3203                         reply = lo_message_new ();
3204                         lo_message_add_float (reply, 1.0);
3205                         lo_send_message (addr, "/select/expand", reply);
3206                         lo_message_free (reply);
3207
3208                 } else {
3209                         lo_message reply = lo_message_new ();
3210                         lo_message_add_int32 (reply, i);
3211                         lo_message_add_float (reply, 0.0);
3212                         lo_send_message (addr, "/strip/expand", reply);
3213                         lo_message_free (reply);
3214                 }
3215         }
3216         if (!sur->expand_enable) {
3217                 lo_message reply = lo_message_new ();
3218                 lo_message_add_float (reply, 0.0);
3219                 lo_send_message (addr, "/select/expand", reply);
3220                 lo_message_free (reply);
3221         }
3222
3223         return 0;
3224 }
3225
3226 void
3227 OSC::processor_changed (lo_address addr)
3228 {
3229         OSCSurface *sur = get_surface (addr);
3230         sur->proc_connection.disconnect ();
3231         _sel_plugin (sur->plugin_id, addr);
3232         if (sur->sel_obs) {
3233                 sur->sel_obs->renew_sends ();
3234                 sur->sel_obs->eq_restart (-1);
3235         }
3236 }
3237
3238 int
3239 OSC::strip_gui_select (int ssid, int yn, lo_message msg)
3240 {
3241         //ignore button release
3242         if (!yn) return 0;
3243
3244         if (!session) {
3245                 return -1;
3246         }
3247         OSCSurface *sur = get_surface(get_address (msg));
3248         sur->expand_enable = false;
3249         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3250         if (s) {
3251                 SetStripableSelection (s);
3252         } else {
3253                 if ((int) (sur->feedback.to_ulong())) {
3254                         route_send_fail ("select", ssid, 0, get_address (msg));
3255                 }
3256         }
3257
3258         return 0;
3259 }
3260
3261 int
3262 OSC::sel_expand (uint32_t state, lo_message msg)
3263 {
3264         OSCSurface *sur = get_surface(get_address (msg));
3265         boost::shared_ptr<Stripable> s;
3266         sur->expand_enable = (bool) state;
3267         if (state && sur->expand) {
3268                 s = get_strip (sur->expand, get_address (msg));
3269         } else {
3270                 s = ControlProtocol::first_selected_stripable();
3271         }
3272
3273         return _strip_select (s, get_address (msg));
3274 }
3275
3276 int
3277 OSC::route_set_gain_abs (int ssid, float level, lo_message msg)
3278 {
3279         if (!session) return -1;
3280         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3281
3282         if (s) {
3283                 if (s->gain_control()) {
3284                         fake_touch (s->gain_control());
3285                         s->gain_control()->set_value (level, PBD::Controllable::NoGroup);
3286                 } else {
3287                         return 1;
3288                 }
3289         } else {
3290                 return 1;
3291         }
3292
3293         return 0;
3294 }
3295
3296 int
3297 OSC::route_set_gain_dB (int ssid, float dB, lo_message msg)
3298 {
3299         if (!session) {
3300                 route_send_fail ("gain", ssid, -193, get_address (msg));
3301                 return -1;
3302         }
3303         int ret;
3304         if (dB < -192) {
3305                 ret = route_set_gain_abs (ssid, 0.0, msg);
3306         } else {
3307                 ret = route_set_gain_abs (ssid, dB_to_coefficient (dB), msg);
3308         }
3309         if (ret != 0) {
3310                 return route_send_fail ("gain", ssid, -193, get_address (msg));
3311         }
3312         return 0;
3313 }
3314
3315 int
3316 OSC::sel_gain (float val, lo_message msg)
3317 {
3318         OSCSurface *sur = get_surface(get_address (msg));
3319         boost::shared_ptr<Stripable> s;
3320         if (sur->expand_enable) {
3321                 s = get_strip (sur->expand, get_address (msg));
3322         } else {
3323                 s = _select;
3324         }
3325         if (s) {
3326                 float abs;
3327                 if (val < -192) {
3328                         abs = 0;
3329                 } else {
3330                         abs = dB_to_coefficient (val);
3331                 }
3332                 if (s->gain_control()) {
3333                         fake_touch (s->gain_control());
3334                         s->gain_control()->set_value (abs, PBD::Controllable::NoGroup);
3335                         return 0;
3336                 }
3337         }
3338         return sel_fail ("gain", -193, get_address (msg));
3339 }
3340
3341 int
3342 OSC::route_set_gain_fader (int ssid, float pos, lo_message msg)
3343 {
3344         if (!session) {
3345                 return -1;
3346         }
3347         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3348
3349         if (s) {
3350                 if (s->gain_control()) {
3351                         fake_touch (s->gain_control());
3352                         s->gain_control()->set_value (s->gain_control()->interface_to_internal (pos), PBD::Controllable::NoGroup);
3353                 } else {
3354                         return route_send_fail ("fader", ssid, 0, get_address (msg));
3355                 }
3356         } else {
3357                 return route_send_fail ("fader", ssid, 0, get_address (msg));
3358         }
3359         return 0;
3360 }
3361
3362 int
3363 OSC::strip_db_delta (int ssid, float delta, lo_message msg)
3364 {
3365         if (!session) return -1;
3366         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3367         if (s) {
3368                 float db = accurate_coefficient_to_dB (s->gain_control()->get_value()) + delta;
3369                 float abs;
3370                 if (db < -192) {
3371                         abs = 0;
3372                 } else {
3373                         abs = dB_to_coefficient (db);
3374                 }
3375                 s->gain_control()->set_value (abs, PBD::Controllable::NoGroup);
3376                 return 0;
3377         }
3378         return -1;
3379 }
3380
3381 int
3382 OSC::sel_fader (float val, lo_message msg)
3383 {
3384         OSCSurface *sur = get_surface(get_address (msg));
3385         boost::shared_ptr<Stripable> s;
3386         if (sur->expand_enable) {
3387                 s = get_strip (sur->expand, get_address (msg));
3388         } else {
3389                 s = _select;
3390         }
3391         if (s) {
3392                 if (s->gain_control()) {
3393                         fake_touch (s->gain_control());
3394                         s->gain_control()->set_value (s->gain_control()->interface_to_internal (val), PBD::Controllable::NoGroup);
3395                         return 0;
3396                 }
3397         }
3398         return sel_fail ("fader", 0, get_address (msg));
3399 }
3400
3401 int
3402 OSC::route_set_trim_abs (int ssid, float level, lo_message msg)
3403 {
3404         if (!session) return -1;
3405         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3406
3407         if (s) {
3408                 if (s->trim_control()) {
3409                         s->trim_control()->set_value (level, PBD::Controllable::NoGroup);
3410                         return 0;
3411                 }
3412
3413         }
3414
3415         return -1;
3416 }
3417
3418 int
3419 OSC::route_set_trim_dB (int ssid, float dB, lo_message msg)
3420 {
3421         int ret;
3422         ret = route_set_trim_abs(ssid, dB_to_coefficient (dB), msg);
3423         if (ret != 0) {
3424                 return route_send_fail ("trimdB", ssid, 0, get_address (msg));
3425         }
3426
3427 return 0;
3428 }
3429
3430 int
3431 OSC::sel_trim (float val, lo_message msg)
3432 {
3433         OSCSurface *sur = get_surface(get_address (msg));
3434         boost::shared_ptr<Stripable> s;
3435         if (sur->expand_enable) {
3436                 s = get_strip (sur->expand, get_address (msg));
3437         } else {
3438                 s = _select;
3439         }
3440         if (s) {
3441                 if (s->trim_control()) {
3442                         s->trim_control()->set_value (dB_to_coefficient (val), PBD::Controllable::NoGroup);
3443                         return 0;
3444                 }
3445         }
3446         return sel_fail ("trimdB", 0, get_address (msg));
3447 }
3448
3449 int
3450 OSC::sel_pan_position (float val, lo_message msg)
3451 {
3452         OSCSurface *sur = get_surface(get_address (msg));
3453         boost::shared_ptr<Stripable> s;
3454         if (sur->expand_enable) {
3455                 s = get_strip (sur->expand, get_address (msg));
3456         } else {
3457                 s = _select;
3458         }
3459         if (s) {
3460                 if(s->pan_azimuth_control()) {
3461                         s->pan_azimuth_control()->set_value (s->pan_azimuth_control()->interface_to_internal (val), PBD::Controllable::NoGroup);
3462                         return 0;
3463                 }
3464         }
3465         return sel_fail ("pan_stereo_position", 0.5, get_address (msg));
3466 }
3467
3468 int
3469 OSC::sel_pan_width (float val, lo_message msg)
3470 {
3471         OSCSurface *sur = get_surface(get_address (msg));
3472         boost::shared_ptr<Stripable> s;
3473         if (sur->expand_enable) {
3474                 s = get_strip (sur->expand, get_address (msg));
3475         } else {
3476                 s = _select;
3477         }
3478         if (s) {
3479                 if (s->pan_width_control()) {
3480                         s->pan_width_control()->set_value (s->pan_width_control()->interface_to_internal (val), PBD::Controllable::NoGroup);
3481                         return 0;
3482                 }
3483         }
3484         return sel_fail ("pan_stereo_width", 1, get_address (msg));
3485 }
3486
3487 int
3488 OSC::route_set_pan_stereo_position (int ssid, float pos, lo_message msg)
3489 {
3490         if (!session) return -1;
3491         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3492
3493         if (s) {
3494                 if(s->pan_azimuth_control()) {
3495                         s->pan_azimuth_control()->set_value (s->pan_azimuth_control()->interface_to_internal (pos), PBD::Controllable::NoGroup);
3496                         return 0;
3497                 }
3498         }
3499
3500         return route_send_fail ("pan_stereo_position", ssid, 0.5, get_address (msg));
3501 }
3502
3503 int
3504 OSC::route_set_pan_stereo_width (int ssid, float pos, lo_message msg)
3505 {
3506         if (!session) return -1;
3507         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3508
3509         if (s) {
3510                 if (s->pan_width_control()) {
3511                         s->pan_width_control()->set_value (pos, PBD::Controllable::NoGroup);
3512                         return 0;
3513                 }
3514         }
3515
3516         return route_send_fail ("pan_stereo_width", ssid, 1, get_address (msg));
3517 }
3518
3519 int
3520 OSC::route_set_send_gain_dB (int ssid, int id, float val, lo_message msg)
3521 {
3522         if (!session) {
3523                 return -1;
3524         }
3525         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3526         float abs;
3527         if (s) {
3528                 if (id > 0) {
3529                         --id;
3530                 }
3531 #ifdef MIXBUS
3532                 abs = val;
3533 #else
3534                 if (val < -192) {
3535                         abs = 0;
3536                 } else {
3537                         abs = dB_to_coefficient (val);
3538                 }
3539 #endif
3540                 if (s->send_level_controllable (id)) {
3541                         s->send_level_controllable (id)->set_value (abs, PBD::Controllable::NoGroup);
3542                         return 0;
3543                 }
3544         }
3545         return 0;
3546 }
3547
3548 int
3549 OSC::route_set_send_fader (int ssid, int id, float val, lo_message msg)
3550 {
3551         if (!session) {
3552                 return -1;
3553         }
3554         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3555         float abs;
3556         if (s) {
3557
3558                 if (id > 0) {
3559                         --id;
3560                 }
3561
3562                 if (s->send_level_controllable (id)) {
3563                         abs = s->send_level_controllable(id)->interface_to_internal (val);
3564                         s->send_level_controllable (id)->set_value (abs, PBD::Controllable::NoGroup);
3565                         return 0;
3566                 }
3567         }
3568         return 0;
3569 }
3570
3571 int
3572 OSC::sel_sendgain (int id, float val, lo_message msg)
3573 {
3574         OSCSurface *sur = get_surface(get_address (msg));
3575         if (sur->send_page_size && (id > (int)sur->send_page_size)) {
3576                 return sel_send_fail ("send_gain", id, -193, get_address (msg));
3577         }
3578         boost::shared_ptr<Stripable> s;
3579         if (sur->expand_enable) {
3580                 s = get_strip (sur->expand, get_address (msg));
3581         } else {
3582                 s = _select;
3583         }
3584         float abs;
3585         int send_id;
3586         if (s) {
3587                 if (id > 0) {
3588                         send_id = id - 1;
3589                 }
3590 #ifdef MIXBUS
3591                 abs = val;
3592 #else
3593                 if (val < -192) {
3594                         abs = 0;
3595                 } else {
3596                         abs = dB_to_coefficient (val);
3597                 }
3598 #endif
3599                 if (sur->send_page_size) {
3600                         send_id = send_id + ((sur->send_page - 1) * sur->send_page_size);
3601                 }
3602                 if (s->send_level_controllable (send_id)) {
3603                         s->send_level_controllable (send_id)->set_value (abs, PBD::Controllable::NoGroup);
3604                         return 0;
3605                 }
3606         }
3607         return sel_send_fail ("send_gain", id, -193, get_address (msg));
3608 }
3609
3610 int
3611 OSC::sel_sendfader (int id, float val, lo_message msg)
3612 {
3613         OSCSurface *sur = get_surface(get_address (msg));
3614         if (sur->send_page_size && (id > (int)sur->send_page_size)) {
3615                 return sel_send_fail ("send_fader", id, 0, get_address (msg));
3616         }
3617         boost::shared_ptr<Stripable> s;
3618         if (sur->expand_enable) {
3619                 s = get_strip (sur->expand, get_address (msg));
3620         } else {
3621                 s = _select;
3622         }
3623         float abs;
3624         int send_id;
3625         if (s) {
3626
3627                 if (id > 0) {
3628                         send_id = id - 1;
3629                 }
3630                 if (sur->send_page_size) {
3631                         send_id = send_id + ((sur->send_page - 1) * sur->send_page_size);
3632                 }
3633
3634                 if (s->send_level_controllable (send_id)) {
3635                         abs = s->send_level_controllable(send_id)->interface_to_internal (val);
3636                         s->send_level_controllable (send_id)->set_value (abs, PBD::Controllable::NoGroup);
3637                         return 0;
3638                 }
3639         }
3640         return sel_send_fail ("send_fader", id, 0, get_address (msg));
3641 }
3642
3643 int
3644 OSC::route_set_send_enable (int ssid, int sid, float val, lo_message msg)
3645 {
3646         if (!session) {
3647                 return -1;
3648         }
3649         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
3650
3651         if (s) {
3652
3653                 /* revert to zero-based counting */
3654
3655                 if (sid > 0) {
3656                         --sid;
3657                 }
3658
3659                 if (s->send_enable_controllable (sid)) {
3660                         s->send_enable_controllable (sid)->set_value (val, PBD::Controllable::NoGroup);
3661                         return 0;
3662                 }
3663
3664                 if (s->send_level_controllable (sid)) {
3665                         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
3666                         if (!r) {
3667                                 return 0;
3668                         }
3669                         boost::shared_ptr<Send> snd = boost::dynamic_pointer_cast<Send> (r->nth_send(sid));
3670                         if (snd) {
3671                                 if (val) {
3672                                         snd->activate();
3673                                 } else {
3674                                         snd->deactivate();
3675                                 }
3676                         }
3677                         return 0;
3678                 }
3679
3680         }
3681
3682         return -1;
3683 }
3684
3685 int
3686 OSC::sel_sendenable (int id, float val, lo_message msg)
3687 {
3688         OSCSurface *sur = get_surface(get_address (msg));
3689         if (sur->send_page_size && (id > (int)sur->send_page_size)) {
3690                 return sel_send_fail ("send_enable", id, 0, get_address (msg));
3691         }
3692         boost::shared_ptr<Stripable> s;
3693         if (sur->expand_enable) {
3694                 s = get_strip (sur->expand, get_address (msg));
3695         } else {
3696                 s = _select;
3697         }
3698         int send_id;
3699         if (s) {
3700                 if (id > 0) {
3701                         send_id = id - 1;
3702                 }
3703                 if (sur->send_page_size) {
3704                         send_id = send_id + ((sur->send_page - 1) * sur->send_page_size);
3705                 }
3706                 if (s->send_enable_controllable (send_id)) {
3707                         s->send_enable_controllable (send_id)->set_value (val, PBD::Controllable::NoGroup);
3708                         return 0;
3709                 }
3710                 if (s->send_level_controllable (send_id)) {
3711                         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
3712                         if (!r) {
3713                                 // should never get here
3714                                 return sel_send_fail ("send_enable", id, 0, get_address (msg));
3715                         }
3716                         boost::shared_ptr<Send> snd = boost::dynamic_pointer_cast<Send> (r->nth_send(send_id));
3717                         if (snd) {
3718                                 if (val) {
3719                                         snd->activate();
3720                                 } else {
3721                                         snd->deactivate();
3722                                 }
3723                         }
3724                         return 0;
3725                 }
3726         }
3727         return sel_send_fail ("send_enable", id, 0, get_address (msg));
3728 }
3729
3730 int
3731 OSC::sel_master_send_enable (int state, lo_message msg)
3732 {
3733         OSCSurface *sur = get_surface(get_address (msg));
3734         boost::shared_ptr<Stripable> s;
3735         if (sur->expand_enable) {
3736                 s = get_strip (sur->expand, get_address (msg));
3737         } else {
3738                 s = _select;
3739         }
3740         if (s) {
3741                 if (s->master_send_enable_controllable ()) {
3742                         s->master_send_enable_controllable()->set_value (state, PBD::Controllable::NoGroup);
3743                         return 0;
3744                 }
3745         }
3746         return cue_float_message ("/select/master_send_enable", 0, get_address(msg));
3747 }
3748
3749 int
3750 OSC::select_plugin_parameter (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg) {
3751         OSCSurface *sur = get_surface(get_address (msg));
3752         int paid;
3753         int piid = sur->plugin_id;
3754         float value = 0;
3755         if (argc > 1) {
3756                 // no inline args
3757                 if (argc == 2) {
3758                         // change parameter in already selected plugin
3759                         if (argv[0]->f) {
3760                                 paid = (int) argv[0]->f;
3761                         } else {
3762                                 paid = argv[0]->i;
3763                         }
3764                         value = argv[1]->f;
3765                 } else if (argc == 3) {
3766                         if (argv[0]->f) {
3767                                 piid = (int) argv[0]->f;
3768                         } else {
3769                                 piid = argv[0]->i;
3770                         }
3771                         _sel_plugin (piid, get_address (msg));
3772                         if (argv[1]->f) {
3773                                 paid = (int) argv[1]->f;
3774                         } else {
3775                                 paid = argv[1]->i;
3776                         }
3777                         value = argv[2]->f;
3778                 } else if (argc > 3) {
3779                         PBD::warning << "OSC: Too many parameters: " << argc << endmsg;
3780                         return -1;
3781                 }
3782         } else if (argc) {
3783                 const char * par = strstr (&path[25], "/");
3784                 if (par) {
3785                         piid = atoi (&path[25]);
3786                         _sel_plugin (piid, msg);
3787                         paid = atoi (&par[1]);
3788                         value = argv[0]->f;
3789                         // we have plugin id too
3790                 } else {
3791                         // just parameter
3792                         paid = atoi (&path[25]);
3793                         value = argv[0]->f;
3794                 }
3795         } else {
3796                 PBD::warning << "OSC: Must have parameters." << endmsg;
3797                 return -1;
3798         }
3799         if (piid != sur->plugin_id) {
3800                 // if the user is sending to a non-existant plugin, don't adjust one we do have
3801                 PBD::warning << "OSC: plugin: " << piid << " out of range" << endmsg;
3802                 return -1;
3803         }
3804         if (sur->plug_page_size && (paid > (int)sur->plug_page_size)) {
3805                 return sel_send_fail ("plugin/parameter", paid, 0, get_address (msg));
3806         }
3807         boost::shared_ptr<Stripable> s;
3808         if (sur->expand_enable) {
3809                 s = get_strip (sur->expand, get_address (msg));
3810         } else {
3811                 s = _select;
3812         }
3813         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(s);
3814         if (!r) {
3815                 return 1;
3816         }
3817
3818         boost::shared_ptr<Processor> proc = r->nth_plugin (sur->plugins[sur->plugin_id - 1]);
3819         boost::shared_ptr<PluginInsert> pi;
3820         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(proc))) {
3821                 return 1;
3822         }
3823         boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
3824         // paid is paged parameter convert to absolute
3825         int parid = paid + (int)(sur->plug_page_size * (sur->plug_page - 1));
3826         if (parid > (int) sur->plug_params.size ()) {
3827                 if (sur->feedback[13]) {
3828                         sel_send_fail ("plugin/parameter", paid, 0, get_address (msg));
3829                 }
3830                 return 0;
3831         }
3832
3833         bool ok = false;
3834         uint32_t controlid = pip->nth_parameter(sur->plug_params[parid - 1], ok);
3835         if (!ok) {
3836                 return 1;
3837         }
3838         ParameterDescriptor pd;
3839         pip->get_parameter_descriptor(controlid, pd);
3840         if ( pip->parameter_is_input(controlid) || pip->parameter_is_control(controlid) ) {
3841                 boost::shared_ptr<AutomationControl> c = pi->automation_control(Evoral::Parameter(PluginAutomation, 0, controlid));
3842                 if (c) {
3843                         if (pd.integer_step && pd.upper == 1) {
3844                                 if (c->get_value () && value < 1.0) {
3845                                         c->set_value (0, PBD::Controllable::NoGroup);
3846                                 } else if (!c->get_value () && value) {
3847                                         c->set_value (1, PBD::Controllable::NoGroup);
3848                                 }
3849                         } else {
3850                                 c->set_value (c->interface_to_internal (value), PBD::Controllable::NoGroup);
3851                         }
3852                         return 0;
3853                 }
3854         }
3855         return 1;
3856 }
3857
3858 int
3859 OSC::route_plugin_list (int ssid, lo_message msg) {
3860         if (!session) {
3861                 return -1;
3862         }
3863
3864         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(get_strip (ssid, get_address (msg)));
3865
3866         if (!r) {
3867                 PBD::error << "OSC: Invalid Remote Control ID '" << ssid << "'" << endmsg;
3868                 return -1;
3869         }
3870         int piid = 0;
3871
3872         lo_message reply = lo_message_new ();
3873         lo_message_add_int32 (reply, ssid);
3874
3875
3876         for (;;) {
3877                 boost::shared_ptr<Processor> redi = r->nth_plugin(piid);
3878                 if ( !redi ) {
3879                         break;
3880                 }
3881
3882                 boost::shared_ptr<PluginInsert> pi;
3883
3884                 if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
3885                         PBD::error << "OSC: given processor # " << piid << " on RID '" << ssid << "' is not a Plugin." << endmsg;
3886                         continue;
3887                 }
3888                 lo_message_add_int32 (reply, piid + 1);
3889
3890                 boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
3891                 lo_message_add_string (reply, pip->name());
3892
3893                 piid++;
3894         }
3895
3896         lo_send_message (get_address (msg), "/strip/plugin/list", reply);
3897         lo_message_free (reply);
3898         return 0;
3899 }
3900
3901 int
3902 OSC::route_plugin_descriptor (int ssid, int piid, lo_message msg) {
3903         if (!session) {
3904                 return -1;
3905         }
3906
3907         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(get_strip (ssid, get_address (msg)));
3908
3909         if (!r) {
3910                 PBD::error << "OSC: Invalid Remote Control ID '" << ssid << "'" << endmsg;
3911                 return -1;
3912         }
3913
3914         boost::shared_ptr<Processor> redi = r->nth_plugin(piid - 1);
3915
3916         if (!redi) {
3917                 PBD::error << "OSC: cannot find plugin # " << piid << " for RID '" << ssid << "'" << endmsg;
3918                 return -1;
3919         }
3920
3921         boost::shared_ptr<PluginInsert> pi;
3922
3923         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
3924                 PBD::error << "OSC: given processor # " << piid << " on RID '" << ssid << "' is not a Plugin." << endmsg;
3925                 return -1;
3926         }
3927
3928         boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
3929         bool ok = false;
3930
3931         lo_message reply = lo_message_new();
3932         lo_message_add_int32 (reply, ssid);
3933         lo_message_add_int32 (reply, piid);
3934         lo_message_add_string (reply, pip->name());
3935         for ( uint32_t ppi = 0; ppi < pip->parameter_count(); ppi++) {
3936
3937                 uint32_t controlid = pip->nth_parameter(ppi, ok);
3938                 if (!ok) {
3939                         continue;
3940                 }
3941                 if ( pip->parameter_is_input(controlid) || pip->parameter_is_control(controlid) ) {
3942                         boost::shared_ptr<AutomationControl> c = pi->automation_control(Evoral::Parameter(PluginAutomation, 0, controlid));
3943
3944                                 lo_message_add_int32 (reply, ppi + 1);
3945                                 ParameterDescriptor pd;
3946                                 pi->plugin()->get_parameter_descriptor(controlid, pd);
3947                                 lo_message_add_string (reply, pd.label.c_str());
3948
3949                                 // I've combined those binary descriptor parts in a bit-field to reduce lilo message elements
3950                                 int flags = 0;
3951                                 flags |= pd.enumeration ? 1 : 0;
3952                                 flags |= pd.integer_step ? 2 : 0;
3953                                 flags |= pd.logarithmic ? 4 : 0;
3954                                 flags |= pd.sr_dependent ? 32 : 0;
3955                                 flags |= pd.toggled ? 64 : 0;
3956                                 flags |= c != NULL ? 128 : 0; // bit 7 indicates in input control
3957                                 lo_message_add_int32 (reply, flags);
3958
3959                                 lo_message_add_int32 (reply, pd.datatype);
3960                                 lo_message_add_float (reply, pd.lower);
3961                                 lo_message_add_float (reply, pd.upper);
3962                                 lo_message_add_string (reply, pd.print_fmt.c_str());
3963                                 if ( pd.scale_points ) {
3964                                         lo_message_add_int32 (reply, pd.scale_points->size());
3965                                         for ( ARDOUR::ScalePoints::const_iterator i = pd.scale_points->begin(); i != pd.scale_points->end(); ++i) {
3966                                                 lo_message_add_int32 (reply, i->second);
3967                                                 lo_message_add_string (reply, ((std::string)i->first).c_str());
3968                                         }
3969                                 }
3970                                 else {
3971                                         lo_message_add_int32 (reply, 0);
3972                                 }
3973                                 if ( c ) {
3974                                         lo_message_add_double (reply, c->get_value());
3975                                 }
3976                                 else {
3977                                         lo_message_add_double (reply, 0);
3978                         }
3979                 }
3980         }
3981
3982         lo_send_message (get_address (msg), "/strip/plugin/descriptor", reply);
3983         lo_message_free (reply);
3984
3985         return 0;
3986 }
3987
3988 int
3989 OSC::route_plugin_reset (int ssid, int piid, lo_message msg) {
3990         if (!session) {
3991                 return -1;
3992         }
3993
3994         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(get_strip (ssid, get_address (msg)));
3995
3996         if (!r) {
3997                 PBD::error << "OSC: Invalid Remote Control ID '" << ssid << "'" << endmsg;
3998                 return -1;
3999         }
4000
4001         boost::shared_ptr<Processor> redi = r->nth_plugin(piid - 1);
4002
4003         if (!redi) {
4004                 PBD::error << "OSC: cannot find plugin # " << piid << " for RID '" << ssid << "'" << endmsg;
4005                 return -1;
4006         }
4007
4008         boost::shared_ptr<PluginInsert> pi;
4009
4010         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
4011                 PBD::error << "OSC: given processor # " << piid << " on RID '" << ssid << "' is not a Plugin." << endmsg;
4012                 return -1;
4013         }
4014
4015         pi->reset_parameters_to_default ();
4016
4017         return 0;
4018 }
4019
4020 int
4021 OSC::route_plugin_parameter (int ssid, int piid, int par, float val, lo_message msg)
4022 {
4023         if (!session)
4024                 return -1;
4025         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
4026
4027         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
4028
4029         if (!r) {
4030                 PBD::error << "OSC: Invalid Remote Control ID '" << ssid << "'" << endmsg;
4031                 return -1;
4032         }
4033
4034         boost::shared_ptr<Processor> redi=r->nth_plugin (piid - 1);
4035
4036         if (!redi) {
4037                 PBD::error << "OSC: cannot find plugin # " << piid << " for RID '" << ssid << "'" << endmsg;
4038                 return -1;
4039         }
4040
4041         boost::shared_ptr<PluginInsert> pi;
4042
4043         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
4044                 PBD::error << "OSC: given processor # " << piid << " on RID '" << ssid << "' is not a Plugin." << endmsg;
4045                 return -1;
4046         }
4047
4048         boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
4049         bool ok=false;
4050
4051         uint32_t controlid = pip->nth_parameter (par - 1,ok);
4052
4053         if (!ok) {
4054                 PBD::error << "OSC: Cannot find parameter # " << par <<  " for plugin # " << piid << " on RID '" << ssid << "'" << endmsg;
4055                 return -1;
4056         }
4057
4058         if (!pip->parameter_is_input(controlid)) {
4059                 PBD::error << "OSC: Parameter # " << par <<  " for plugin # " << piid << " on RID '" << ssid << "' is not a control input" << endmsg;
4060                 return -1;
4061         }
4062
4063         ParameterDescriptor pd;
4064         pi->plugin()->get_parameter_descriptor (controlid,pd);
4065
4066         if (val >= pd.lower && val <= pd.upper) {
4067
4068                 boost::shared_ptr<AutomationControl> c = pi->automation_control (Evoral::Parameter(PluginAutomation, 0, controlid));
4069                 // cerr << "parameter:" << redi->describe_parameter(controlid) << " val:" << val << "\n";
4070                 c->set_value (val, PBD::Controllable::NoGroup);
4071         } else {
4072                 PBD::warning << "OSC: Parameter # " << par <<  " for plugin # " << piid << " on RID '" << ssid << "' is out of range" << endmsg;
4073                 PBD::info << "OSC: Valid range min=" << pd.lower << " max=" << pd.upper << endmsg;
4074         }
4075
4076         return 0;
4077 }
4078
4079 //prints to cerr only
4080 int
4081 OSC::route_plugin_parameter_print (int ssid, int piid, int par, lo_message msg)
4082 {
4083         if (!session) {
4084                 return -1;
4085         }
4086         boost::shared_ptr<Stripable> s = get_strip (ssid, get_address (msg));
4087
4088         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
4089
4090         if (!r) {
4091                 return -1;
4092         }
4093
4094         boost::shared_ptr<Processor> redi=r->nth_plugin (piid - 1);
4095
4096         if (!redi) {
4097                 return -1;
4098         }
4099
4100         boost::shared_ptr<PluginInsert> pi;
4101
4102         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
4103                 return -1;
4104         }
4105
4106         boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
4107         bool ok=false;
4108
4109         uint32_t controlid = pip->nth_parameter (par - 1,ok);
4110
4111         if (!ok) {
4112                 return -1;
4113         }
4114
4115         ParameterDescriptor pd;
4116
4117         if (pi->plugin()->get_parameter_descriptor (controlid, pd) == 0) {
4118                 boost::shared_ptr<AutomationControl> c = pi->automation_control (Evoral::Parameter(PluginAutomation, 0, controlid));
4119
4120                 cerr << "parameter:     " << pd.label  << "\n";
4121                 if (c) {
4122                         cerr << "current value: " << c->get_value () << "\n";
4123                 } else {
4124                         cerr << "current value not available, control does not exist\n";
4125                 }
4126                 cerr << "lower value:   " << pd.lower << "\n";
4127                 cerr << "upper value:   " << pd.upper << "\n";
4128         }
4129
4130         return 0;
4131 }
4132
4133 int
4134 OSC::route_plugin_activate (int ssid, int piid, lo_message msg)
4135 {
4136         if (!session)
4137                 return -1;
4138         boost::shared_ptr<Stripable> s = get_strip (ssid, lo_message_get_source (msg));
4139
4140         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
4141
4142         if (!r) {
4143                 PBD::error << "OSC: Invalid Remote Control ID '" << ssid << "'" << endmsg;
4144                 return -1;
4145         }
4146
4147         boost::shared_ptr<Processor> redi=r->nth_plugin (piid - 1);
4148
4149         if (!redi) {
4150                 PBD::error << "OSC: cannot find plugin # " << piid << " for RID '" << ssid << "'" << endmsg;
4151                 return -1;
4152         }
4153
4154         boost::shared_ptr<PluginInsert> pi;
4155
4156         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
4157                 PBD::error << "OSC: given processor # " << piid << " on RID '" << ssid << "' is not a Plugin." << endmsg;
4158                 return -1;
4159         }
4160
4161         boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
4162         pi->activate();
4163
4164         return 0;
4165 }
4166
4167 int
4168 OSC::route_plugin_deactivate (int ssid, int piid, lo_message msg)
4169 {
4170         if (!session)
4171                 return -1;
4172         boost::shared_ptr<Stripable> s = get_strip (ssid, lo_message_get_source (msg));
4173
4174         boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
4175
4176         if (!r) {
4177                 PBD::error << "OSC: Invalid Remote Control ID '" << ssid << "'" << endmsg;
4178                 return -1;
4179         }
4180
4181         boost::shared_ptr<Processor> redi=r->nth_plugin (piid - 1);
4182
4183         if (!redi) {
4184                 PBD::error << "OSC: cannot find plugin # " << piid << " for RID '" << ssid << "'" << endmsg;
4185                 return -1;
4186         }
4187
4188         boost::shared_ptr<PluginInsert> pi;
4189
4190         if (!(pi = boost::dynamic_pointer_cast<PluginInsert>(redi))) {
4191                 PBD::error << "OSC: given processor # " << piid << " on RID '" << ssid << "' is not a Plugin." << endmsg;
4192                 return -1;
4193         }
4194
4195         boost::shared_ptr<ARDOUR::Plugin> pip = pi->plugin();
4196         pi->deactivate();
4197
4198         return 0;
4199 }
4200
4201 // select
4202
4203 int
4204 OSC::sel_pan_elevation (float val, lo_message msg)
4205 {
4206         OSCSurface *sur = get_surface(get_address (msg));
4207         boost::shared_ptr<Stripable> s;
4208         if (sur->expand_enable) {
4209                 s = get_strip (sur->expand, get_address (msg));
4210         } else {
4211                 s = _select;
4212         }
4213         if (s) {
4214                 if (s->pan_elevation_control()) {
4215                         s->pan_elevation_control()->set_value (s->pan_elevation_control()->interface_to_internal (val), PBD::Controllable::NoGroup);
4216                         return 0;
4217                 }
4218         }
4219         return sel_fail ("pan_elevation_position", 0, get_address (msg));
4220 }
4221
4222 int
4223 OSC::sel_pan_frontback (float val, lo_message msg)
4224 {
4225         OSCSurface *sur = get_surface(get_address (msg));
4226         boost::shared_ptr<Stripable> s;
4227         if (sur->expand_enable) {
4228                 s = get_strip (sur->expand, get_address (msg));
4229         } else {
4230                 s = _select;
4231         }
4232         if (s) {
4233                 if (s->pan_frontback_control()) {
4234                         s->pan_frontback_control()->set_value (s->pan_frontback_control()->interface_to_internal (val), PBD::Controllable::NoGroup);
4235                         return 0;
4236                 }
4237         }
4238         return sel_fail ("pan_frontback_position", 0.5, get_address (msg));
4239 }
4240
4241 int
4242 OSC::sel_pan_lfe (float val, lo_message msg)
4243 {
4244         OSCSurface *sur = get_surface(get_address (msg));
4245         boost::shared_ptr<Stripable> s;
4246         if (sur->expand_enable) {
4247                 s = get_strip (sur->expand, get_address (msg));
4248         } else {
4249                 s = _select;
4250         }
4251         if (s) {
4252                 if (s->pan_lfe_control()) {
4253                         s->pan_lfe_control()->set_value (s->pan_lfe_control()->interface_to_internal (val), PBD::Controllable::NoGroup);
4254                         return 0;
4255                 }
4256         }
4257         return sel_fail ("pan_lfe_control", 0, get_address (msg));
4258 }
4259
4260 // compressor control
4261 int
4262 OSC::sel_comp_enable (float val, lo_message msg)
4263 {
4264         OSCSurface *sur = get_surface(get_address (msg));
4265         boost::shared_ptr<Stripable> s;
4266         if (sur->expand_enable) {
4267                 s = get_strip (sur->expand, get_address (msg));
4268         } else {
4269                 s = _select;
4270         }
4271         if (s) {
4272                 if (s->comp_enable_controllable()) {
4273                         s->comp_enable_controllable()->set_value (s->comp_enable_controllable()->interface_to_internal (val), PBD::Controllable::NoGroup);
4274                         return 0;
4275                 }
4276         }
4277         return sel_fail ("comp_enable", 0, get_address (msg));
4278 }
4279
4280 int
4281 OSC::sel_comp_threshold (float val, lo_message msg)
4282 {
4283         OSCSurface *sur = get_surface(get_address (msg));
4284         boost::shared_ptr<Stripable> s;
4285         if (sur->expand_enable) {
4286                 s = get_strip (sur->expand, get_address (msg));
4287         } else {
4288                 s = _select;
4289         }
4290         if (s) {
4291                 if (s->comp_threshold_controllable()) {
4292                         s->comp_threshold_controllable()->set_value (s->comp_threshold_controllable()->interface_to_internal (val), PBD::Controllable::NoGroup);
4293                         return 0;
4294                 }
4295         }
4296         return sel_fail ("comp_threshold", 0, get_address (msg));
4297 }
4298
4299 int
4300 OSC::sel_comp_speed (float val, lo_message msg)
4301 {
4302         OSCSurface *sur = get_surface(get_address (msg));
4303         boost::shared_ptr<Stripable> s;
4304         if (sur->expand_enable) {
4305                 s = get_strip (sur->expand, get_address (msg));
4306         } else {
4307                 s = _select;
4308         }
4309         if (s) {
4310                 if (s->comp_speed_controllable()) {
4311                         s->comp_speed_controllable()->set_value (s->comp_speed_controllable()->interface_to_internal (val), PBD::Controllable::NoGroup);
4312                         return 0;
4313                 }
4314         }
4315         return sel_fail ("comp_speed", 0, get_address (msg));
4316 }
4317
4318 int
4319 OSC::sel_comp_mode (float val, lo_message msg)
4320 {
4321         OSCSurface *sur = get_surface(get_address (msg));
4322         boost::shared_ptr<Stripable> s;
4323         if (sur->expand_enable) {
4324                 s = get_strip (sur->expand, get_address (msg));
4325         } else {
4326                 s = _select;
4327         }
4328         if (s) {
4329                 if (s->comp_mode_controllable()) {
4330                         s->comp_mode_controllable()->set_value (s->comp_mode_controllable()->interface_to_internal (val), PBD::Controllable::NoGroup);
4331                         return 0;
4332                 }
4333         }
4334         return sel_fail ("comp_mode", 0, get_address (msg));
4335 }
4336
4337 int
4338 OSC::sel_comp_makeup (float val, lo_message msg)
4339 {
4340         OSCSurface *sur = get_surface(get_address (msg));
4341         boost::shared_ptr<Stripable> s;
4342         if (sur->expand_enable) {
4343                 s = get_strip (sur->expand, get_address (msg));
4344         } else {
4345                 s = _select;
4346         }
4347         if (s) {
4348                 if (s->comp_makeup_controllable()) {
4349                         s->comp_makeup_controllable()->set_value (s->comp_makeup_controllable()->interface_to_internal (val), PBD::Controllable::NoGroup);
4350                         return 0;
4351                 }
4352         }
4353         return sel_fail ("comp_makeup", 0, get_address (msg));
4354 }
4355
4356 // EQ control
4357
4358 int
4359 OSC::sel_eq_enable (float val, lo_message msg)
4360 {
4361         OSCSurface *sur = get_surface(get_address (msg));
4362         boost::shared_ptr<Stripable> s;
4363         if (sur->expand_enable) {
4364                 s = get_strip (sur->expand, get_address (msg));
4365         } else {
4366                 s = _select;
4367         }
4368         if (s) {
4369                 if (s->eq_enable_controllable()) {
4370                         s->eq_enable_controllable()->set_value (s->eq_enable_controllable()->interface_to_internal (val), PBD::Controllable::NoGroup);
4371                         return 0;
4372                 }
4373         }
4374         return sel_fail ("eq_enable", 0, get_address (msg));
4375 }
4376
4377 int
4378 OSC::sel_eq_hpf_freq (float val, lo_message msg)
4379 {
4380         OSCSurface *sur = get_surface(get_address (msg));
4381         boost::shared_ptr<Stripable> s;
4382         if (sur->expand_enable) {
4383                 s = get_strip (sur->expand, get_address (msg));
4384         } else {
4385                 s = _select;
4386         }
4387         if (s) {
4388                 if (s->filter_freq_controllable(true)) {
4389                         s->filter_freq_controllable(true)->set_value (s->filter_freq_controllable(true)->interface_to_internal (val), PBD::Controllable::NoGroup);
4390                         return 0;
4391                 }
4392         }
4393         return sel_fail ("eq_hpf/freq", 0, get_address (msg));
4394 }
4395
4396 int
4397 OSC::sel_eq_lpf_freq (float val, lo_message msg)
4398 {
4399         OSCSurface *sur = get_surface(get_address (msg));
4400         boost::shared_ptr<Stripable> s;
4401         if (sur->expand_enable) {
4402                 s = get_strip (sur->expand, get_address (msg));
4403         } else {
4404                 s = _select;
4405         }
4406         if (s) {
4407                 if (s->filter_freq_controllable(false)) {
4408                         s->filter_freq_controllable(false)->set_value (s->filter_freq_controllable(false)->interface_to_internal (val), PBD::Controllable::NoGroup);
4409                         return 0;
4410                 }
4411         }
4412         return sel_fail ("eq_lpf/freq", 0, get_address (msg));
4413 }
4414
4415 int
4416 OSC::sel_eq_hpf_enable (float val, lo_message msg)
4417 {
4418         OSCSurface *sur = get_surface(get_address (msg));
4419         boost::shared_ptr<Stripable> s;
4420         if (sur->expand_enable) {
4421                 s = get_strip (sur->expand, get_address (msg));
4422         } else {
4423                 s = _select;
4424         }
4425         if (s) {
4426                 if (s->filter_enable_controllable(true)) {
4427                         s->filter_enable_controllable(true)->set_value (s->filter_enable_controllable(true)->interface_to_internal (val), PBD::Controllable::NoGroup);
4428                         return 0;
4429                 }
4430         }
4431         return sel_fail ("eq_hpf/enable", 0, get_address (msg));
4432 }
4433
4434 int
4435 OSC::sel_eq_lpf_enable (float val, lo_message msg)
4436 {
4437         OSCSurface *sur = get_surface(get_address (msg));
4438         boost::shared_ptr<Stripable> s;
4439         if (sur->expand_enable) {
4440                 s = get_strip (sur->expand, get_address (msg));
4441         } else {
4442                 s = _select;
4443         }
4444         if (s) {
4445                 if (s->filter_enable_controllable(false)) {
4446                         s->filter_enable_controllable(false)->set_value (s->filter_enable_controllable(false)->interface_to_internal (val), PBD::Controllable::NoGroup);
4447                         return 0;
4448                 }
4449         }
4450         return sel_fail ("eq_lpf/enable", 0, get_address (msg));
4451 }
4452
4453 int
4454 OSC::sel_eq_hpf_slope (float val, lo_message msg)
4455 {
4456         OSCSurface *sur = get_surface(get_address (msg));
4457         boost::shared_ptr<Stripable> s;
4458         if (sur->expand_enable) {
4459                 s = get_strip (sur->expand, get_address (msg));
4460         } else {
4461                 s = _select;
4462         }
4463         if (s) {
4464                 if (s->filter_slope_controllable(true)) {
4465                         s->filter_slope_controllable(true)->set_value (s->filter_slope_controllable(true)->interface_to_internal (val), PBD::Controllable::NoGroup);
4466                         return 0;
4467                 }
4468         }
4469         return sel_fail ("eq_hpf/slope", 0, get_address (msg));
4470 }
4471
4472 int
4473 OSC::sel_eq_lpf_slope (float val, lo_message msg)
4474 {
4475         OSCSurface *sur = get_surface(get_address (msg));
4476         boost::shared_ptr<Stripable> s;
4477         if (sur->expand_enable) {
4478                 s = get_strip (sur->expand, get_address (msg));
4479         } else {
4480                 s = _select;
4481         }
4482         if (s) {
4483                 if (s->filter_slope_controllable(false)) {
4484                         s->filter_slope_controllable(false)->set_value (s->filter_slope_controllable(false)->interface_to_internal (val), PBD::Controllable::NoGroup);
4485                         return 0;
4486                 }
4487         }
4488         return sel_fail ("eq_lpf/slope", 0, get_address (msg));
4489 }
4490
4491 int
4492 OSC::sel_eq_gain (int id, float val, lo_message msg)
4493 {
4494         OSCSurface *sur = get_surface(get_address (msg));
4495         boost::shared_ptr<Stripable> s;
4496         if (sur->expand_enable) {
4497                 s = get_strip (sur->expand, get_address (msg));
4498         } else {
4499                 s = _select;
4500         }
4501         if (s) {
4502                 if (id > 0) {
4503                         --id;
4504                 }
4505                 if (s->eq_gain_controllable (id)) {
4506                         s->eq_gain_controllable (id)->set_value (s->eq_gain_controllable(id)->interface_to_internal (val), PBD::Controllable::NoGroup);
4507                         return 0;
4508                 }
4509         }
4510         return sel_send_fail ("eq_gain", id + 1, 0, get_address (msg));
4511 }
4512
4513 int
4514 OSC::sel_eq_freq (int id, float val, lo_message msg)
4515 {
4516         OSCSurface *sur = get_surface(get_address (msg));
4517         boost::shared_ptr<Stripable> s;
4518         if (sur->expand_enable) {
4519                 s = get_strip (sur->expand, get_address (msg));
4520         } else {
4521                 s = _select;
4522         }
4523         if (s) {
4524                 if (id > 0) {
4525                         --id;
4526                 }
4527                 if (s->eq_freq_controllable (id)) {
4528                         s->eq_freq_controllable (id)->set_value (s->eq_freq_controllable(id)->interface_to_internal (val), PBD::Controllable::NoGroup);
4529                         return 0;
4530                 }
4531         }
4532         return sel_send_fail ("eq_freq", id + 1, 0, get_address (msg));
4533 }
4534
4535 int
4536 OSC::sel_eq_q (int id, float val, lo_message msg)
4537 {
4538         OSCSurface *sur = get_surface(get_address (msg));
4539         boost::shared_ptr<Stripable> s;
4540         if (sur->expand_enable) {
4541                 s = get_strip (sur->expand, get_address (msg));
4542         } else {
4543                 s = _select;
4544         }
4545         if (s) {
4546                 if (id > 0) {
4547                         --id;
4548                 }
4549                 if (s->eq_q_controllable (id)) {
4550                         s->eq_q_controllable (id)->set_value (s->eq_q_controllable(id)->interface_to_internal (val), PBD::Controllable::NoGroup);
4551                         return 0;
4552                 }
4553         }
4554         return sel_send_fail ("eq_q", id + 1, 0, get_address (msg));
4555 }
4556
4557 int
4558 OSC::sel_eq_shape (int id, float val, lo_message msg)
4559 {
4560         OSCSurface *sur = get_surface(get_address (msg));
4561         boost::shared_ptr<Stripable> s;
4562         if (sur->expand_enable) {
4563                 s = get_strip (sur->expand, get_address (msg));
4564         } else {
4565                 s = _select;
4566         }
4567         if (s) {
4568                 if (id > 0) {
4569                         --id;
4570                 }
4571                 if (s->eq_shape_controllable (id)) {
4572                         s->eq_shape_controllable (id)->set_value (s->eq_shape_controllable(id)->interface_to_internal (val), PBD::Controllable::NoGroup);
4573                         return 0;
4574                 }
4575         }
4576         return sel_send_fail ("eq_shape", id + 1, 0, get_address (msg));
4577 }
4578
4579 void
4580 OSC::gui_selection_changed ()
4581 {
4582         boost::shared_ptr<Stripable> strip = ControlProtocol::first_selected_stripable();
4583
4584         if (strip) {
4585                 _select = strip;
4586                 for (uint32_t it = 0; it < _surface.size(); ++it) {
4587                         OSCSurface* sur = &_surface[it];
4588                         if(!sur->expand_enable) {
4589                                 lo_address addr = lo_address_new_from_url (sur->remote_url.c_str());
4590                                 _strip_select (strip, addr);
4591                         }
4592                 }
4593         }
4594 }
4595
4596 // timer callbacks
4597 bool
4598 OSC::periodic (void)
4599 {
4600         if (!tick) {
4601                 Glib::usleep(100); // let flurry of signals subside
4602                 if (global_init) {
4603                         for (uint32_t it = 0; it < _surface.size(); it++) {
4604                                 OSCSurface* sur = &_surface[it];
4605                                 lo_address addr = lo_address_new_from_url (sur->remote_url.c_str());
4606                                 global_feedback (sur->feedback, addr, sur->gainmode);
4607                         }
4608                         global_init = false;
4609                         tick = true;
4610                 }
4611                 if (bank_dirty) {
4612                         _recalcbanks ();
4613                         bank_dirty = false;
4614                         tick = true;
4615                 }
4616         }
4617
4618         if (scrub_speed != 0) {
4619                 // for those jog wheels that don't have 0 on release (touch), time out.
4620                 int64_t now = ARDOUR::get_microseconds ();
4621                 int64_t diff = now - scrub_time;
4622                 if (diff > 120000) {
4623                         scrub_speed = 0;
4624                         session->request_transport_speed (0);
4625                         // locate to the place PH was at last tick
4626                         session->request_locate (scrub_place, false);
4627                 }
4628         }
4629
4630         for (GlobalObservers::iterator x = global_observers.begin(); x != global_observers.end(); x++) {
4631
4632                 OSCGlobalObserver* go;
4633
4634                 if ((go = dynamic_cast<OSCGlobalObserver*>(*x)) != 0) {
4635                         go->tick();
4636                 }
4637         }
4638         for (RouteObservers::iterator x = route_observers.begin(); x != route_observers.end(); x++) {
4639
4640                 OSCRouteObserver* ro;
4641
4642                 if ((ro = dynamic_cast<OSCRouteObserver*>(*x)) != 0) {
4643                         ro->tick();
4644                 }
4645         }
4646         for (uint32_t it = 0; it < _surface.size(); it++) {
4647                 OSCSurface* sur = &_surface[it];
4648                 OSCSelectObserver* so;
4649                 if ((so = dynamic_cast<OSCSelectObserver*>(sur->sel_obs)) != 0) {
4650                         so->tick();
4651                 }
4652         }
4653         for (CueObservers::iterator x = cue_observers.begin(); x != cue_observers.end(); x++) {
4654
4655                 OSCCueObserver* co;
4656
4657                 if ((co = dynamic_cast<OSCCueObserver*>(*x)) != 0) {
4658                         co->tick();
4659                 }
4660         }
4661         for (FakeTouchMap::iterator x = _touch_timeout.begin(); x != _touch_timeout.end();) {
4662                 _touch_timeout[(*x).first] = (*x).second - 1;
4663                 if (!(*x).second) {
4664                         boost::shared_ptr<ARDOUR::AutomationControl> ctrl = (*x).first;
4665                         // turn touch off
4666                         ctrl->stop_touch (true, ctrl->session().transport_frame());
4667                         _touch_timeout.erase (x++);
4668                 } else {
4669                         x++;
4670                 }
4671         }
4672         return true;
4673 }
4674
4675 int
4676 OSC::route_send_fail (string path, uint32_t ssid, float val, lo_address addr)
4677 {
4678         OSCSurface *sur = get_surface(addr);
4679
4680         ostringstream os;
4681         lo_message reply;
4682         if (ssid) {
4683                 reply = lo_message_new ();
4684                 if (sur->feedback[2]) {
4685                         os << "/strip/" << path << "/" << ssid;
4686                 } else {
4687                         os << "/strip/" << path;
4688                         lo_message_add_int32 (reply, ssid);
4689                 }
4690                 string str_pth = os.str();
4691                 lo_message_add_float (reply, (float) val);
4692
4693                 lo_send_message (addr, str_pth.c_str(), reply);
4694                 lo_message_free (reply);
4695         }
4696         if ((_select == get_strip (ssid, addr)) || ((sur->expand == ssid) && (sur->expand_enable))) {
4697                 os.str("");
4698                 os << "/select/" << path;
4699                 string sel_pth = os.str();
4700                 reply = lo_message_new ();
4701                 lo_message_add_float (reply, (float) val);
4702                 lo_send_message (addr, sel_pth.c_str(), reply);
4703                 lo_message_free (reply);
4704         }
4705
4706         return 0;
4707 }
4708
4709 int
4710 OSC::sel_fail (string path, float val, lo_address addr)
4711 {
4712         ostringstream os;
4713         os.str("");
4714         os << "/select/" << path;
4715         string sel_pth = os.str();
4716         lo_message reply = lo_message_new ();
4717         lo_message_add_float (reply, (float) val);
4718         lo_send_message (addr, sel_pth.c_str(), reply);
4719         lo_message_free (reply);
4720
4721         return 0;
4722 }
4723
4724 int
4725 OSC::sel_send_fail (string path, uint32_t id, float val, lo_address addr)
4726 {
4727         OSCSurface *sur = get_surface(addr);
4728
4729         ostringstream os;
4730         lo_message reply;
4731         reply = lo_message_new ();
4732         if (sur->feedback[2]) {
4733                 os << "/select/" << path << "/" << id;
4734         } else {
4735                 os << "/select/" << path;
4736                 lo_message_add_int32 (reply, id);
4737         }
4738         string str_pth = os.str();
4739         lo_message_add_float (reply, (float) val);
4740
4741         lo_send_message (addr, str_pth.c_str(), reply);
4742         lo_message_free (reply);
4743
4744         return 0;
4745 }
4746
4747 XMLNode&
4748 OSC::get_state ()
4749 {
4750         XMLNode& node (ControlProtocol::get_state());
4751         node.set_property ("debugmode", (int32_t) _debugmode); // TODO: enum2str
4752         node.set_property ("address-only", address_only);
4753         node.set_property ("remote-port", remote_port);
4754         node.set_property ("banksize", default_banksize);
4755         node.set_property ("striptypes", default_strip);
4756         node.set_property ("feedback", default_feedback);
4757         node.set_property ("gainmode", default_gainmode);
4758         node.set_property ("send-page-size", default_send_size);
4759         node.set_property ("plug-page-size", default_plugin_size);
4760         if (_surface.size()) {
4761                 XMLNode* config = new XMLNode (X_("Configurations"));
4762                 for (uint32_t it = 0; it < _surface.size(); ++it) {
4763                         OSCSurface* sur = &_surface[it];
4764                         XMLNode* devnode = new XMLNode (X_("Configuration"));
4765                         devnode->set_property (X_("url"), sur->remote_url);
4766                         devnode->set_property (X_("bank-size"), sur->bank_size);
4767                         devnode->set_property (X_("strip-types"), (uint64_t)sur->strip_types.to_ulong());
4768                         devnode->set_property (X_("feedback"), (uint64_t)sur->feedback.to_ulong());
4769                         devnode->set_property (X_("gainmode"), sur->gainmode);
4770                         devnode->set_property (X_("send-page-size"), sur->send_page_size);
4771                         devnode->set_property (X_("plug-page-size"), sur->plug_page_size);
4772                         devnode->set_property (X_("no-clear"), sur->no_clear);
4773                         devnode->set_property (X_("cue"), sur->cue);
4774                         devnode->set_property (X_("aux"), sur->aux);
4775                         config->add_child_nocopy (*devnode);
4776                 }
4777                 node.add_child_nocopy (*config);
4778         }
4779         return node;
4780 }
4781
4782 int
4783 OSC::set_state (const XMLNode& node, int version)
4784 {
4785         if (ControlProtocol::set_state (node, version)) {
4786                 return -1;
4787         }
4788         int32_t debugmode;
4789         if (node.get_property (X_("debugmode"), debugmode)) {
4790                 _debugmode = OSCDebugMode (debugmode);
4791         }
4792
4793         node.get_property (X_("address-only"), address_only);
4794         node.get_property (X_("remote-port"), remote_port);
4795         node.get_property (X_("banksize"), default_banksize);
4796         node.get_property (X_("striptypes"), default_strip);
4797         node.get_property (X_("feedback"), default_feedback);
4798         node.get_property (X_("gainmode"), default_gainmode);
4799         node.get_property (X_("send-page-size"), default_send_size);
4800         node.get_property (X_("plugin-page-size"), default_plugin_size);
4801
4802         XMLNode* cnode = node.child (X_("Configurations"));
4803
4804         if (cnode) {
4805                 XMLNodeList const& devices = cnode->children();
4806                 for (XMLNodeList::const_iterator d = devices.begin(); d != devices.end(); ++d) {
4807                         OSCSurface s;
4808                         if (!(*d)->get_property (X_("url"), s.remote_url)) {
4809                                 continue;
4810                         }
4811
4812                         bank_dirty = true;
4813
4814                         (*d)->get_property (X_("bank-size"), s.bank_size);
4815
4816                         uint64_t bits;
4817                         if ((*d)->get_property (X_ ("strip-types"), bits)) {
4818                                 s.strip_types = bits;
4819                         }
4820                         if ((*d)->get_property (X_("feedback"), bits)) {
4821                                 s.feedback = bits;
4822                         }
4823                         (*d)->get_property (X_("gainmode"), s.gainmode);
4824
4825                         (*d)->get_property (X_("send-page-size"), s.send_page_size);
4826                         (*d)->get_property (X_("plug-page-size"), s.plug_page_size);
4827                         (*d)->get_property (X_("no-clear"), s.no_clear);
4828                         (*d)->get_property (X_("cue"), s.cue);
4829                         (*d)->get_property (X_("aux"), s.aux);
4830                         s.bank = 1;
4831                         s.sel_obs = 0;
4832                         s.expand = 0;
4833                         s.expand_enable = false;
4834                         s.strips = get_sorted_stripables (s.strip_types, s.cue);
4835                         s.nstrips = s.strips.size ();
4836                         s.jogmode = JOG;
4837                         _surface.push_back (s);
4838                 }
4839         }
4840         global_init = true;
4841         tick = false;
4842
4843         return 0;
4844 }
4845
4846 // predicate for sort call in get_sorted_stripables
4847 struct StripableByPresentationOrder
4848 {
4849         bool operator () (const boost::shared_ptr<Stripable> & a, const boost::shared_ptr<Stripable> & b) const
4850         {
4851                 return a->presentation_info().order() < b->presentation_info().order();
4852         }
4853
4854         bool operator () (const Stripable & a, const Stripable & b) const
4855         {
4856                 return a.presentation_info().order() < b.presentation_info().order();
4857         }
4858
4859         bool operator () (const Stripable * a, const Stripable * b) const
4860         {
4861                 return a->presentation_info().order() < b->presentation_info().order();
4862         }
4863 };
4864
4865 OSC::Sorted
4866 OSC::get_sorted_stripables(std::bitset<32> types, bool cue)
4867 {
4868         Sorted sorted;
4869
4870         // fetch all stripables
4871         StripableList stripables;
4872
4873         session->get_stripables (stripables);
4874
4875         // Look for stripables that match bit in sur->strip_types
4876         for (StripableList::iterator it = stripables.begin(); it != stripables.end(); ++it) {
4877
4878                 boost::shared_ptr<Stripable> s = *it;
4879                 if ((!cue) && (!types[9]) && (s->presentation_info().flags() & PresentationInfo::Hidden)) {
4880                         // do nothing... skip it
4881                 } else {
4882
4883                         if (types[0] && (s->presentation_info().flags() & PresentationInfo::AudioTrack)) {
4884                                 sorted.push_back (s);
4885                         } else
4886                         if (types[1] && (s->presentation_info().flags() & PresentationInfo::MidiTrack)) {
4887                                 sorted.push_back (s);
4888                         } else
4889                         if ((s->presentation_info().flags() & PresentationInfo::AudioBus)) {
4890                                 boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
4891                                 // r->feeds (session->master_out()) may make more sense
4892                                 if (r->direct_feeds_according_to_reality (session->master_out())) {
4893                                         // this is a bus
4894                                         if (types[2]) {
4895                                                 sorted.push_back (s);
4896                                         }
4897                                 } else {
4898                                         // this is an Aux out
4899                                         if (types[7]) {
4900                                                 sorted.push_back (s);
4901                                         }
4902                                 }
4903                         } else if (types[3] && (s->presentation_info().flags() & PresentationInfo::MidiBus)) {
4904                                 sorted.push_back (s);
4905                         } else if (types[4] && (s->presentation_info().flags() & PresentationInfo::VCA)) {
4906                                 sorted.push_back (s);
4907                         } else if (types[8] && (s->is_selected())) {
4908                                 sorted.push_back (s);
4909                         } else if (types[9] && (s->presentation_info().flags() & PresentationInfo::Hidden)) {
4910                                 sorted.push_back (s);
4911                         }
4912 #ifdef MIXBUS
4913                         else if (types[2]) {
4914                                 if (Profile->get_mixbus()) {
4915                                         if (s->mixbus()) {
4916                                                 sorted.push_back (s);
4917                                         }
4918                                 }
4919                         }
4920 #endif
4921                 }
4922         }
4923         sort (sorted.begin(), sorted.end(), StripableByPresentationOrder());
4924         // Master/Monitor might be anywhere... we put them at the end - Sorry ;)
4925         if (types[5]) {
4926                 sorted.push_back (session->master_out());
4927         }
4928         if (types[6]) {
4929                 sorted.push_back (session->monitor_out());
4930         }
4931         return sorted;
4932 }
4933
4934 int
4935 OSC::cue_parse (const char *path, const char* types, lo_arg **argv, int argc, lo_message msg)
4936 {
4937         int ret = 1; /* unhandled */
4938
4939         if (!strncmp (path, "/cue/aux", 8)) {
4940                 // set our Aux bus
4941                 ret = cue_set (argv[0]->i, msg);
4942         }
4943         else if (!strncmp (path, "/cue/connect", 12)) {
4944                 // Connect to default Aux bus
4945                 if ((!argc) || argv[0]->i) {
4946                         ret = cue_set (1, msg);
4947                 }
4948         }
4949         else if (!strncmp (path, "/cue/next_aux", 13)) {
4950                 // switch to next Aux bus
4951                 if ((!argc) || argv[0]->i) {
4952                         ret = cue_next (msg);
4953                 }
4954         }
4955         else if (!strncmp (path, "/cue/previous_aux", 17)) {
4956                 // switch to previous Aux bus
4957                 if ((!argc) || argv[0]->i) {
4958                         ret = cue_previous (msg);
4959                 }
4960         }
4961         else if (!strncmp (path, "/cue/send/fader/", 16) && strlen (path) > 16) {
4962                 int id = atoi (&path[16]);
4963                 ret = cue_send_fader (id, argv[0]->f, msg);
4964         }
4965         else if (!strncmp (path, "/cue/send/enable/", 17) && strlen (path) > 17) {
4966                 int id = atoi (&path[17]);
4967                 ret = cue_send_enable (id, argv[0]->f, msg);
4968         }
4969         else if (!strncmp (path, "/cue/fader", 10)) {
4970                 ret = cue_aux_fader (argv[0]->f, msg);
4971         }
4972         else if (!strncmp (path, "/cue/mute", 9)) {
4973                 ret = cue_aux_mute (argv[0]->f, msg);
4974         }
4975
4976         return ret;
4977 }
4978
4979 int
4980 OSC::cue_set (uint32_t aux, lo_message msg)
4981 {
4982         return _cue_set (aux, get_address (msg));
4983 }
4984
4985 int
4986 OSC::_cue_set (uint32_t aux, lo_address addr)
4987 {
4988         int ret = 1;
4989         OSCSurface *s = get_surface(addr);
4990         s->bank_size = 0;
4991         s->strip_types = 128;
4992         s->feedback = 0;
4993         s->gainmode = 1;
4994         s->cue = true;
4995         s->strips = get_sorted_stripables(s->strip_types, s->cue);
4996
4997         s->nstrips = s->strips.size();
4998
4999         if (aux < 1) {
5000                 aux = 1;
5001         } else if (aux > s->nstrips) {
5002                 aux = s->nstrips;
5003         }
5004         s->aux = aux;
5005
5006         // get rid of any old CueObsevers for this address
5007         //cueobserver_connections.drop_connections ();
5008         CueObservers::iterator x;
5009         for (x = cue_observers.begin(); x != cue_observers.end();) {
5010
5011                 OSCCueObserver* co;
5012
5013                 if ((co = dynamic_cast<OSCCueObserver*>(*x)) != 0) {
5014
5015                         int res = strcmp(lo_address_get_url(co->address()), lo_address_get_url(addr));
5016
5017                         if (res == 0) {
5018                                 delete *x;
5019                                 x = cue_observers.erase (x);
5020                         } else {
5021                                 ++x;
5022                         }
5023                 } else {
5024                         ++x;
5025                 }
5026         }
5027
5028         // get a list of Auxes
5029         for (uint32_t n = 0; n < s->nstrips; ++n) {
5030                 boost::shared_ptr<Stripable> stp = s->strips[n];
5031                 if (stp) {
5032                         text_message (string_compose ("/cue/name/%1", n+1), stp->name(), addr);
5033                         if (aux == n+1) {
5034                                 // aux must be at least one
5035                                 // need a signal if aux vanishes
5036                                 stp->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::_cue_set, this, aux, addr), this);
5037
5038                                 // make a list of stripables with sends that go to this bus
5039                                 s->sends = cue_get_sorted_stripables(stp, aux, addr);
5040                                 // start cue observer
5041                                 OSCCueObserver* co = new OSCCueObserver (stp, s->sends, addr);
5042                                 cue_observers.push_back (co);
5043                                 ret = 0;
5044                         }
5045
5046                 }
5047         }
5048
5049         return ret;
5050 }
5051
5052 int
5053 OSC::cue_next (lo_message msg)
5054 {
5055         OSCSurface *s = get_surface(get_address (msg));
5056         int ret = 1;
5057
5058         if (!s->cue) {
5059                 ret = cue_set (1, msg);
5060         }
5061         if (s->aux < s->nstrips) {
5062                 ret = cue_set (s->aux + 1, msg);
5063         } else {
5064                 ret = cue_set (s->nstrips, msg);
5065         }
5066         return ret;
5067 }
5068
5069 int
5070 OSC::cue_previous (lo_message msg)
5071 {
5072         OSCSurface *s = get_surface(get_address (msg));
5073         int ret = 1;
5074         if (!s->cue) {
5075                 ret = cue_set (1, msg);
5076         }
5077         if (s->aux > 1) {
5078                 ret = cue_set (s->aux - 1, msg);
5079         }
5080         return ret;
5081 }
5082
5083 boost::shared_ptr<Send>
5084 OSC::cue_get_send (uint32_t id, lo_address addr)
5085 {
5086         OSCSurface *s = get_surface(addr);
5087         if (id && s->aux > 0 && id <= s->sends.size()) {
5088                 boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s->sends[id - 1]);
5089                 boost::shared_ptr<Stripable> aux = get_strip (s->aux, addr);
5090                 if (r && aux) {
5091                         return r->internal_send_for (boost::dynamic_pointer_cast<Route> (aux));
5092                 }
5093         }
5094         return boost::shared_ptr<Send>();
5095
5096 }
5097
5098 int
5099 OSC::cue_aux_fader (float position, lo_message msg)
5100 {
5101         if (!session) return -1;
5102
5103         OSCSurface *sur = get_surface(get_address (msg));
5104         if (sur->cue) {
5105                 if (sur->aux) {
5106                         boost::shared_ptr<Stripable> s = get_strip (sur->aux, get_address (msg));
5107
5108                         if (s) {
5109                                 if (s->gain_control()) {
5110                                         s->gain_control()->set_value (s->gain_control()->interface_to_internal (position), PBD::Controllable::NoGroup);
5111                                         return 0;
5112                                 }
5113                         }
5114                 }
5115         }
5116         cue_float_message ("/cue/fader", 0, get_address (msg));
5117         return -1;
5118 }
5119
5120 int
5121 OSC::cue_aux_mute (float state, lo_message msg)
5122 {
5123         if (!session) return -1;
5124
5125         OSCSurface *sur = get_surface(get_address (msg));
5126         if (sur->cue) {
5127                 if (sur->aux) {
5128                         boost::shared_ptr<Stripable> s = get_strip (sur->aux, get_address (msg));
5129                         if (s) {
5130                                 if (s->mute_control()) {
5131                                         s->mute_control()->set_value (state ? 1.0 : 0.0, PBD::Controllable::NoGroup);
5132                                         return 0;
5133                                 }
5134                         }
5135                 }
5136         }
5137         cue_float_message ("/cue/mute", 0, get_address (msg));
5138         return -1;
5139 }
5140
5141 int
5142 OSC::cue_send_fader (uint32_t id, float val, lo_message msg)
5143 {
5144         if (!session) {
5145                 return -1;
5146         }
5147         boost::shared_ptr<Send> s = cue_get_send (id, get_address (msg));
5148         if (s) {
5149                 if (s->gain_control()) {
5150                         s->gain_control()->set_value (s->gain_control()->interface_to_internal(val), PBD::Controllable::NoGroup);
5151                         return 0;
5152                 }
5153         }
5154         cue_float_message (string_compose ("/cue/send/fader/%1", id), 0, get_address (msg));
5155         return -1;
5156 }
5157
5158 int
5159 OSC::cue_send_enable (uint32_t id, float state, lo_message msg)
5160 {
5161         if (!session)
5162                 return -1;
5163         boost::shared_ptr<Send> s = cue_get_send (id, get_address (msg));
5164         if (s) {
5165                 if (state) {
5166                         s->activate ();
5167                 } else {
5168                         s->deactivate ();
5169                 }
5170                 return 0;
5171         }
5172         cue_float_message (string_compose ("/cue/send/enable/%1", id), 0, get_address (msg));
5173         return -1;
5174 }
5175
5176 int
5177 OSC::cue_float_message (string path, float val, lo_address addr)
5178 {
5179
5180         lo_message reply;
5181         reply = lo_message_new ();
5182         lo_message_add_float (reply, (float) val);
5183
5184         lo_send_message (addr, path.c_str(), reply);
5185         lo_message_free (reply);
5186
5187         return 0;
5188 }
5189
5190 int
5191 OSC::text_message (string path, string val, lo_address addr)
5192 {
5193
5194         lo_message reply;
5195         reply = lo_message_new ();
5196         lo_message_add_string (reply, val.c_str());
5197
5198         lo_send_message (addr, path.c_str(), reply);
5199         lo_message_free (reply);
5200
5201         return 0;
5202 }
5203
5204
5205 // we have to have a sorted list of stripables that have sends pointed at our aux
5206 // we can use the one in osc.cc to get an aux list
5207 OSC::Sorted
5208 OSC::cue_get_sorted_stripables(boost::shared_ptr<Stripable> aux, uint32_t id, lo_message msg)
5209 {
5210         Sorted sorted;
5211         cueobserver_connections.drop_connections ();
5212         // fetch all stripables
5213         StripableList stripables;
5214
5215         session->get_stripables (stripables);
5216
5217         // Look for stripables that have a send to aux
5218         for (StripableList::iterator it = stripables.begin(); it != stripables.end(); ++it) {
5219
5220                 boost::shared_ptr<Stripable> s = *it;
5221                 // we only want routes
5222                 boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route> (s);
5223                 if (r) {
5224                         r->processors_changed.connect  (*this, MISSING_INVALIDATOR, boost::bind (&OSC::recalcbanks, this), this);
5225                         boost::shared_ptr<Send> snd = r->internal_send_for (boost::dynamic_pointer_cast<Route> (aux));
5226                         if (snd) { // test for send to aux
5227                                 sorted.push_back (s);
5228                                 s->DropReferences.connect (*this, MISSING_INVALIDATOR, boost::bind (&OSC::cue_set, this, id, msg), this);
5229                         }
5230                 }
5231
5232
5233         }
5234         sort (sorted.begin(), sorted.end(), StripableByPresentationOrder());
5235
5236         return sorted;
5237 }
5238