MCP: Momentarily light buttons when they are used to trigger a defined action.
[ardour.git] / libs / surfaces / mackie / strip.cc
index 2428681d9e6bc8ac16d9a164218c70e5f749b3e3..9a570f8227dd31c3eacf5921260a07d85f076aa6 100644 (file)
 #include "ardour/debug.h"
 #include "ardour/midi_ui.h"
 #include "ardour/meter.h"
+#include "ardour/monitor_control.h"
 #include "ardour/plugin_insert.h"
 #include "ardour/pannable.h"
 #include "ardour/panner.h"
 #include "ardour/panner_shell.h"
+#include "ardour/phase_control.h"
 #include "ardour/rc_configuration.h"
+#include "ardour/record_enable_control.h"
 #include "ardour/route.h"
 #include "ardour/session.h"
 #include "ardour/send.h"
+#include "ardour/solo_isolate_control.h"
 #include "ardour/track.h"
 #include "ardour/midi_track.h"
 #include "ardour/user_bundle.h"
@@ -163,7 +167,7 @@ Strip::add (Control & control)
 }
 
 void
-Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
+Strip::set_stripable (boost::shared_ptr<Stripable> r, bool /*with_messages*/)
 {
        if (_controls_locked) {
                return;
@@ -171,7 +175,7 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
 
        mb_pan_controllable.reset();
 
-       route_connections.drop_connections ();
+       stripable_connections.drop_connections ();
 
        _solo->set_control (boost::shared_ptr<AutomationControl>());
        _mute->set_control (boost::shared_ptr<AutomationControl>());
@@ -180,69 +184,68 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
        _fader->set_control (boost::shared_ptr<AutomationControl>());
        _vpot->set_control (boost::shared_ptr<AutomationControl>());
 
-       _route = r;
+       _stripable = r;
 
        reset_saved_values ();
 
        if (!r) {
+               DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 Strip %2 mapped to null route\n", _surface->number(), _index));
                zero ();
                return;
        }
 
-       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 strip %2 now mapping route %3\n",
-                                                          _surface->number(), _index, _route->name()));
+       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 strip %2 now mapping stripable %3\n",
+                                                          _surface->number(), _index, _stripable->name()));
 
-       _solo->set_control (_route->solo_control());
-       _mute->set_control (_route->mute_control());
+       _solo->set_control (_stripable->solo_control());
+       _mute->set_control (_stripable->mute_control());
 
-       _route->solo_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_solo_changed, this), ui_context());
-       _route->listen_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_solo_changed, this), ui_context());
+       _stripable->solo_control()->Changed.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_solo_changed, this), ui_context());
+       _stripable->mute_control()->Changed.connect(stripable_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_mute_changed, this), ui_context());
 
-       _route->mute_control()->Changed.connect(route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_mute_changed, this), ui_context());
-
-       boost::shared_ptr<AutomationControl> pan_control = _route->pan_azimuth_control();
+       boost::shared_ptr<AutomationControl> pan_control = _stripable->pan_azimuth_control();
        if (pan_control) {
-               pan_control->Changed.connect(route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_panner_azi_changed, this, false), ui_context());
+               pan_control->Changed.connect(stripable_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_panner_azi_changed, this, false), ui_context());
        }
 
-       pan_control = _route->pan_width_control();
+       pan_control = _stripable->pan_width_control();
        if (pan_control) {
-               pan_control->Changed.connect(route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_panner_width_changed, this, false), ui_context());
+               pan_control->Changed.connect(stripable_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_panner_width_changed, this, false), ui_context());
        }
 
-       _route->gain_control()->Changed.connect(route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_gain_changed, this, false), ui_context());
-       _route->PropertyChanged.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_property_changed, this, _1), ui_context());
+       _stripable->gain_control()->Changed.connect(stripable_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_gain_changed, this, false), ui_context());
+       _stripable->PropertyChanged.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_property_changed, this, _1), ui_context());
+       _stripable->presentation_info().PropertyChanged.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_property_changed, this, _1), ui_context());
 
-       boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<ARDOUR::Track>(_route);
+       boost::shared_ptr<AutomationControl> rec_enable_control = _stripable->rec_enable_control ();
 
-       if (trk) {
-               _recenable->set_control (trk->rec_enable_control());
-               trk->rec_enable_control()->Changed .connect(route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_record_enable_changed, this), ui_context());
+       if (rec_enable_control) {
+               _recenable->set_control (rec_enable_control);
+               rec_enable_control->Changed.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_record_enable_changed, this), ui_context());
        }
 
-       // TODO this works when a currently-banked route is made inactive, but not
-       // when a route is activated which should be currently banked.
+       // TODO this works when a currently-banked stripable is made inactive, but not
+       // when a stripable is activated which should be currently banked.
 
-       _route->active_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_active_changed, this), ui_context());
-       _route->DropReferences.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_route_deleted, this), ui_context());
+       _stripable->DropReferences.connect (stripable_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_stripable_deleted, this), ui_context());
 
-       /* setup legal VPot modes for this route */
+       /* setup legal VPot modes for this stripable */
 
        possible_pot_parameters.clear();
 
-       if (_route->pan_azimuth_control()) {
+       if (_stripable->pan_azimuth_control()) {
                possible_pot_parameters.push_back (PanAzimuthAutomation);
        }
-       if (_route->pan_width_control()) {
+       if (_stripable->pan_width_control()) {
                possible_pot_parameters.push_back (PanWidthAutomation);
        }
-       if (_route->pan_elevation_control()) {
+       if (_stripable->pan_elevation_control()) {
                possible_pot_parameters.push_back (PanElevationAutomation);
        }
-       if (_route->pan_frontback_control()) {
+       if (_stripable->pan_frontback_control()) {
                possible_pot_parameters.push_back (PanFrontBackAutomation);
        }
-       if (_route->pan_lfe_control()) {
+       if (_stripable->pan_lfe_control()) {
                possible_pot_parameters.push_back (PanLFEAutomation);
        }
 
@@ -252,7 +255,7 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
                set_vpot_parameter (_pan_mode);
        }
 
-       _fader->set_control (_route->gain_control());
+       _fader->set_control (_stripable->gain_control());
 
        notify_all ();
 }
@@ -260,7 +263,7 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
 void
 Strip::notify_all()
 {
-       if (!_route) {
+       if (!_stripable) {
                zero ();
                return;
        }
@@ -273,6 +276,7 @@ Strip::notify_all()
        notify_mute_changed ();
        notify_gain_changed ();
        notify_property_changed (PBD::PropertyChange (ARDOUR::Properties::name));
+       notify_property_changed (PBD::PropertyChange (ARDOUR::Properties::selected));
        notify_panner_azi_changed ();
        notify_panner_width_changed ();
        notify_record_enable_changed ();
@@ -282,8 +286,8 @@ Strip::notify_all()
 void
 Strip::notify_solo_changed ()
 {
-       if (_route && _solo) {
-               _surface->write (_solo->set_state ((_route->soloed() || _route->listening_via_monitor()) ? on : off));
+       if (_stripable && _solo) {
+               _surface->write (_solo->set_state (_stripable->solo_control()->soloed() ? on : off));
        }
 }
 
@@ -291,42 +295,40 @@ void
 Strip::notify_mute_changed ()
 {
        DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Strip %1 mute changed\n", _index));
-       if (_route && _mute) {
-               DEBUG_TRACE (DEBUG::MackieControl, string_compose ("\troute muted ? %1\n", _route->muted()));
-               DEBUG_TRACE (DEBUG::MackieControl, string_compose ("mute message: %1\n", _mute->set_state (_route->muted() ? on : off)));
+       if (_stripable && _mute) {
+               DEBUG_TRACE (DEBUG::MackieControl, string_compose ("\tstripable muted ? %1\n", _stripable->mute_control()->muted()));
+               DEBUG_TRACE (DEBUG::MackieControl, string_compose ("mute message: %1\n", _mute->set_state (_stripable->mute_control()->muted() ? on : off)));
 
-               _surface->write (_mute->set_state (_route->muted() ? on : off));
+               _surface->write (_mute->set_state (_stripable->mute_control()->muted() ? on : off));
        }
 }
 
 void
 Strip::notify_record_enable_changed ()
 {
-       if (_route && _recenable)  {
-               _surface->write (_recenable->set_state (_route->record_enabled() ? on : off));
+       if (_stripable && _recenable)  {
+               boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<Track> (_stripable);
+               if (trk) {
+                       _surface->write (_recenable->set_state (trk->rec_enable_control()->get_value() ? on : off));
+               }
        }
 }
 
 void
-Strip::notify_active_changed ()
-{
-       _surface->mcp().refresh_current_bank();
-}
-
-void
-Strip::notify_route_deleted ()
+Strip::notify_stripable_deleted ()
 {
+       _surface->mcp().notify_stripable_removed ();
        _surface->mcp().refresh_current_bank();
 }
 
 void
 Strip::notify_gain_changed (bool force_update)
 {
-       if (!_route) {
+       if (!_stripable) {
                return;
        }
 
-       boost::shared_ptr<AutomationControl> ac = _route->gain_control();
+       boost::shared_ptr<AutomationControl> ac = _stripable->gain_control();
        Control* control;
 
        if (!ac) {
@@ -372,15 +374,20 @@ Strip::notify_processor_changed (bool force_update)
 void
 Strip::notify_property_changed (const PropertyChange& what_changed)
 {
-       if (!what_changed.contains (ARDOUR::Properties::name)) {
-               return;
+       if (what_changed.contains (ARDOUR::Properties::name)) {
+               show_stripable_name ();
        }
 
-       show_route_name ();
+       if (what_changed.contains (ARDOUR::Properties::selected)) {
+               if (_stripable) {
+                       _surface->write (_select->set_state (_stripable->is_selected()));
+                       _surface->mcp().update_selected (_stripable, _stripable->is_selected());
+               }
+       }
 }
 
 void
-Strip::show_route_name ()
+Strip::show_stripable_name ()
 {
        MackieControlProtocol::SubViewMode svm = _surface->mcp().subview_mode();
 
@@ -390,29 +397,23 @@ Strip::show_route_name ()
        }
 
        string fullname = string();
-       if (!_route) {
-               // make sure first three strips get cleared of view mode
-               if (_index > 2) {
-                       return;
-               }
+       if (!_stripable) {
+               fullname = string();
        } else {
-               fullname = _route->name();
+               fullname = _stripable->name();
        }
-       string line1;
 
        if (fullname.length() <= 6) {
-               line1 = fullname;
+               pending_display[0] = fullname;
        } else {
-               line1 = PBD::short_version (fullname, 6);
+               pending_display[0] = PBD::short_version (fullname, 6);
        }
-
-       pending_display[0] = line1;
 }
 
 void
 Strip::notify_send_level_change (AutomationType type, uint32_t send_num, bool force_update)
 {
-       boost::shared_ptr<Route> r = _surface->mcp().subview_route();
+       boost::shared_ptr<Stripable> r = _surface->mcp().subview_stripable();
 
        if (!r) {
                /* not in subview mode */
@@ -443,7 +444,7 @@ Strip::notify_send_level_change (AutomationType type, uint32_t send_num, bool fo
 void
 Strip::notify_trackview_change (AutomationType type, uint32_t send_num, bool force_update)
 {
-       boost::shared_ptr<Route> r = _surface->mcp().subview_route();
+       boost::shared_ptr<Stripable> r = _surface->mcp().subview_stripable();
 
        if (!r) {
                /* not in subview mode */
@@ -497,7 +498,7 @@ Strip::notify_trackview_change (AutomationType type, uint32_t send_num, bool for
 void
 Strip::notify_eq_change (AutomationType type, uint32_t band, bool force_update)
 {
-       boost::shared_ptr<Route> r = _surface->mcp().subview_route();
+       boost::shared_ptr<Stripable> r = _surface->mcp().subview_stripable();
 
        if (!r) {
                /* not in subview mode */
@@ -545,7 +546,7 @@ Strip::notify_eq_change (AutomationType type, uint32_t band, bool force_update)
 void
 Strip::notify_dyn_change (AutomationType type, bool force_update, bool propagate_mode)
 {
-       boost::shared_ptr<Route> r = _surface->mcp().subview_route();
+       boost::shared_ptr<Stripable> r = _surface->mcp().subview_stripable();
 
        if (!r) {
                /* not in subview mode */
@@ -574,9 +575,6 @@ Strip::notify_dyn_change (AutomationType type, bool force_update, bool propagate
        case CompMakeup:
                control = r->comp_makeup_controllable ();
                break;
-       case CompRedux:
-               control = r->comp_redux_controllable ();
-               break;
        case CompEnable:
                control = r->comp_enable_controllable ();
                break;
@@ -599,13 +597,13 @@ Strip::notify_dyn_change (AutomationType type, bool force_update, bool propagate
 void
 Strip::notify_panner_azi_changed (bool force_update)
 {
-       if (!_route) {
+       if (!_stripable) {
                return;
        }
 
        DEBUG_TRACE (DEBUG::MackieControl, string_compose ("pan change for strip %1\n", _index));
 
-       boost::shared_ptr<AutomationControl> pan_control = _route->pan_azimuth_control ();
+       boost::shared_ptr<AutomationControl> pan_control = _stripable->pan_azimuth_control ();
 
        if (!pan_control) {
                /* basically impossible, since we're here because that control
@@ -634,13 +632,13 @@ Strip::notify_panner_azi_changed (bool force_update)
 void
 Strip::notify_panner_width_changed (bool force_update)
 {
-       if (!_route) {
+       if (!_stripable) {
                return;
        }
 
        DEBUG_TRACE (DEBUG::MackieControl, string_compose ("pan width change for strip %1\n", _index));
 
-       boost::shared_ptr<AutomationControl> pan_control = _route->pan_width_control ();
+       boost::shared_ptr<AutomationControl> pan_control = _stripable->pan_width_control ();
 
        if (!pan_control) {
                /* basically impossible, since we're here because that control
@@ -680,18 +678,9 @@ Strip::select_event (Button&, ButtonState bs)
                        return;
                }
 
-               if (ms & MackieControlProtocol::MODIFIER_SHIFT) {
-                       /* reset to default */
-                       boost::shared_ptr<AutomationControl> ac = _fader->control ();
-                       if (ac) {
-                               ac->set_value (ac->normal(), Controllable::NoGroup);
-                       }
-                       return;
-               }
-
                DEBUG_TRACE (DEBUG::MackieControl, "add select button on press\n");
                _surface->mcp().add_down_select_button (_surface->number(), _index);
-               _surface->mcp().select_range ();
+               _surface->mcp().select_range (_surface->mcp().global_index (*this));
 
        } else {
                DEBUG_TRACE (DEBUG::MackieControl, "remove select button on release\n");
@@ -747,7 +736,7 @@ Strip::vselect_event (Button&, ButtonState bs)
                         * explicitly.
                         */
 
-                       boost::shared_ptr<Route> r = _surface->mcp().subview_route();
+                       boost::shared_ptr<Stripable> r = _surface->mcp().subview_stripable();
 
                        if (r) {
 
@@ -772,7 +761,7 @@ Strip::vselect_event (Button&, ButtonState bs)
                                        } else {
                                                /* we just turned it on, show the level
                                                */
-                                               control = _route->send_level_controllable (global_pos);
+                                               control = _stripable->send_level_controllable (global_pos);
                                                do_parameter_display (BusSendLevel, control->get_value());
                                        }
                                }
@@ -801,8 +790,8 @@ Strip::vselect_event (Button&, ButtonState bs)
                }  else {
 
 #ifdef MIXBUS
-                       if (_route) {
-                               boost::shared_ptr<AutomationControl> ac = _route->master_send_enable_controllable ();
+                       if (_stripable) {
+                               boost::shared_ptr<AutomationControl> ac = _stripable->master_send_enable_controllable ();
                                if (ac) {
                                        Controllable::GroupControlDisposition gcd;
 
@@ -890,7 +879,8 @@ Strip::handle_button (Button& button, ButtonState bs)
                                 * several down buttons
                                 */
 
-                               MackieControlProtocol::ControlList controls = _surface->mcp().down_controls ((AutomationType) control->parameter().type());
+                               MackieControlProtocol::ControlList controls = _surface->mcp().down_controls ((AutomationType) control->parameter().type(),
+                                                                                                            _surface->mcp().global_index(*this));
 
 
                                DEBUG_TRACE (DEBUG::MackieControl, string_compose ("there are %1 buttons down for control type %2, new value = %3\n",
@@ -927,7 +917,6 @@ Strip::do_parameter_display (AutomationType type, float val)
 
        switch (type) {
        case GainAutomation:
-       case BusSendLevel:
                if (val == 0.0) {
                        pending_display[1] = " -inf ";
                } else {
@@ -938,16 +927,33 @@ Strip::do_parameter_display (AutomationType type, float val)
                }
                break;
 
+       case BusSendLevel:
+               if (Profile->get_mixbus()) {  //Mixbus sends are already stored in dB
+                       snprintf (buf, sizeof (buf), "%2.1f", val);
+                       pending_display[1] = buf;
+                       screen_hold = true;
+               } else {
+                       if (val == 0.0) {
+                               pending_display[1] = " -inf ";
+                       } else {
+                               float dB = accurate_coefficient_to_dB (val);
+                               snprintf (buf, sizeof (buf), "%6.1f", dB);
+                               pending_display[1] = buf;
+                               screen_hold = true;
+                       }
+               }
+               break;
+
        case PanAzimuthAutomation:
                if (Profile->get_mixbus()) {
                        snprintf (buf, sizeof (buf), "%2.1f", val);
                        pending_display[1] = buf;
                        screen_hold = true;
                } else {
-                       if (_route) {
-                               boost::shared_ptr<Pannable> p = _route->pannable();
-                               if (p && _route->panner()) {
-                                       pending_display[1] =_route->panner()->value_as_string (p->pan_azimuth_control);
+                       if (_stripable) {
+                               boost::shared_ptr<AutomationControl> pa = _stripable->pan_azimuth_control();
+                               if (pa) {
+                                       pending_display[1] = pa->get_user_string ();
                                        screen_hold = true;
                                }
                        }
@@ -955,7 +961,7 @@ Strip::do_parameter_display (AutomationType type, float val)
                break;
 
        case PanWidthAutomation:
-               if (_route) {
+               if (_stripable) {
                        snprintf (buf, sizeof (buf), "%5ld%%", lrintf ((val * 200.0)-100));
                        pending_display[1] = buf;
                        screen_hold = true;
@@ -963,7 +969,7 @@ Strip::do_parameter_display (AutomationType type, float val)
                break;
 
        case TrimAutomation:
-               if (_route) {
+               if (_stripable) {
                        float dB = accurate_coefficient_to_dB (val);
                        snprintf (buf, sizeof (buf), "%6.1f", dB);
                        pending_display[1] = buf;
@@ -972,7 +978,7 @@ Strip::do_parameter_display (AutomationType type, float val)
                break;
 
        case PhaseAutomation:
-               if (_route) {
+               if (_stripable) {
                        if (val < 0.5) {
                                pending_display[1] = "Normal";
                        } else {
@@ -1004,8 +1010,8 @@ Strip::do_parameter_display (AutomationType type, float val)
                }
                break;
        case CompMode:
-               if (_surface->mcp().subview_route()) {
-                       pending_display[1] = _surface->mcp().subview_route()->comp_mode_name (val);
+               if (_surface->mcp().subview_stripable()) {
+                       pending_display[1] = _surface->mcp().subview_stripable()->comp_mode_name (val);
                }
                break;
        case SoloSafeAutomation:
@@ -1133,14 +1139,14 @@ Strip::handle_pot (Pot& pot, float delta)
 
        } else {
 
-               double p = ac->get_value();
+               double p = ac->get_interface();
 
                p += delta;
 
-               p = max (ac->lower(), p);
-               p = min (ac->upper(), p);
+               p = max (0.0, p);
+               p = min (1.0, p);
 
-               ac->set_value (p, gcd);
+               ac->set_value ( ac->interface_to_internal(p), gcd);
        }
 }
 
@@ -1186,17 +1192,17 @@ Strip::redisplay (ARDOUR::microseconds_t now, bool force)
 void
 Strip::update_automation ()
 {
-       if (!_route) {
+       if (!_stripable) {
                return;
        }
 
-       ARDOUR::AutoState state = _route->gain_control()->automation_state();
+       ARDOUR::AutoState state = _stripable->gain_control()->automation_state();
 
        if (state == Touch || state == Play) {
                notify_gain_changed (false);
        }
 
-       boost::shared_ptr<AutomationControl> pan_control = _route->pan_azimuth_control ();
+       boost::shared_ptr<AutomationControl> pan_control = _stripable->pan_azimuth_control ();
        if (pan_control) {
                state = pan_control->automation_state ();
                if (state == Touch || state == Play) {
@@ -1204,7 +1210,7 @@ Strip::update_automation ()
                }
        }
 
-       pan_control = _route->pan_width_control ();
+       pan_control = _stripable->pan_width_control ();
        if (pan_control) {
                state = pan_control->automation_state ();
                if (state == Touch || state == Play) {
@@ -1216,7 +1222,7 @@ Strip::update_automation ()
 void
 Strip::update_meter ()
 {
-       if (!_route) {
+       if (!_stripable) {
                return;
        }
 
@@ -1224,8 +1230,8 @@ Strip::update_meter ()
                return;
        }
 
-       if (_meter && _transport_is_rolling && _metering_active) {
-               float dB = const_cast<PeakMeter&> (_route->peak_meter()).meter_level (0, MeterMCP);
+       if (_meter && _transport_is_rolling && _metering_active && _stripable->peak_meter()) {
+               float dB = _stripable->peak_meter()->meter_level (0, MeterMCP);
                _meter->send_update (*_surface, dB);
                return;
        }
@@ -1305,19 +1311,6 @@ Strip::unlock_controls ()
        _controls_locked = false;
 }
 
-void
-Strip::gui_selection_changed (const ARDOUR::StrongRouteNotificationList& rl)
-{
-       for (ARDOUR::StrongRouteNotificationList::const_iterator i = rl.begin(); i != rl.end(); ++i) {
-               if ((*i) == _route) {
-                       _surface->write (_select->set_state (on));
-                       return;
-               }
-       }
-
-       _surface->write (_select->set_state (off));
-}
-
 string
 Strip::vpot_mode_string ()
 {
@@ -1345,6 +1338,12 @@ Strip::vpot_mode_string ()
        default:
                break;
        }
+#ifdef MIXBUS
+       //"None" mode, by definition (currently) shows the pan control above the fader.
+       //Mixbus controllers are created from a LADSPA so they don't have ac->desc().type
+       //For the forseeable future, we will just return "Pan" here.
+       return "Pan";
+#endif
 
        return "???";
 }
@@ -1358,14 +1357,25 @@ Strip::flip_mode_changed ()
                boost::shared_ptr<AutomationControl> fader_control = _fader->control();
 
                if (pot_control && fader_control) {
+
                        _vpot->set_control (fader_control);
                        _fader->set_control (pot_control);
-               }
 
-               if (_surface->mcp().flip_mode() == MackieControlProtocol::Normal) {
-                       do_parameter_display (GainAutomation, fader_control->get_value());
-               } else {
-                       do_parameter_display (BusSendLevel, fader_control->get_value());
+                       /* update fader with pot value */
+
+                       _surface->write (_fader->set_position (pot_control->internal_to_interface (pot_control->get_value ())));
+
+                       /* update pot with fader value */
+
+                       _surface->write (_vpot->set (fader_control->internal_to_interface (fader_control->get_value()), true, Pot::wrap));
+
+
+                       if (_surface->mcp().flip_mode() == MackieControlProtocol::Normal) {
+                               do_parameter_display (GainAutomation, fader_control->get_value());
+                       } else {
+                               do_parameter_display (BusSendLevel, pot_control->get_value());
+                       }
+
                }
 
        } else {
@@ -1395,7 +1405,7 @@ Strip::return_to_vpot_mode_display ()
        if (_surface->mcp().subview_mode() != MackieControlProtocol::None) {
                /* do nothing - second line shows value of current subview parameter */
                return;
-       } else if (_route) {
+       } else if (_stripable) {
                pending_display[1] = vpot_mode_string();
        } else {
                pending_display[1] = string();
@@ -1455,7 +1465,7 @@ Strip::next_pot_mode ()
 void
 Strip::subview_mode_changed ()
 {
-       boost::shared_ptr<Route> r = _surface->mcp().subview_route();
+       boost::shared_ptr<Stripable> r = _surface->mcp().subview_stripable();
 
        subview_connections.drop_connections ();
 
@@ -1463,7 +1473,11 @@ Strip::subview_mode_changed ()
        case MackieControlProtocol::None:
                set_vpot_parameter (_pan_mode);
                /* need to show strip name again */
-               show_route_name ();
+               show_stripable_name ();
+               if (!_stripable) {
+                       _surface->write (_vpot->set (0, true, Pot::wrap));
+                       _surface->write (_fader->set_position (0.0));
+               }
                notify_metering_state_changed ();
                eq_band = -1;
                break;
@@ -1505,7 +1519,7 @@ Strip::subview_mode_changed ()
 }
 
 void
-Strip::setup_dyn_vpot (boost::shared_ptr<Route> r)
+Strip::setup_dyn_vpot (boost::shared_ptr<Stripable> r)
 {
        if (!r) {
                return;
@@ -1515,7 +1529,6 @@ Strip::setup_dyn_vpot (boost::shared_ptr<Route> r)
        boost::shared_ptr<AutomationControl> sc = r->comp_speed_controllable ();
        boost::shared_ptr<AutomationControl> mc = r->comp_mode_controllable ();
        boost::shared_ptr<AutomationControl> kc = r->comp_makeup_controllable ();
-       boost::shared_ptr<AutomationControl> rc = r->comp_redux_controllable ();
        boost::shared_ptr<AutomationControl> ec = r->comp_enable_controllable ();
 
        uint32_t pos = _surface->mcp().global_index (*this);
@@ -1531,7 +1544,6 @@ Strip::setup_dyn_vpot (boost::shared_ptr<Route> r)
        if (sc) { available.push_back (sc); params.push_back (CompSpeed); }
        if (mc) { available.push_back (mc); params.push_back (CompMode); }
        if (kc) { available.push_back (kc); params.push_back (CompMakeup); }
-       if (rc) { available.push_back (rc); params.push_back (CompRedux); }
        if (ec) { available.push_back (ec); params.push_back (CompEnable); }
 
        if (pos >= available.size()) {
@@ -1590,7 +1602,7 @@ Strip::setup_dyn_vpot (boost::shared_ptr<Route> r)
 }
 
 void
-Strip::setup_eq_vpot (boost::shared_ptr<Route> r)
+Strip::setup_eq_vpot (boost::shared_ptr<Stripable> r)
 {
        uint32_t bands = r->eq_band_cnt ();
 
@@ -1725,7 +1737,7 @@ Strip::setup_eq_vpot (boost::shared_ptr<Route> r)
 }
 
 void
-Strip::setup_sends_vpot (boost::shared_ptr<Route> r)
+Strip::setup_sends_vpot (boost::shared_ptr<Stripable> r)
 {
        if (!r) {
                return;
@@ -1736,6 +1748,8 @@ Strip::setup_sends_vpot (boost::shared_ptr<Route> r)
        boost::shared_ptr<AutomationControl> pc = r->send_level_controllable (global_pos);
 
        if (!pc) {
+               /* nothing to control */
+               _vpot->set_control (boost::shared_ptr<AutomationControl>());
                pending_display[0] = string();
                pending_display[1] = string();
                return;
@@ -1744,13 +1758,13 @@ Strip::setup_sends_vpot (boost::shared_ptr<Route> r)
        pc->Changed.connect (subview_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_send_level_change, this, BusSendLevel, global_pos, false), ui_context());
        _vpot->set_control (pc);
 
-       pending_display[0] = r->send_name (global_pos);
+       pending_display[0] = PBD::short_version (r->send_name (global_pos), 6);
 
        notify_send_level_change (BusSendLevel, global_pos, true);
 }
 
 void
-Strip::setup_trackview_vpot (boost::shared_ptr<Route> r)
+Strip::setup_trackview_vpot (boost::shared_ptr<Stripable> r)
 {
        if (!r) {
                return;
@@ -1759,6 +1773,8 @@ Strip::setup_trackview_vpot (boost::shared_ptr<Route> r)
        const uint32_t global_pos = _surface->mcp().global_index (*this);
 
        if (global_pos >= 8) {
+               /* nothing to control */
+               _vpot->set_control (boost::shared_ptr<AutomationControl>());
                pending_display[0] = string();
                pending_display[1] = string();
                return;
@@ -1834,7 +1850,7 @@ Strip::setup_trackview_vpot (boost::shared_ptr<Route> r)
 void
 Strip::set_vpot_parameter (AutomationType p)
 {
-       if (!_route || (p == NullAutomation)) {
+       if (!_stripable || (p == NullAutomation)) {
                _vpot->set_control (boost::shared_ptr<AutomationControl>());
                pending_display[1] = string();
                return;
@@ -1848,10 +1864,10 @@ Strip::set_vpot_parameter (AutomationType p)
 
        switch (p) {
        case PanAzimuthAutomation:
-               pan_control = _route->pan_azimuth_control ();
+               pan_control = _stripable->pan_azimuth_control ();
                break;
        case PanWidthAutomation:
-               pan_control = _route->pan_width_control ();
+               pan_control = _stripable->pan_width_control ();
                break;
        case PanElevationAutomation:
                break;
@@ -1874,7 +1890,7 @@ Strip::set_vpot_parameter (AutomationType p)
 bool
 Strip::is_midi_track () const
 {
-       return boost::dynamic_pointer_cast<MidiTrack>(_route) != 0;
+       return boost::dynamic_pointer_cast<MidiTrack>(_stripable) != 0;
 }
 
 void
@@ -1894,7 +1910,7 @@ Strip::notify_metering_state_changed()
                return;
        }
 
-       if (!_route || !_meter) {
+       if (!_stripable || !_meter) {
                return;
        }