diff --git a/libs/surfaces/osc/osc.cc b/libs/surfaces/osc/osc.cc index 4438c6dba4..19516045dc 100644 --- a/libs/surfaces/osc/osc.cc +++ b/libs/surfaces/osc/osc.cc @@ -487,6 +487,8 @@ OSC::register_callbacks() REGISTER_CALLBACK (serv, "/master/pan_stereo_position", "f", master_set_pan_stereo_position); REGISTER_CALLBACK (serv, "/monitor/gain", "f", monitor_set_gain); REGISTER_CALLBACK (serv, "/monitor/fader", "i", monitor_set_fader); + REGISTER_CALLBACK (serv, "/select/recenable", "i", sel_recenable); + REGISTER_CALLBACK (serv, "/select/record_safe", "ii", sel_recsafe); /* These commands require the route index in addition to the arg; TouchOSC (et al) can't use these */ @@ -496,6 +498,8 @@ OSC::register_callbacks() REGISTER_CALLBACK (serv, "/strip/record_safe", "ii", route_recsafe); REGISTER_CALLBACK (serv, "/strip/monitor_input", "ii", route_monitor_input); REGISTER_CALLBACK (serv, "/strip/monitor_disk", "ii", route_monitor_disk); + REGISTER_CALLBACK (serv, "/strip/select", "ii", strip_select); + REGISTER_CALLBACK (serv, "/strip/gui_select", "ii", strip_gui_select); REGISTER_CALLBACK (serv, "/strip/gain", "if", route_set_gain_dB); REGISTER_CALLBACK (serv, "/strip/fader", "if", route_set_gain_fader); REGISTER_CALLBACK (serv, "/strip/trimabs", "if", route_set_trim_abs); @@ -503,6 +507,7 @@ OSC::register_callbacks() REGISTER_CALLBACK (serv, "/strip/pan_stereo_position", "if", route_set_pan_stereo_position); REGISTER_CALLBACK (serv, "/strip/pan_stereo_width", "if", route_set_pan_stereo_width); REGISTER_CALLBACK (serv, "/strip/plugin/parameter", "iiif", route_plugin_parameter); + // prints to cerr only REGISTER_CALLBACK (serv, "/strip/plugin/parameter/print", "iii", route_plugin_parameter_print); REGISTER_CALLBACK (serv, "/strip/send/gainabs", "iif", route_set_send_gain_abs); REGISTER_CALLBACK (serv, "/strip/send/gaindB", "iif", route_set_send_gain_dB); @@ -832,6 +837,16 @@ OSC::catchall (const char *path, const char* types, lo_arg **argv, int argc, lo_ route_recsafe (ssid, argv[0]->f == 1.0, msg); ret = 0; } + else if (!strncmp (path, "/strip/select/", 14) && strlen (path) > 14) { + int ssid = atoi (&path[14]); + strip_select (ssid, argv[0]->f == 1.0, msg); + ret = 0; + } + else if (!strncmp (path, "/strip/gui_select/", 18) && strlen (path) > 18) { + int ssid = atoi (&path[18]); + strip_gui_select (ssid, argv[0]->f == 1.0, msg); + ret = 0; + } } if ((ret && _debugmode == Unhandled)) { @@ -1385,10 +1400,6 @@ OSC::master_set_pan_stereo_position (float position) if (s->pan_azimuth_control()) { s->pan_azimuth_control()->set_value (position, PBD::Controllable::NoGroup); } - /*boost::shared_ptr panner = s->pan_azimuth_control(); - if (panner) { - panner->set_value (position, PBD::Controllable::NoGroup); - }*/ } return 0; @@ -1470,6 +1481,13 @@ OSC::route_solo (int ssid, int yn, lo_message msg) return 0; } +int +OSC::sel_recenable (uint32_t yn, lo_message msg) +{ + OSCSurface *sur = get_surface(lo_message_get_source (msg)); + return route_recenable(sur->surface_sel, yn, msg); +} + int OSC::route_recenable (int ssid, int yn, lo_message msg) { @@ -1490,6 +1508,13 @@ OSC::route_recenable (int ssid, int yn, lo_message msg) return route_send_fail ("/strip/recenable", ssid, msg); } +int +OSC::sel_recsafe (uint32_t yn, lo_message msg) +{ + OSCSurface *sur = get_surface(lo_message_get_source (msg)); + return route_recsafe(sur->surface_sel, yn, msg); +} + int OSC::route_recsafe (int ssid, int yn, lo_message msg) { @@ -1551,6 +1576,54 @@ OSC::route_monitor_disk (int ssid, int yn, lo_message msg) return 0; } +int +OSC::strip_select (int ssid, int yn, lo_message msg) +{ + //ignore button release + if (!yn) return 0; + + if (!session) { + route_send_fail ("/strip/select", ssid, msg); + return -1; + } + int rid = get_rid (ssid, lo_message_get_source (msg)); + boost::shared_ptr s = session->get_remote_nth_stripable (rid, PresentationInfo::Route); + OSCSurface *sur = get_surface(lo_message_get_source (msg)); + sur->surface_sel = ssid; + + if (s) { + sur->sel = s; + } else { + route_send_fail ("/strip/select", ssid, msg); + } + + return 0; +} + +int +OSC::strip_gui_select (int ssid, int yn, lo_message msg) +{ + //ignore button release + if (!yn) return 0; + + if (!session) { + route_send_fail ("/strip/gui_select", ssid, msg); + return -1; + } + int rid = get_rid (ssid, lo_message_get_source (msg)); + boost::shared_ptr s = session->get_remote_nth_stripable (rid, PresentationInfo::Route); + OSCSurface *sur = get_surface(lo_message_get_source (msg)); + sur->surface_sel = ssid; + + if (s) { + sur->sel = s; + } else { + route_send_fail ("/strip/gui_select", ssid, msg); + } + + return 0; +} + int OSC::route_set_gain_abs (int rid, float level, lo_message msg) { @@ -1741,6 +1814,7 @@ OSC::route_plugin_parameter (int ssid, int piid, int par, float val, lo_message return 0; } +//prints to cerr only int OSC::route_plugin_parameter_print (int ssid, int piid, int par, lo_message msg) { diff --git a/libs/surfaces/osc/osc.h b/libs/surfaces/osc/osc.h index 6d33fabd4e..f4cd7dcd7f 100644 --- a/libs/surfaces/osc/osc.h +++ b/libs/surfaces/osc/osc.h @@ -98,17 +98,19 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI // keep a surface's global setup by remote server url struct OSCSurface { public: - std::string remote_url; // the url these setting belong to - uint32_t bank; // current bank - uint32_t bank_size; // size of banks for this surface - std::bitset<32> strip_types; // what strip types are a part of this bank - std::bitset<32> feedback; // What is fed back? strips/meters/timecode/bar_beat/global - int gainmode; // what kind of faders do we have Gain db or position 0 to 1023? - uint32_t surface_sel; // which strip within the bank is locally selected + std::string remote_url; // the url these setting belong to + uint32_t bank; // current bank + uint32_t bank_size; // size of banks for this surface + std::bitset<32> strip_types; // what strip types are a part of this bank + std::bitset<32> feedback; // What is fed back? strips/meters/timecode/bar_beat/global + int gainmode; // what kind of faders do we have Gain db or position 0 to 1023? + boost::shared_ptr sel; // + uint32_t surface_sel; // which strip within the bank is locally selected //StripableList strips; //list of stripables for the current bank }; /* * Reminder of what strip_types there are + * XXX these have changed!!! AudioTrack = 0x1, MidiTrack = 0x2, AudioBus = 0x4, @@ -132,6 +134,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI * [7] - Send metering as dB or positional depending on gainmode * [8] - Send metering as 16 bits (led strip) * [9] - Send signal present (signal greater than -20dB) + * [10] - Selection is local */ @@ -322,6 +325,8 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI PATH_CALLBACK1_MSG(set_surface_strip_types,i); PATH_CALLBACK1_MSG(set_surface_feedback,i); PATH_CALLBACK1_MSG(set_surface_gainmode,i); + PATH_CALLBACK1_MSG(sel_recenable,i); + PATH_CALLBACK1_MSG(sel_recsafe,i); #define PATH_CALLBACK2(name,arg1type,arg2type) \ static int _ ## name (const char *path, const char *types, lo_arg **argv, int argc, void *data, void *user_data) { \ @@ -380,6 +385,8 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI PATH_CALLBACK2_MSG(route_recsafe,i,i); PATH_CALLBACK2_MSG(route_monitor_input,i,i); PATH_CALLBACK2_MSG(route_monitor_disk,i,i); + PATH_CALLBACK2_MSG(strip_select,i,i); + PATH_CALLBACK2_MSG(strip_gui_select,i,i); PATH_CALLBACK2_MSG(route_set_gain_abs,i,f); PATH_CALLBACK2_MSG(route_set_gain_dB,i,f); PATH_CALLBACK2_MSG(route_set_gain_fader,i,f); @@ -398,6 +405,8 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI int route_recsafe (int ssid, int yn, lo_message msg); int route_monitor_input (int rid, int yn, lo_message msg); int route_monitor_disk (int rid, int yn, lo_message msg); + int strip_select (int rid, int yn, lo_message msg); + int strip_gui_select (int rid, int yn, lo_message msg); int route_set_gain_abs (int rid, float level, lo_message msg); int route_set_gain_dB (int rid, float dB, lo_message msg); int route_set_gain_fader (int rid, float pos, lo_message msg); @@ -427,6 +436,8 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI int master_set_mute (uint32_t state); int monitor_set_gain (float dB); int monitor_set_fader (uint32_t position); + int sel_recenable (uint32_t state, lo_message msg); + int sel_recsafe (uint32_t state, lo_message msg); void listen_to_route (boost::shared_ptr, lo_address); void end_listen (boost::shared_ptr, lo_address); diff --git a/libs/surfaces/osc/osc_global_observer.cc b/libs/surfaces/osc/osc_global_observer.cc index 85a758e4dd..5cbb61d3a4 100644 --- a/libs/surfaces/osc/osc_global_observer.cc +++ b/libs/surfaces/osc/osc_global_observer.cc @@ -37,85 +37,89 @@ OSCGlobalObserver::OSCGlobalObserver (Session& s, lo_address a, uint32_t gm, std : gainmode (gm) ,feedback (fb) { + if (feedback[4]) { + addr = lo_address_new (lo_address_get_hostname(a) , lo_address_get_port(a)); + session = &s; + _last_frame = -1; - addr = lo_address_new (lo_address_get_hostname(a) , lo_address_get_port(a)); - session = &s; - _last_frame = -1; - // connect to all the things we want to send feed back from + // connect to all the things we want to send feed back from - /* - * Master (todo) - * Pan width - */ + /* + * Master (todo) + * Pan width + */ - // Master channel first - boost::shared_ptr strip = session->master_out(); + // Master channel first + boost::shared_ptr strip = session->master_out(); - boost::shared_ptr mute_controllable = boost::dynamic_pointer_cast(strip->mute_control()); - mute_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_change_message, this, X_("/master/mute"), strip->mute_control()), OSC::instance()); - send_change_message ("/master/mute", strip->mute_control()); + boost::shared_ptr mute_controllable = boost::dynamic_pointer_cast(strip->mute_control()); + mute_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_change_message, this, X_("/master/mute"), strip->mute_control()), OSC::instance()); + send_change_message ("/master/mute", strip->mute_control()); - boost::shared_ptr trim_controllable = boost::dynamic_pointer_cast(strip->trim_control()); + boost::shared_ptr trim_controllable = boost::dynamic_pointer_cast(strip->trim_control()); trim_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_trim_message, this, X_("/master/trimdB"), strip->trim_control()), OSC::instance()); send_trim_message ("/master/trimdB", strip->trim_control()); - boost::shared_ptr pan_controllable = boost::dynamic_pointer_cast(strip->pan_azimuth_control()); + boost::shared_ptr pan_controllable = boost::dynamic_pointer_cast(strip->pan_azimuth_control()); pan_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_change_message, this, X_("/master/pan_stereo_position"), strip->pan_azimuth_control()), OSC::instance()); send_change_message ("/master/pan_stereo_position", strip->pan_azimuth_control()); - boost::shared_ptr gain_controllable = boost::dynamic_pointer_cast(strip->gain_control()); - if (gainmode) { - gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/master/fader"), strip->gain_control()), OSC::instance()); - send_gain_message ("/master/fader", strip->gain_control()); - } else { - gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/master/gain"), strip->gain_control()), OSC::instance()); - send_gain_message ("/master/gain", strip->gain_control()); + boost::shared_ptr gain_controllable = boost::dynamic_pointer_cast(strip->gain_control()); + if (gainmode) { + gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/master/fader"), strip->gain_control()), OSC::instance()); + send_gain_message ("/master/fader", strip->gain_control()); + } else { + gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/master/gain"), strip->gain_control()), OSC::instance()); + send_gain_message ("/master/gain", strip->gain_control()); + } + + // monitor stuff next + /* + * Monitor (todo) + * Mute + * Dim + * Mono + * Rude Solo + * etc. + */ + strip = session->monitor_out(); + if (strip) { + + // Hmm, it seems the monitor mute is not at route->mute_control() + /*boost::shared_ptr mute_controllable2 = boost::dynamic_pointer_cast(strip->mute_control()); + //mute_controllable = boost::dynamic_pointer_cast(r2->mute_control()); + mute_controllable2->Changed.connect (monitor_mute_connection, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_change_message, this, X_("/monitor/mute"), strip->mute_control()), OSC::instance()); + send_change_message ("/monitor/mute", strip->mute_control()); + */ + gain_controllable = boost::dynamic_pointer_cast(strip->gain_control()); + if (gainmode) { + gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/monitor/fader"), strip->gain_control()), OSC::instance()); + send_gain_message ("/monitor/fader", strip->gain_control()); + } else { + gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/monitor/gain"), strip->gain_control()), OSC::instance()); + send_gain_message ("/monitor/gain", strip->gain_control()); + } + } + + /* + * Transport (todo) + * punchin/out + */ + //Transport feedback + session->TransportStateChange.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_transport_state_changed, this), OSC::instance()); + send_transport_state_changed (); + session->TransportLooped.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_transport_state_changed, this), OSC::instance()); + session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_record_state_changed, this), OSC::instance()); + send_record_state_changed (); + + // session feedback + session->StateSaved.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_session_saved, this, _1), OSC::instance()); + send_session_saved (session->snap_name()); + + /* + * Maybe (many) more + */ } - - // monitor stuff next - /* - * Monitor (todo) - * Mute - * Dim - * Mono - * Rude Solo - * etc. - */ - strip = session->monitor_out(); - - // Hmm, it seems the monitor mute is not at route->mute_control() - /*boost::shared_ptr mute_controllable2 = boost::dynamic_pointer_cast(strip->mute_control()); - //mute_controllable = boost::dynamic_pointer_cast(r2->mute_control()); - mute_controllable2->Changed.connect (monitor_mute_connection, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_change_message, this, X_("/monitor/mute"), strip->mute_control()), OSC::instance()); - send_change_message ("/monitor/mute", strip->mute_control()); - */ - gain_controllable = boost::dynamic_pointer_cast(strip->gain_control()); - if (gainmode) { - gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/monitor/fader"), strip->gain_control()), OSC::instance()); - send_gain_message ("/monitor/fader", strip->gain_control()); - } else { - gain_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCGlobalObserver::send_gain_message, this, X_("/monitor/gain"), strip->gain_control()), OSC::instance()); - send_gain_message ("/monitor/gain", strip->gain_control()); - } - - /* - * Transport (todo) - * punchin/out - */ - //Transport feedback - session->TransportStateChange.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_transport_state_changed, this), OSC::instance()); - send_transport_state_changed (); - session->TransportLooped.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_transport_state_changed, this), OSC::instance()); - session->RecordStateChanged.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_record_state_changed, this), OSC::instance()); - send_record_state_changed (); - - // session feedback - session->StateSaved.connect(session_connections, MISSING_INVALIDATOR, boost::bind (&OSCGlobalObserver::send_session_saved, this, _1), OSC::instance()); - send_session_saved (session->snap_name()); - - /* - * Maybe (many) more - */ } OSCGlobalObserver::~OSCGlobalObserver () diff --git a/libs/surfaces/osc/osc_route_observer.cc b/libs/surfaces/osc/osc_route_observer.cc index ff80dbe781..8f7abe2991 100644 --- a/libs/surfaces/osc/osc_route_observer.cc +++ b/libs/surfaces/osc/osc_route_observer.cc @@ -69,6 +69,7 @@ OSCRouteObserver::OSCRouteObserver (boost::shared_ptr s, lo_address a recsafe_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCRouteObserver::send_change_message, this, X_("/strip/record_safe"), _strip->rec_safe_control()), OSC::instance()); send_change_message ("/strip/record_safe", _strip->rec_safe_control()); } + send_select_status (); } if (feedback[1]) { // level controls @@ -119,6 +120,7 @@ OSCRouteObserver::~OSCRouteObserver () clear_strip ("/strip/record_safe", 0); clear_strip ("/strip/monitor_input", 0); clear_strip ("/strip/monitor_disk", 0); + clear_strip ("/strip/gui_select", 0); } if (feedback[1]) { // level controls if (gainmode) { @@ -359,3 +361,23 @@ OSCRouteObserver::clear_strip (string path, float val) lo_message_free (msg); } + +void +OSCRouteObserver::send_select_status () +{ + // waiting for _strip->is_selected to start working + if (_strip) { + string path = "/strip/gui_select"; + + lo_message msg = lo_message_new (); + if (feedback[2]) { + path = set_path (path); + } else { + lo_message_add_int32 (msg, ssid); + } + //std::cout << "strip: " << ssid << " strip name: " << _strip->name() << " select: " << _strip->is_selected() << "\n"; + lo_message_add_float (msg, _strip->is_selected()); + lo_send_message (addr, path.c_str(), msg); + lo_message_free (msg); + } +} diff --git a/libs/surfaces/osc/osc_route_observer.h b/libs/surfaces/osc/osc_route_observer.h index 220eb176ff..cef044a582 100644 --- a/libs/surfaces/osc/osc_route_observer.h +++ b/libs/surfaces/osc/osc_route_observer.h @@ -40,6 +40,7 @@ class OSCRouteObserver boost::shared_ptr strip () const { return _strip; } lo_address address() const { return addr; }; void tick (void); + void send_select_status (void); private: boost::shared_ptr _strip;