OSC: select commands for pan and trim added, feedback for select sends. GUI_select...
authorLen Ovens <len@ovenwerks.net>
Thu, 9 Jun 2016 06:08:56 +0000 (23:08 -0700)
committerLen Ovens <len@ovenwerks.net>
Thu, 9 Jun 2016 06:08:56 +0000 (23:08 -0700)
libs/surfaces/osc/osc.cc
libs/surfaces/osc/osc.h
libs/surfaces/osc/osc_route_observer.cc
libs/surfaces/osc/osc_select_observer.cc
libs/surfaces/osc/osc_select_observer.h

index f924788a4080191dc8db776419f617354c00d2ad..ff5c093758be5819ce81703f8336b188cf709147 100644 (file)
@@ -522,6 +522,8 @@ OSC::register_callbacks()
                REGISTER_CALLBACK (serv, "/select/monitor_disk", "i", sel_monitor_disk);
                REGISTER_CALLBACK (serv, "/select/gain", "f", sel_gain);
                REGISTER_CALLBACK (serv, "/select/fader", "f", sel_fader);
+               REGISTER_CALLBACK (serv, "/select/trimdB", "f", sel_trim);
+               REGISTER_CALLBACK (serv, "/select/pan_stereo_position", "f", sel_pan_position);
 
                /* These commands require the route index in addition to the arg; TouchOSC (et al) can't use these  */ 
                REGISTER_CALLBACK (serv, "/strip/mute", "ii", route_mute);
@@ -542,7 +544,8 @@ OSC::register_callbacks()
                // 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);
+               REGISTER_CALLBACK (serv, "/strip/send/gain", "iif", route_set_send_gain_dB);
+               REGISTER_CALLBACK (serv, "/strip/send/fader", "iif", route_set_send_fader);
 
                /* still not-really-standardized query interface */
                //REGISTER_CALLBACK (serv, "/ardour/*/#current_value", "", current_value);
@@ -1292,10 +1295,14 @@ OSC::set_bank (uint32_t bank_start, lo_message msg)
                        boost::shared_ptr<Stripable> stp = session->get_remote_nth_stripable (n - 1, PresentationInfo::Route);
 
                        if (stp) {
-                       listen_to_route(stp, lo_message_get_source (msg));
+                               listen_to_route(stp, lo_message_get_source (msg));
+                               if (!s->feedback[10]) {
+                                       if (stp->is_selected()) {
+                                               _strip_select (n, lo_message_get_source (msg));
+                                       }
+                               }
                        }
                }
-               // put in check for GUI_selects here.
        }
        return 0;
 }
@@ -1692,7 +1699,7 @@ OSC::_strip_select (int ssid, lo_address addr)
                delete sur->sel_obs;
                sur->sel_obs = 0;
        }
-               sur->surface_sel = 0;
+       sur->surface_sel = 0;
 
        if (s) {
                sur->surface_sel = ssid;
@@ -1706,22 +1713,28 @@ OSC::_strip_select (int ssid, lo_address addr)
                b_s = sur->nstrips;
        }
        for (int i = 1;  i <= b_s; i++) {
-                       if (i==(int)sur->surface_sel) {
-                               string path = "/strip/select";
-                               lo_message reply = lo_message_new ();
-                               if (sur->feedback[2]) {
-                                       ostringstream os;
-                                       os << path << "/" << ssid;
-                                       path = os.str();
-                               } else {
+               string path = "select";
+               if (!sur->feedback[10]) {
+                       path = "gui_select";
+               }
+               if (i==(int)sur->surface_sel) {
+                       lo_message reply = lo_message_new ();
+                       if (sur->feedback[2]) {
+                               ostringstream os;
+                               os << "/strip/" << path << "/" << ssid;
+                               path = os.str();
+                       } else {
+                               ostringstream os;
+                               os << "/strip/" << path;
+                               path = os.str();
                                lo_message_add_int32 (reply, ssid);
-                               }
+                       }
                                lo_message_add_float (reply, (float) 1);
 
                                lo_send_message (addr, path.c_str(), reply);
                                lo_message_free (reply);
                        } else {
-                               route_send_fail ("select", i, 0, addr);
+                               route_send_fail (path, i, 0, addr);
                        }
        }
 
@@ -1738,17 +1751,12 @@ OSC::strip_gui_select (int ssid, int yn, lo_message msg)
                route_send_fail ("gui_select", ssid, 0, lo_message_get_source (msg));
                return -1;
        }
-       int ret = strip_select (ssid, yn, msg);
-       if (ret != 0) {
-               return ret;
-       }
+
        int rid = get_rid (ssid, lo_message_get_source (msg));
        boost::shared_ptr<Stripable> s = session->get_remote_nth_stripable (rid, PresentationInfo::Route);
-       //OSCSurface *sur = get_surface(lo_message_get_source (msg));
-
        if (s) {
-               //s->set_select();
-               //sur->surface_sel = ssid;
+       //SetStripableSelection ((*s)->presentation_info().order());
+               SetStripableSelection (rid); //alt above may end up being better
        } else {
                route_send_fail ("gui_select", ssid, 0, lo_message_get_source (msg));
        }
@@ -1855,6 +1863,27 @@ OSC::route_set_trim_dB (int ssid, float dB, lo_message msg)
        return route_set_trim_abs(ssid, dB_to_coefficient (dB), msg);
 }
 
+int
+OSC::sel_trim (float val, lo_message msg)
+{
+       OSCSurface *sur = get_surface(lo_message_get_source (msg));
+       if (sur->surface_sel) {
+               return route_set_trim_dB (sur->surface_sel, val, msg);
+       } else { 
+               return route_send_fail ("trimdB", 0, 0, lo_message_get_source (msg));
+       }
+}
+
+int
+OSC::sel_pan_position (float val, lo_message msg)
+{
+       OSCSurface *sur = get_surface(lo_message_get_source (msg));
+       if (sur->surface_sel) {
+               return route_set_pan_stereo_position (sur->surface_sel, val, msg);
+       } else { 
+               return route_send_fail ("pan_stereo_position", 0, 0, lo_message_get_source (msg));
+       }
+}
 
 int
 OSC::route_set_pan_stereo_position (int ssid, float pos, lo_message msg)
@@ -1925,6 +1954,21 @@ OSC::route_set_send_gain_dB (int ssid, int sid, float val, lo_message msg)
        return route_set_send_gain_abs (ssid, sid, dB_to_coefficient (val), msg);
 }
 
+int
+OSC::route_set_send_fader (int ssid, int sid, float pos, lo_message msg)
+{
+       if (!session) {
+               return -1;
+       }
+       int ret;
+       if ((pos > 799.5) && (pos < 800.5)) {
+               ret = route_set_send_gain_abs (ssid, sid, 1.0, msg);
+       } else {
+               ret = route_set_send_gain_abs (ssid, sid, slider_position_to_gain_with_max ((pos/1023), 2.0), msg);
+       }
+       return ret;
+}
+
 int
 OSC::route_plugin_parameter (int ssid, int piid, int par, float val, lo_message msg)
 {
index aea4dd1dc64ddd753cb70a106c4dba6beecc195b..55a0a09aedeb1feee931dd0d88d59805160699f0 100644 (file)
@@ -335,6 +335,8 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
        PATH_CALLBACK1_MSG(sel_monitor_disk,i);
        PATH_CALLBACK1_MSG(sel_gain,f);
        PATH_CALLBACK1_MSG(sel_fader,f);
+       PATH_CALLBACK1_MSG(sel_trim,f);
+       PATH_CALLBACK1_MSG(sel_pan_position,f);
 
 #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) { \
@@ -404,6 +406,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
        PATH_CALLBACK2_MSG(route_set_pan_stereo_width,i,f);
        PATH_CALLBACK3(route_set_send_gain_abs,i,i,f);
        PATH_CALLBACK3(route_set_send_gain_dB,i,i,f);
+       PATH_CALLBACK3(route_set_send_fader,i,i,f);
        PATH_CALLBACK4(route_plugin_parameter,i,i,i,f);
        PATH_CALLBACK3(route_plugin_parameter_print,i,i,i);
 
@@ -425,6 +428,7 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
        int route_set_pan_stereo_width (int rid, float percent, lo_message msg);
        int route_set_send_gain_abs (int rid, int sid, float val, lo_message msg);
        int route_set_send_gain_dB (int rid, int sid, float val, lo_message msg);
+       int route_set_send_fader (int rid, int sid, float val, lo_message msg);
        int route_plugin_parameter (int rid, int piid,int par, float val, lo_message msg);
        int route_plugin_parameter_print (int rid, int piid,int par, lo_message msg);
 
@@ -453,6 +457,8 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
        int sel_monitor_disk (uint32_t state, lo_message msg);
        int sel_gain (float state, lo_message msg);
        int sel_fader (float state, lo_message msg);
+       int sel_trim (float val, lo_message msg);
+       int sel_pan_position (float val, lo_message msg);
 
        void listen_to_route (boost::shared_ptr<ARDOUR::Stripable>, lo_address);
        void end_listen (boost::shared_ptr<ARDOUR::Stripable>, lo_address);
index f0758ba71a0e063299f88f3a5325b5497adcbe2c..e077fc923aa2d0863eab8b429e5a569b8f9d713a 100644 (file)
@@ -69,7 +69,9 @@ OSCRouteObserver::OSCRouteObserver (boost::shared_ptr<Stripable> 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[10]) {
+                       send_select_status ();
+               }
        }
 
        if (feedback[1]) { // level controls
index 37c5f16b42f3da421bfdca53bcdfdd8d61cb6876..06decb7e324c54911aa7e91b9f210597c411a451 100644 (file)
@@ -40,6 +40,7 @@ OSCSelectObserver::OSCSelectObserver (boost::shared_ptr<Stripable> s, lo_address
        ,ssid (ss)
        ,gainmode (gm)
        ,feedback (fb)
+       ,nsends (0)
 {
        addr = lo_address_new (lo_address_get_hostname(a) , lo_address_get_port(a));
 
@@ -91,6 +92,10 @@ OSCSelectObserver::OSCSelectObserver (boost::shared_ptr<Stripable> s, lo_address
                        pan_controllable->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCSelectObserver::send_change_message, this, X_("/select/pan_stereo_position"), _strip->pan_azimuth_control()), OSC::instance());
                        send_change_message ("/select/pan_stereo_position", _strip->pan_azimuth_control());
                }
+               // detecting processor changes requires cast to route
+               boost::shared_ptr<Route> r = boost::dynamic_pointer_cast<Route>(_strip);
+               r->processors_changed.connect  (strip_connections, MISSING_INVALIDATOR, bind (&OSCSelectObserver::send_restart, this, -1), OSC::instance());
+               send_init();
        }
        tick();
 }
@@ -135,10 +140,105 @@ OSCSelectObserver::~OSCSelectObserver ()
        }else if (feedback[8]) {
                clear_strip ("/select/meter", 0);
        }
+       send_end();
 
        lo_address_free (addr);
 }
 
+void
+OSCSelectObserver::send_init()
+{
+       // we don't know how many there are, so find out.
+       bool sends;
+       do {
+               sends = false;
+               if (_strip->send_level_controllable (nsends)) {
+                       _strip->send_level_controllable(nsends)->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCSelectObserver::send_gain, this, X_("/select/send_gain"), nsends, _strip->send_level_controllable(nsends)), OSC::instance());
+                       send_gain ("/select/send_gain", nsends, _strip->send_level_controllable(nsends));
+                       sends = true;
+               }
+
+               if (_strip->send_enable_controllable (nsends)) {
+                       _strip->send_enable_controllable(nsends)->Changed.connect (strip_connections, MISSING_INVALIDATOR, bind (&OSCSelectObserver::send_enable, this, X_("/select/send_enable"), nsends, _strip->send_enable_controllable(nsends)), OSC::instance());
+                       send_enable ("/select/send_enable", nsends, _strip->send_enable_controllable(nsends));
+                       sends = true;
+               } else if (sends) {
+                       // not used by Ardour, just mixbus so in Ardour always true
+                       lo_message msg = lo_message_new ();
+                       path = "/select/send_enable";
+                       if (feedback[2]) {
+                               path = set_path (path, nsends + 1);
+                       } else {
+                               lo_message_add_int32 (msg, nsends + 1);
+                       }
+                       lo_message_add_int32 (msg, 1);
+                       lo_send_message (addr, path.c_str(), msg);
+                       lo_message_free (msg);
+                       }
+
+               if (sends) { // if the gain control is there, this is too
+                       send_rename ("/select/send_name", nsends, _strip->send_name(nsends));
+               }
+               // Send numbers are 0 based, OSC is 1 based so this gets incremented at the end
+               if (sends) {
+                       nsends++;
+               }
+       } while (sends);
+}
+
+void
+OSCSelectObserver::send_end ()
+{
+       send_connections.drop_connections ();
+       for (uint32_t i = 1; i <= nsends; i++) {
+               lo_message msg = lo_message_new ();
+               string path = "/select/send_gain";
+               if (feedback[2]) {
+                       path = set_path (path, i);
+               } else {
+                       lo_message_add_int32 (msg, i);
+               }
+
+               if (gainmode) {
+                       lo_message_add_int32 (msg, 0);
+               } else {
+                       lo_message_add_float (msg, -193);
+               }
+               lo_send_message (addr, path.c_str(), msg);
+               lo_message_free (msg);
+               // next enable
+               msg = lo_message_new ();
+               path = "/select/send_enable";
+               if (feedback[2]) {
+                       path = set_path (path, i);
+               } else {
+                       lo_message_add_int32 (msg, i);
+               }
+               lo_message_add_int32 (msg, 0);
+               lo_send_message (addr, path.c_str(), msg);
+               lo_message_free (msg);
+               // next name
+               msg = lo_message_new ();
+               path = "/select/send_name";
+               if (feedback[2]) {
+                       path = set_path (path, i);
+               } else {
+                       lo_message_add_int32 (msg, i);
+               }
+               lo_message_add_string (msg, " ");
+               lo_send_message (addr, path.c_str(), msg);
+               lo_message_free (msg);
+       }
+       nsends = 0;
+}
+
+void
+OSCSelectObserver::send_restart(int x)
+{
+       send_end();
+       send_init();
+}
+
 void
 OSCSelectObserver::tick ()
 {
@@ -290,12 +390,73 @@ OSCSelectObserver::send_gain_message (string path, boost::shared_ptr<Controllabl
        lo_message_free (msg);
 }
 
+void
+OSCSelectObserver::send_gain (std::string path, uint32_t id, boost::shared_ptr<PBD::Controllable> controllable)
+{
+       lo_message msg = lo_message_new ();
+
+       if (feedback[2]) {
+               path = set_path (path, id + 1);
+       } else {
+               lo_message_add_int32 (msg, id + 1);
+       }
+
+       if (gainmode) {
+               if (controllable->get_value() == 1) {
+                       lo_message_add_int32 (msg, 800);
+               } else {
+                       lo_message_add_int32 (msg, gain_to_slider_position (controllable->get_value()) * 1023);
+               }
+       } else {
+               if (controllable->get_value() < 1e-15) {
+                       lo_message_add_float (msg, -200);
+               } else {
+                       lo_message_add_float (msg, accurate_coefficient_to_dB (controllable->get_value()));
+               }
+       }
+
+       lo_send_message (addr, path.c_str(), msg);
+       lo_message_free (msg);
+}
+
+void
+OSCSelectObserver::send_enable (string path, uint32_t id, boost::shared_ptr<Controllable> controllable)
+{
+       lo_message msg = lo_message_new ();
+       if (feedback[2]) {
+               path = set_path (path, id + 1);
+       } else {
+               lo_message_add_int32 (msg, id + 1);
+       }
+
+       lo_message_add_float (msg, (float) controllable->get_value());
+
+       lo_send_message (addr, path.c_str(), msg);
+       lo_message_free (msg);
+}
+
+void
+OSCSelectObserver::send_rename (string path, uint32_t id, string name)
+{
+       lo_message msg = lo_message_new ();
+       if (feedback[2]) {
+               path = set_path (path, id + 1);
+       } else {
+               lo_message_add_int32 (msg, id + 1);
+       }
+
+       lo_message_add_string (msg, name.c_str());
+
+       lo_send_message (addr, path.c_str(), msg);
+       lo_message_free (msg);
+}
+
 string
-OSCSelectObserver::set_path (string path)
+OSCSelectObserver::set_path (string path, uint32_t id)
 {
        if (feedback[2]) {
   ostringstream os;
-  os << path << "/" << ssid;
+  os << path << "/" << id;
   path = os.str();
        }
        return path;
index 66b4f04d6fa8528a2ab4d1090d11025f7a6f403c..3d64957577aeac09f438f317bb3a2b9677f8ec02 100644 (file)
@@ -45,6 +45,8 @@ class OSCSelectObserver
        boost::shared_ptr<ARDOUR::Stripable> _strip;
 
        PBD::ScopedConnectionList strip_connections;
+       // sends need their own
+       PBD::ScopedConnectionList send_connections;
 
        lo_address addr;
        std::string path;
@@ -52,6 +54,7 @@ class OSCSelectObserver
        uint32_t gainmode;
        std::bitset<32> feedback;
        float _last_meter;
+       uint32_t nsends;
 
 
        void name_changed (const PBD::PropertyChange& what_changed);
@@ -59,7 +62,14 @@ class OSCSelectObserver
        void send_monitor_status (boost::shared_ptr<PBD::Controllable> controllable);
        void send_gain_message (std::string path, boost::shared_ptr<PBD::Controllable> controllable);
        void send_trim_message (std::string path, boost::shared_ptr<PBD::Controllable> controllable);
-       std::string set_path (std::string path);
+       // sends stuff
+       void send_init (void);
+       void send_end (void);
+       void send_restart (int);
+       void send_gain (std::string path, uint32_t id, boost::shared_ptr<PBD::Controllable> controllable);
+       void send_enable (std::string path, uint32_t id, boost::shared_ptr<PBD::Controllable> controllable);
+       void send_rename (std::string path, uint32_t id, std::string name);
+       std::string set_path (std::string path, uint32_t id);
        void clear_strip (std::string path, float val);
 };