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