OSC: Further fixes so multiple controls can touch at once.
[ardour.git] / libs / surfaces / osc / osc.cc
index ff9e8aaf90ae4eeea612c650e6b1af9fff0000d4..70b02a7501c324e83cd3f053283c434bfd0591ef 100644 (file)
@@ -2335,20 +2335,38 @@ OSC::touch_detect (const char *path, lo_arg **argv, int argc, lo_message msg)
                if (control) {
                        if (touch) {
                                //start touch
-                               if (!control->touching ()) {
+                               if (control->automation_state() == Touch && !control->touching ()) {
                                        control->start_touch (control->session().transport_frame());
                                }
                        } else {
                                // end touch
                                control->stop_touch (true, control->session().transport_frame());
                        }
-
+                       // just in case some crazy surface starts sending control values before touch
+                       FakeTouchMap::iterator x = _touch_timeout.find(control);
+                       if (x != _touch_timeout.end()) {
+                               _touch_timeout.erase (x);
+                       }
                }
        }
 
        return ret;
 }
 
+int
+OSC::fake_touch (boost::shared_ptr<ARDOUR::AutomationControl> ctrl)
+{
+       if (ctrl) {
+               //start touch
+               if (ctrl->automation_state() == Touch && !ctrl->touching ()) {
+               ctrl->start_touch (ctrl->session().transport_frame());
+               _touch_timeout[ctrl] = 10;
+               }
+       }
+
+       return 0;
+}
+
 int
 OSC::route_mute (int ssid, int yn, lo_message msg)
 {
@@ -2834,6 +2852,7 @@ OSC::route_set_gain_abs (int ssid, float level, lo_message msg)
 
        if (s) {
                if (s->gain_control()) {
+                       fake_touch (s->gain_control());
                        s->gain_control()->set_value (level, PBD::Controllable::NoGroup);
                } else {
                        return 1;
@@ -2882,6 +2901,7 @@ OSC::sel_gain (float val, lo_message msg)
                        abs = dB_to_coefficient (val);
                }
                if (s->gain_control()) {
+                       fake_touch (s->gain_control());
                        s->gain_control()->set_value (abs, PBD::Controllable::NoGroup);
                        return 0;
                }
@@ -2918,6 +2938,7 @@ OSC::sel_fader (float val, lo_message msg)
                float abs;
                abs = slider_position_to_gain_with_max (val, 2.0);
                if (s->gain_control()) {
+                       fake_touch (s->gain_control());
                        s->gain_control()->set_value (abs, PBD::Controllable::NoGroup);
                        return 0;
                }
@@ -3952,6 +3973,17 @@ OSC::periodic (void)
                        co->tick();
                }
        }
+       for (FakeTouchMap::iterator x = _touch_timeout.begin(); x != _touch_timeout.end();) {
+               _touch_timeout[(*x).first] = (*x).second - 1;
+               if (!(*x).second) {
+                       boost::shared_ptr<ARDOUR::AutomationControl> ctrl = (*x).first;
+                       // turn touch off
+                       ctrl->stop_touch (true, ctrl->session().transport_frame());
+                       _touch_timeout.erase (x++);
+               } else {
+                       x++;
+               }
+       }
        return true;
 }