mackie: use new route API for universal access to pan/eq/dynamics parameters to provi...
authorPaul Davis <paul@linuxaudiosystems.com>
Tue, 15 Dec 2015 03:22:34 +0000 (22:22 -0500)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 16 Dec 2015 11:01:20 +0000 (06:01 -0500)
libs/surfaces/mackie/mackie_control_protocol.cc
libs/surfaces/mackie/mackie_control_protocol.h
libs/surfaces/mackie/mcp_buttons.cc
libs/surfaces/mackie/strip.cc
libs/surfaces/mackie/strip.h
libs/surfaces/mackie/surface.cc

index d3318519751b29f77955daf4379e9e6bb120a648..8c9d44481941e9a0b0571b2520bfc8453596fcff 100644 (file)
@@ -434,12 +434,9 @@ MackieControlProtocol::switch_banks (uint32_t initial, bool force)
                }
        }
 
-       /* reset this to get the right display of view mode after the switch */
-       display_view_mode ();
-
        /* make sure selection is correct */
 
-       _gui_track_selection_changed (&_last_selected_routes, false);
+       _gui_track_selection_changed (&_last_selected_routes, false, false);
 
        /* current bank has not been saved */
        session->set_dirty();
@@ -1624,31 +1621,41 @@ MackieControlProtocol::clear_ports ()
 void
 MackieControlProtocol::set_subview_mode (SubViewMode sm, boost::shared_ptr<Route> r)
 {
+       SubViewMode old = _subview_mode;
+
        _subview_mode = sm;
-       _subview_route = r;
 
-       if (_subview_mode == None) {
-               assert (!_subview_route);
+       if (r) {
+               _subview_route = r;
        }
 
-       {
-               Glib::Threads::Mutex::Lock lm (surfaces_lock);
+       if (_subview_mode != old) {
 
-               for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
+               /* subview mode did actually change */
+
+               {
+                       Surfaces copy; /* can't hold surfaces lock while calling Strip::subview_mode_changed */
+
+                       {
+                               Glib::Threads::Mutex::Lock lm (surfaces_lock);
+                               copy = surfaces;
+                       }
+
+                       for (Surfaces::iterator s = copy.begin(); s != copy.end(); ++s) {
                        (*s)->subview_mode_changed ();
+                       }
                }
-       }
 
-       /* turn buttons related to vpot mode on or off as required */
+               /* turn buttons related to vpot mode on or off as required */
 
-       if (_subview_mode != None) {
-               update_global_button (Button::Trim, off);
-               update_global_button (Button::Send, off);
-               update_global_button (Button::Pan, off);
-       } else {
-               pot_mode_globals ();
+               if (_subview_mode != None) {
+                       update_global_button (Button::Trim, off);
+                       update_global_button (Button::Send, off);
+                       update_global_button (Button::Pan, off);
+               } else {
+                       pot_mode_globals ();
+               }
        }
-
 }
 
 void
@@ -1657,7 +1664,7 @@ MackieControlProtocol::set_view_mode (ViewMode m)
        _last_bank[_view_mode] = _current_initial_bank;
 
        _view_mode = m;
-       _subview_mode = None;
+       set_subview_mode (None, boost::shared_ptr<Route>());
 
        switch_banks(_last_bank[_view_mode], true);
 }
@@ -1775,11 +1782,11 @@ MackieControlProtocol::force_special_route_to_strip (boost::shared_ptr<Route> r,
 void
 MackieControlProtocol::gui_track_selection_changed (ARDOUR::RouteNotificationListPtr rl, bool save_list)
 {
-       _gui_track_selection_changed (rl.get(), save_list);
+       _gui_track_selection_changed (rl.get(), save_list, true);
 }
 
 void
-MackieControlProtocol::_gui_track_selection_changed (ARDOUR::RouteNotificationList* rl, bool save_list)
+MackieControlProtocol::_gui_track_selection_changed (ARDOUR::RouteNotificationList* rl, bool save_list, bool gui_selection_did_change)
 {
        /* We need to keep a list of the most recently selected routes around,
           but we are not allowed to keep shared_ptr<Route> unless we want to
@@ -1810,6 +1817,11 @@ MackieControlProtocol::_gui_track_selection_changed (ARDOUR::RouteNotificationLi
        if (save_list) {
                _last_selected_routes = *rl;
        }
+
+       if (gui_selection_did_change) {
+               /* actual GUI selection changed */
+               set_subview_mode (_subview_mode, first_selected_route());
+       }
 }
 
 framepos_t
@@ -2182,3 +2194,19 @@ MackieControlProtocol::subview_route () const
 {
        return _subview_route;
 }
+
+uint32_t
+MackieControlProtocol::global_index (Strip& strip)
+{
+       Glib::Threads::Mutex::Lock lm (surfaces_lock);
+       uint32_t global = 0;
+
+       for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
+               if ((*s).get() == strip.surface()) {
+                       return global + strip.index();
+               }
+               global += (*s)->n_strips ();
+       }
+
+       return global;
+}
index 93e90c56f2b12ea50ea5f5b6af440d2a28b054f0..b8940d650c151e81b39470c0258a18aadce61b34 100644 (file)
@@ -58,6 +58,7 @@ namespace Mackie {
        class Control;
        class SurfacePort;
        class Button;
+       class Strip;
 }
 
 gboolean ipmidi_input_handler (GIOChannel*, GIOCondition condition, void *data);
@@ -185,6 +186,8 @@ class MackieControlProtocol
        boost::shared_ptr<Mackie::Surface> get_surface_by_raw_pointer (void*) const;
        boost::shared_ptr<Mackie::Surface> nth_surface (uint32_t) const;
 
+       uint32_t global_index (Mackie::Strip&);
+
        std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles ();
 
        void set_master_on_surface_strip (uint32_t surface, uint32_t strip);
@@ -366,7 +369,7 @@ class MackieControlProtocol
        void force_special_route_to_strip (boost::shared_ptr<ARDOUR::Route> r, uint32_t surface, uint32_t strip_number);
        void build_button_map ();
        void gui_track_selection_changed (ARDOUR::RouteNotificationListPtr, bool save_list);
-       void _gui_track_selection_changed (ARDOUR::RouteNotificationList*, bool save_list);
+       void _gui_track_selection_changed (ARDOUR::RouteNotificationList*, bool save_list, bool gui_did_change);
        int ipmidi_restart ();
         void initialize ();
         int set_device_info (const std::string& device_name);
index 0ae214cc78df35b27a50ecf50cd13d4b361cadaf..1d4ae37c4e6496c6a8c0116ec90d554a9e6ab1f7 100644 (file)
@@ -98,6 +98,10 @@ MackieControlProtocol::cmd_alt_release (Button &)
 LedState
 MackieControlProtocol::left_press (Button &)
 {
+       if (_subview_mode != None) {
+               return none;
+       }
+
        Sorted sorted = get_sorted_routes();
        uint32_t strip_cnt = n_strips ();
 
@@ -122,6 +126,10 @@ MackieControlProtocol::left_release (Button &)
 LedState
 MackieControlProtocol::right_press (Button &)
 {
+       if (_subview_mode != None) {
+               return none;
+       }
+
        Sorted sorted = get_sorted_routes();
        uint32_t strip_cnt = n_strips();
        uint32_t route_cnt = sorted.size();
@@ -266,6 +274,9 @@ MackieControlProtocol::cursor_down_release (Button&)
 LedState
 MackieControlProtocol::channel_left_press (Button &)
 {
+       if (_subview_mode != None) {
+               return none;
+       }
        Sorted sorted = get_sorted_routes();
        if (sorted.size() > n_strips()) {
                prev_track();
@@ -284,6 +295,9 @@ MackieControlProtocol::channel_left_release (Button &)
 LedState
 MackieControlProtocol::channel_right_press (Button &)
 {
+       if (_subview_mode != None) {
+               return none;
+       }
        Sorted sorted = get_sorted_routes();
        if (sorted.size() > n_strips()) {
                next_track();
@@ -569,6 +583,10 @@ MackieControlProtocol::enter_release (Button &)
 LedState
 MackieControlProtocol::bank_release (Button& b, uint32_t basic_bank_num)
 {
+       if (_subview_mode != None) {
+               return none;
+       }
+
        uint32_t bank_num = basic_bank_num;
 
        if (b.long_press_count() > 0) {
@@ -691,7 +709,7 @@ MackieControlProtocol::eq_press (Button &)
 {
        if (Profile->get_mixbus()) {
                boost::shared_ptr<Route> r = first_selected_route ();
-               if (r) {
+               if (r && r->eq_band_cnt() > 0) {
                        set_subview_mode (EQ, r);
                        return on;
                }
index f4eda5b91993a347280f9593eb24a07262cc83a8..13211f3e9570b37215704b18768c8bd65ff67efa 100644 (file)
@@ -97,6 +97,7 @@ Strip::Strip (Surface& s, const std::string& name, int index, const map<Button::
        , _metering_active (true)
        , _block_vpot_mode_redisplay_until (0)
        , _block_screen_redisplay_until (0)
+       , eq_band (-1)
        , _pan_mode (PanAzimuthAutomation)
        , _trim_mode (TrimAutomation)
        , vpot_parameter (PanAzimuthAutomation)
@@ -193,14 +194,6 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
        control_by_parameter[TrimAutomation] = (Control*) 0;
        control_by_parameter[PhaseAutomation] = (Control*) 0;
        control_by_parameter[SendAutomation] = (Control*) 0;
-       control_by_parameter[EQParam1] = (Control*) 0;
-       control_by_parameter[EQParam2] = (Control*) 0;
-       control_by_parameter[EQParam3] = (Control*) 0;
-       control_by_parameter[EQParam4] = (Control*) 0;
-       control_by_parameter[EQParam5] = (Control*) 0;
-       control_by_parameter[EQParam6] = (Control*) 0;
-       control_by_parameter[EQParam7] = (Control*) 0;
-       control_by_parameter[EQParam8] = (Control*) 0;
 
        reset_saved_values ();
 
@@ -229,19 +222,14 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
                _route->phase_control()->set_channel(0);
        }
 
-       boost::shared_ptr<Pannable> pannable = _route->pannable();
-
-       if(Profile->get_mixbus()) {
-               const uint32_t port_channel_post_pan = 2; // gtk2_ardour/mixbus_ports.h
-               boost::shared_ptr<ARDOUR::PluginInsert> plug = _route->ch_post();
-               mb_pan_controllable = boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (plug->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, port_channel_post_pan)));
+       boost::shared_ptr<AutomationControl> pan_control = _route->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());
+       }
 
-               mb_pan_controllable->Changed.connect(route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_panner_azi_changed, this, false), ui_context());
-       } else {
-               if (pannable && _route->panner()) {
-                       pannable->pan_azimuth_control->Changed.connect(route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_panner_azi_changed, this, false), ui_context());
-                       pannable->pan_width_control->Changed.connect(route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_panner_width_changed, this, false), ui_context());
-               }
+       pan_control = _route->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());
        }
 
        _route->gain_control()->Changed.connect(route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_gain_changed, this, false), ui_context());
@@ -252,8 +240,6 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
        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());
-
-
        }
 
        // TODO this works when a currently-banked route is made inactive, but not
@@ -266,24 +252,20 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
 
        possible_pot_parameters.clear();
 
-       if (Profile->get_mixbus()) {
+       if (_route->pan_azimuth_control()) {
                possible_pot_parameters.push_back (PanAzimuthAutomation);
-       } else {
-               if (pannable) {
-                       boost::shared_ptr<Panner> panner = _route->panner();
-                       if (panner) {
-                               set<Evoral::Parameter> automatable = panner->what_can_be_automated ();
-                               set<Evoral::Parameter>::iterator a;
-
-                               if ((a = automatable.find (PanAzimuthAutomation)) != automatable.end()) {
-                                       possible_pot_parameters.push_back (PanAzimuthAutomation);
-                               }
-
-                               if ((a = automatable.find (PanWidthAutomation)) != automatable.end()) {
-                                       possible_pot_parameters.push_back (PanWidthAutomation);
-                               }
-                       }
-               }
+       }
+       if (_route->pan_width_control()) {
+               possible_pot_parameters.push_back (PanWidthAutomation);
+       }
+       if (_route->pan_elevation_control()) {
+               possible_pot_parameters.push_back (PanElevationAutomation);
+       }
+       if (_route->pan_frontback_control()) {
+               possible_pot_parameters.push_back (PanFrontBackAutomation);
+       }
+       if (_route->pan_lfe_control()) {
+               possible_pot_parameters.push_back (PanLFEAutomation);
        }
 
        if (_route->trim() && route()->trim()->active()) {
@@ -533,156 +515,164 @@ Strip::show_route_name ()
 {
        MackieControlProtocol::SubViewMode svm = _surface->mcp().subview_mode();
 
-       if (svm == MackieControlProtocol::None) {
-               if (!_route) {
-                       return;
-               }
-               string line1;
-               string fullname = _route->name();
-
-               if (fullname.length() <= 6) {
-                       line1 = fullname;
-               } else {
-                       line1 = PBD::short_version (fullname, 6);
-               }
+       if (svm != MackieControlProtocol::None) {
+               /* subview mode is responsible for upper line */
+               return;
+       }
 
-               _surface->write (display (0, line1));
-
-       } else if (svm == MackieControlProtocol::EQ) {
-               if (_vpot == control_by_parameter[EQParam1]) {
-                       _surface->write (display (0, "HiFreq"));
-               } else if (_vpot == control_by_parameter[EQParam2]) {
-                       _surface->write (display (0, "HiGain"));
-               } else if (_vpot == control_by_parameter[EQParam3]) {
-                       _surface->write (display (0, "MidFreq"));
-               } else if (_vpot == control_by_parameter[EQParam4]) {
-                       _surface->write (display (0, "MidGain"));
-               } else if (_vpot == control_by_parameter[EQParam5]) {
-                       _surface->write (display (0, "LoFreq"));
-               } else if (_vpot == control_by_parameter[EQParam6]) {
-                       _surface->write (display (0, "LoGain"));
-               } else if (_vpot == control_by_parameter[EQParam7]) {
-                       _surface->write (display (0, "HPFreq"));
-               } else if (_vpot == control_by_parameter[EQParam8]) {
-                       _surface->write (display (0, "In/Out"));
-               }
-       } else if (svm == MackieControlProtocol::Dynamics) {
+       if (!_route) {
+               return;
+       }
+       string line1;
+       string fullname = _route->name();
 
+       if (fullname.length() <= 6) {
+               line1 = fullname;
+       } else {
+               line1 = PBD::short_version (fullname, 6);
        }
 
+       _surface->write (display (0, line1));
 }
 
 void
-Strip::notify_eq_change (AutomationType p, uint32_t port_number, bool force_update)
+Strip::notify_eq_change (AutomationType type, uint32_t band, bool force_update)
 {
-       if (_surface->mcp().subview_mode() == MackieControlProtocol::None) {
-               /* no longer in EQ subview mode */
+       boost::shared_ptr<Route> r = _surface->mcp().subview_route();
+
+       if (!r) {
+               /* not in subview mode */
                return;
        }
 
-       if (_vpot != control_by_parameter[p]) {
-               /* vpot is no longer controlling this EQ parameter */
+       if (_surface->mcp().subview_mode() == MackieControlProtocol::None) {
+               /* no longer in EQ subview mode */
                return;
        }
 
-       boost::shared_ptr<PluginInsert> eq = _surface->mcp().subview_route()->ch_eq();
+       boost::shared_ptr<AutomationControl> control;
 
-       if (eq) {
-               boost::shared_ptr<AutomationControl> control = boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, port_number)));
+       switch (type) {
+       case EQGain:
+               control = r->eq_gain_controllable (band);
+               break;
+       case EQFrequency:
+               control = r->eq_freq_controllable (band);
+               break;
+       case EQQ:
+               control = r->eq_q_controllable (band);
+               break;
+       case EQShape:
+               control = r->eq_shape_controllable (band);
+               break;
+       case EQHPF:
+               control = r->eq_hpf_controllable ();
+               break;
+       case EQEnable:
+               control = r->eq_enable_controllable ();
+               break;
+       default:
+               break;
+       }
 
-               if (control) {
-                       float val = control->get_value();
-                       queue_parameter_display (p, val);
-                       _surface->write (_vpot->set (control->internal_to_interface (val), true, Pot::wrap));
-               }
+       if (control) {
+               float val = control->get_value();
+               queue_parameter_display (type, val);
+               /* update pot/encoder */
+               _surface->write (_vpot->set (control->internal_to_interface (val), true, Pot::wrap));
        }
 }
 
 void
 Strip::notify_panner_azi_changed (bool force_update)
 {
-       if (_route) {
+       if (!_route) {
+               return;
+       }
 
-               DEBUG_TRACE (DEBUG::MackieControl, string_compose ("pan change for strip %1\n", _index));
+       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("pan change for strip %1\n", _index));
 
-               boost::shared_ptr<Pannable> pannable = _route->pannable();
+       boost::shared_ptr<AutomationControl> pan_control = _route->pan_azimuth_control ();
 
-               if (!pannable || !_route->panner()) {
-                       _surface->write (_vpot->zero());
-                       return;
-               }
+       if (!pan_control) {
+               _surface->write (_vpot->zero());
+               return;
+       }
 
-               Control* control = 0;
-               ControlParameterMap::iterator i = control_by_parameter.find (PanAzimuthAutomation);
+       Control* control = 0;
+       ControlParameterMap::iterator i = control_by_parameter.find (PanAzimuthAutomation);
 
-               if (i == control_by_parameter.end()) {
-                       return;
-               }
+       if (i == control_by_parameter.end()) {
+               return;
+       }
 
-               control = i->second;
+       control = i->second;
 
-               double pos = mb_pan_controllable->internal_to_interface (mb_pan_controllable->get_value());
+       double normalized_pos = pan_control->internal_to_interface (pan_control->get_value());
+       double internal_pos = pan_control->get_value();
 
-               if (force_update || pos != _last_pan_azi_position_written) {
+       if (force_update || (normalized_pos != _last_pan_azi_position_written)) {
 
-                       if (control == _fader) {
-                               if (!_fader->in_use()) {
-                                       _surface->write (_fader->set_position (pos));
-                                       queue_parameter_display (PanAzimuthAutomation, pos);
-                               }
-                       } else if (control == _vpot) {
-                               _surface->write (_vpot->set (pos, true, Pot::dot));
-                               queue_parameter_display (PanAzimuthAutomation, pos);
+               if (control == _fader) {
+                       if (!_fader->in_use()) {
+                               _surface->write (_fader->set_position (normalized_pos));
+                               /* show actual internal value to user */
+                               queue_parameter_display (PanAzimuthAutomation, internal_pos);
                        }
-
-                       _last_pan_azi_position_written = pos;
+               } else if (control == _vpot) {
+                       _surface->write (_vpot->set (normalized_pos, true, Pot::dot));
+                       /* show actual internal value to user */
+                       queue_parameter_display (PanAzimuthAutomation, internal_pos);
                }
+
+               _last_pan_azi_position_written = normalized_pos;
        }
 }
 
 void
 Strip::notify_panner_width_changed (bool force_update)
 {
-       if (_route) {
+       if (!_route) {
+               return;
+       }
 
-               DEBUG_TRACE (DEBUG::MackieControl, string_compose ("pan width change for strip %1\n", _index));
+       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("pan width change for strip %1\n", _index));
 
-               boost::shared_ptr<Pannable> pannable = _route->pannable();
+       boost::shared_ptr<AutomationControl> pan_control = _route->pan_width_control ();
 
-               if (!pannable || !_route->panner()) {
-                       _surface->write (_vpot->zero());
-                       return;
-               }
+       if (!pan_control) {
+               _surface->write (_vpot->zero());
+               return;
+       }
 
-               Control* control = 0;
-               ControlParameterMap::iterator i = control_by_parameter.find (PanWidthAutomation);
+       Control* control = 0;
+       ControlParameterMap::iterator i = control_by_parameter.find (PanWidthAutomation);
 
-               if (i == control_by_parameter.end()) {
-                       return;
-               }
+       if (i == control_by_parameter.end()) {
+               return;
+       }
 
-               control = i->second;
+       control = i->second;
 
-               double pos = pannable->pan_width_control->internal_to_interface (pannable->pan_width_control->get_value());
+       double pos = pan_control->internal_to_interface (pan_control->get_value());
 
-               if (force_update || pos != _last_pan_width_position_written) {
+       if (force_update || pos != _last_pan_width_position_written) {
 
-                       if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
+               if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
 
-                               if (control == _fader) {
-                                       if (!control->in_use()) {
-                                               _surface->write (_fader->set_position (pos));
-                                               queue_parameter_display (PanWidthAutomation, pos);
-                                       }
+                       if (control == _fader) {
+                               if (!control->in_use()) {
+                                       _surface->write (_fader->set_position (pos));
+                                       queue_parameter_display (PanWidthAutomation, pos);
                                }
-
-                       } else if (control == _vpot) {
-                               _surface->write (_vpot->set (pos, true, Pot::spread));
-                               queue_parameter_display (PanWidthAutomation, pos);
                        }
 
-                       _last_pan_width_position_written = pos;
+               } else if (control == _vpot) {
+                       _surface->write (_vpot->set (pos, true, Pot::spread));
+                       queue_parameter_display (PanWidthAutomation, pos);
                }
+
+               _last_pan_width_position_written = pos;
        }
 }
 
@@ -931,17 +921,22 @@ Strip::do_parameter_display (AutomationType type, float val)
                        screen_hold = true;
                }
                break;
-       case EQParam1:
-       case EQParam2:
-       case EQParam3:
-       case EQParam4:
-       case EQParam5:
-       case EQParam6:
-       case EQParam7:
-       case EQParam8:
+       case EQGain:
+       case EQFrequency:
+       case EQQ:
+       case EQShape:
+       case EQHPF:
                snprintf (buf, sizeof (buf), "%6.1f", val);
                _surface->write (display (1, buf));
                screen_hold = true;
+               break;
+       case EQEnable:
+               if (val >= 0.5) {
+                       _surface->write (display (1, "on"));
+               } else {
+                       _surface->write (display (1, "off"));
+               }
+               break;
        default:
                break;
        }
@@ -1079,26 +1074,32 @@ Strip::redisplay (ARDOUR::microseconds_t now)
 void
 Strip::update_automation ()
 {
-       ARDOUR::AutoState gain_state = _route->gain_control()->automation_state();
+       if (!_route) {
+               return;
+       }
+
+       ARDOUR::AutoState state = _route->gain_control()->automation_state();
 
-       if (gain_state == Touch || gain_state == Play) {
+       if (state == Touch || state == Play) {
                notify_gain_changed (false);
        }
 
-if ( Profile->get_mixbus() ) {
-       ARDOUR::AutoState panner_state = mb_pan_controllable->automation_state();
-       if (panner_state == Touch || panner_state == Play) {
-               notify_panner_azi_changed (false);
-       }
-} else {
-       if (_route->panner()) {
-               ARDOUR::AutoState panner_state = _route->panner()->automation_state();
-               if (panner_state == Touch || panner_state == Play) {
+       boost::shared_ptr<AutomationControl> pan_control = _route->pan_azimuth_control ();
+       if (pan_control) {
+               state = pan_control->automation_state ();
+               if (state == Touch || state == Play) {
                        notify_panner_azi_changed (false);
+               }
+       }
+
+       pan_control = _route->pan_width_control ();
+       if (pan_control) {
+               state = pan_control->automation_state ();
+               if (state == Touch || state == Play) {
                        notify_panner_width_changed (false);
                }
        }
-}
+
        if (_route->trim() && route()->trim()->active()) {
                ARDOUR::AutoState trim_state = _route->trim_control()->automation_state();
                if (trim_state == Touch || trim_state == Play) {
@@ -1110,6 +1111,10 @@ if ( Profile->get_mixbus() ) {
 void
 Strip::update_meter ()
 {
+       if (_surface->mcp().subview_mode() != MackieControlProtocol::None) {
+               return;
+       }
+
        if (_meter && _transport_is_rolling && _metering_active) {
                float dB = const_cast<PeakMeter&> (_route->peak_meter()).meter_level (0, MeterMCP);
                _meter->send_update (*_surface, dB);
@@ -1301,7 +1306,7 @@ Strip::return_to_vpot_mode_display ()
 void
 Strip::next_pot_mode ()
 {
-       vector<Evoral::Parameter>::iterator i;
+       vector<AutomationType>::iterator i;
 
        if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
                /* do not change vpot mode while in flipped mode */
@@ -1350,7 +1355,7 @@ Strip::next_pot_mode ()
                                break;
                        }
                }
-               if ((*i).type() == PhaseAutomation && _route->phase_invert().size() > 1) {
+               if ((*i) == PhaseAutomation && _route->phase_invert().size() > 1) {
                        // There are more than one channel of phase
                        if ((_route->phase_control()->channel() + 1) < _route->phase_invert().size()) {
                                _route->phase_control()->set_channel(_route->phase_control()->channel() + 1);
@@ -1396,51 +1401,167 @@ Strip::subview_mode_changed ()
 
        switch (_surface->mcp().subview_mode()) {
        case MackieControlProtocol::None:
-               if (vpot_parameter != NullAutomation) {
-                       set_vpot_parameter (vpot_parameter);
-               }
+               set_vpot_parameter (vpot_parameter);
+               notify_metering_state_changed ();
+               eq_band = -1;
                break;
 
        case MackieControlProtocol::EQ:
-               switch (_index) {
+               setup_eq_vpots (r);
+               break;
+
+       case MackieControlProtocol::Dynamics:
+               break;
+       }
+}
+
+void
+Strip::setup_eq_vpots (boost::shared_ptr<Route> r)
+{
+       uint32_t bands = r->eq_band_cnt ();
+
+       if (bands == 0) {
+               /* should never get here */
+               return;
+       }
+
+       /* figure out how many params per band are available */
+
+       boost::shared_ptr<AutomationControl> pc;
+       uint32_t params_per_band = 0;
+
+       if ((pc = r->eq_gain_controllable (0))) {
+               params_per_band += 1;
+       }
+       if ((pc = r->eq_freq_controllable (0))) {
+               params_per_band += 1;
+       }
+       if ((pc = r->eq_q_controllable (0))) {
+               params_per_band += 1;
+       }
+       if ((pc = r->eq_shape_controllable (0))) {
+               params_per_band += 1;
+       }
+
+       /* pick the one for this strip, based on its global position across
+        * all surfaces
+        */
+
+       pc.reset ();
+
+       const uint32_t total_band_parameters = bands * params_per_band;
+       const uint32_t global_pos = _surface->mcp().global_index (*this);
+       AutomationType param = NullAutomation;
+       string band_name;
+
+       eq_band = -1;
+
+       if (global_pos < total_band_parameters) {
+
+               /* show a parameter for an EQ band */
+
+               const uint32_t parameter = global_pos % params_per_band;
+               eq_band = global_pos / params_per_band;
+               band_name = r->eq_band_name (eq_band);
+
+               switch (parameter) {
                case 0:
-                       set_vpot_parameter (ARDOUR::EQParam1);
+                       pc = r->eq_gain_controllable (eq_band);
+                       param = EQGain;
                        break;
                case 1:
-                       set_vpot_parameter (ARDOUR::EQParam2);
+                       pc = r->eq_freq_controllable (eq_band);
+                       param = EQFrequency;
                        break;
                case 2:
-                       set_vpot_parameter (ARDOUR::EQParam3);
+                       pc = r->eq_q_controllable (eq_band);
+                       param = EQQ;
                        break;
                case 3:
-                       set_vpot_parameter (ARDOUR::EQParam4);
+                       pc = r->eq_shape_controllable (eq_band);
+                       param = EQShape;
+                       break;
+               }
+
+       } else {
+
+               /* show a non-band parameter (HPF or enable)
+                */
+
+               uint32_t parameter = global_pos - total_band_parameters;
+
+               switch (parameter) {
+               case 0: /* first control after band parameters */
+                       pc = r->eq_hpf_controllable();
+                       param = EQHPF;
+                       break;
+               case 1: /* second control after band parameters */
+                       pc = r->eq_enable_controllable();
+                       param = EQEnable;
+                       break;
+               default:
+                       /* nothing to control */
+                       _vpot->set_control (boost::shared_ptr<AutomationControl>());
+                       _surface->write (display (0, string()));
+                       _surface->write (display (1, string()));
+                       /* done */
+                       return;
+                       break;
+               }
+
+       }
+
+       if (pc) {
+               pc->Changed.connect (subview_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_eq_change, this, param, eq_band, false), ui_context());
+               _vpot->set_control (pc);
+
+               string pot_id;
+
+               switch (param) {
+               case EQGain:
+                       pot_id = band_name + "Gain";
+                       break;
+               case EQFrequency:
+                       pot_id = band_name + "Freq";
                        break;
-               case 4:
-                       set_vpot_parameter (ARDOUR::EQParam5);
+               case EQQ:
+                       pot_id = band_name + " Q";
                        break;
-               case 5:
-                       set_vpot_parameter (ARDOUR::EQParam6);
+               case EQShape:
+                       pot_id = band_name + " Shp";
                        break;
-               case 6:
-                       set_vpot_parameter (ARDOUR::EQParam7);
+               case EQHPF:
+                       pot_id = "HPFreq";
                        break;
-               case 7:
-                       set_vpot_parameter (ARDOUR::EQParam8);
+               case EQEnable:
+                       pot_id = "on/off";
+                       break;
+               default:
                        break;
                }
-               break;
 
-       case MackieControlProtocol::Dynamics:
-               break;
+               if (!pot_id.empty()) {
+                       _surface->write (display (0, pot_id));
+               }
+
+               notify_eq_change (param, eq_band, true);
        }
 }
 
 void
-Strip::set_vpot_parameter (Evoral::Parameter p)
+Strip::set_vpot_parameter (AutomationType p)
 {
-       boost::shared_ptr<Pannable> pannable;
+       if (!_route || (p == NullAutomation)) {
+               control_by_parameter[vpot_parameter] = 0;
+               vpot_parameter = NullAutomation;
+               _vpot->set_control (boost::shared_ptr<AutomationControl>());
+               _surface->write (display (1, string()));
+               return;
+       }
 
-       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch to vpot mode %1\n", p.type()));
+       boost::shared_ptr<AutomationControl> pan_control;
+
+       DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch to vpot mode %1\n", p));
 
        reset_saved_values ();
 
@@ -1453,63 +1574,65 @@ Strip::set_vpot_parameter (Evoral::Parameter p)
                }
        }
 
-       switch (p.type()) {
+       switch (p) {
        case PanAzimuthAutomation:
-               _pan_mode = PanAzimuthAutomation;
-               pannable = _route->pannable ();
-               vpot_parameter = PanAzimuthAutomation;
-               if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
-                       /* gain to vpot, pan azi to fader */
-                       _vpot->set_control (_route->group_gain_control());
-                       control_by_parameter[GainAutomation] = _vpot;
-                       if (pannable) {
-                               _fader->set_control (mb_pan_controllable);
-                               control_by_parameter[PanAzimuthAutomation] = _fader;
+               if ((pan_control = _route->pan_azimuth_control ())) {
+                       if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
+                               _pan_mode = PanAzimuthAutomation;
+                               if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
+                                       /* gain to vpot, pan azi to fader */
+                                       _vpot->set_control (_route->group_gain_control());
+                                       vpot_parameter = GainAutomation;
+                                       control_by_parameter[GainAutomation] = _vpot;
+                                       _fader->set_control (pan_control);
+                                       control_by_parameter[PanAzimuthAutomation] = _fader;
+                               } else {
+                                       _fader->set_control (boost::shared_ptr<AutomationControl>());
+                                       control_by_parameter[PanAzimuthAutomation] = 0;
+                               }
                        } else {
-                               _fader->set_control (boost::shared_ptr<AutomationControl>());
-                               control_by_parameter[PanAzimuthAutomation] = 0;
-                       }
-               } else {
-                       /* gain to fader, pan azi to vpot */
-                       _fader->set_control (_route->group_gain_control());
-                       control_by_parameter[GainAutomation] = _fader;
-                       if (pannable) {
-                               _vpot->set_control (mb_pan_controllable);
+                               /* gain to fader, pan azi to vpot */
+                               vpot_parameter = PanAzimuthAutomation;
+                               _fader->set_control (_route->group_gain_control());
+                               control_by_parameter[GainAutomation] = _fader;
+                               _vpot->set_control (pan_control);
                                control_by_parameter[PanAzimuthAutomation] = _vpot;
-                       } else {
-                               _vpot->set_control (boost::shared_ptr<AutomationControl>());
-                               control_by_parameter[PanAzimuthAutomation] = 0;
                        }
+               } else {
+                       _vpot->set_control (boost::shared_ptr<AutomationControl>());
+                       control_by_parameter[PanAzimuthAutomation] = 0;
                }
                break;
+
        case PanWidthAutomation:
-               _pan_mode = PanWidthAutomation;
-               pannable = _route->pannable ();
-               vpot_parameter = PanWidthAutomation;
-               if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
-                       /* gain to vpot, pan width to fader */
-                       _vpot->set_control (_route->group_gain_control());
-                       control_by_parameter[GainAutomation] = _vpot;
-                       if (pannable) {
-                               _fader->set_control (pannable->pan_width_control);
-                               control_by_parameter[PanWidthAutomation] = _fader;
+               if ((pan_control = _route->pan_width_control ())) {
+                       if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
+                               _pan_mode = PanWidthAutomation;
+                               if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
+                                       /* gain to vpot, pan width to fader */
+                                       _vpot->set_control (_route->group_gain_control());
+                                       vpot_parameter = GainAutomation;
+                                       control_by_parameter[GainAutomation] = _vpot;
+                                       _fader->set_control (pan_control);
+                                       control_by_parameter[PanWidthAutomation] = _fader;
+                               } else {
+                                       _fader->set_control (boost::shared_ptr<AutomationControl>());
+                                       control_by_parameter[PanWidthAutomation] = 0;
+                               }
                        } else {
-                               _fader->set_control (boost::shared_ptr<AutomationControl>());
-                               control_by_parameter[PanWidthAutomation] = 0;
-                       }
-               } else {
-                       /* gain to fader, pan width to vpot */
-                       _fader->set_control (_route->group_gain_control());
-                       control_by_parameter[GainAutomation] = _fader;
-                       if (pannable) {
-                               _vpot->set_control (pannable->pan_width_control);
+                               /* gain to fader, pan width to vpot */
+                               vpot_parameter = PanWidthAutomation;
+                               _fader->set_control (_route->group_gain_control());
+                               control_by_parameter[GainAutomation] = _fader;
+                               _vpot->set_control (pan_control);
                                control_by_parameter[PanWidthAutomation] = _vpot;
-                       } else {
-                               _vpot->set_control (boost::shared_ptr<AutomationControl>());
-                               control_by_parameter[PanWidthAutomation] = 0;
                        }
+               } else {
+                       _vpot->set_control (boost::shared_ptr<AutomationControl>());
+                       control_by_parameter[PanWidthAutomation] = 0;
                }
                break;
+
        case PanElevationAutomation:
                break;
        case PanFrontBackAutomation:
@@ -1623,46 +1746,6 @@ Strip::set_vpot_parameter (Evoral::Parameter p)
                        }
                }
                break;
-       case EQParam1: {
-               const uint32_t eq_hi_freq = 3; /* gtk2_ardour/mixbus_ports.h */
-               hookup_eq (EQParam1, eq_hi_freq);
-               break;
-       }
-       case EQParam2: {
-               const uint32_t eq_hi_gain = 4; /* gtk2_ardour/mixbus_ports.h */
-               hookup_eq (EQParam2, eq_hi_gain);
-               break;
-       }
-       case EQParam3: {
-               const uint32_t eq_mid_freq = 5; /* gtk2_ardour/mixbus_ports.h */
-               hookup_eq (EQParam3, eq_mid_freq);
-               break;
-       }
-       case EQParam4: {
-               const uint32_t eq_mid_gain = 6; /* gtk2_ardour/mixbus_ports.h */
-               hookup_eq (EQParam4, eq_mid_gain);
-               break;
-       }
-       case EQParam5: {
-               const uint32_t eq_lo_freq = 7; /* gtk2_ardour/mixbus_ports.h */
-               hookup_eq (EQParam5, eq_lo_freq);
-               break;
-       }
-       case EQParam6: {
-               const uint32_t eq_lo_gain = 8; /* gtk2_ardour/mixbus_ports.h */
-               hookup_eq (EQParam6, eq_lo_gain);
-               break;
-       }
-       case EQParam7: {
-               const uint32_t eq_hp_freq = 2; /* gtk2_ardour/mixbus_ports.h */
-               hookup_eq (EQParam7, eq_hp_freq);
-               break;
-       }
-       case EQParam8: {
-               const uint32_t eq_in = 1; /* gtk2_ardour/mixbus_ports.h */
-               hookup_eq (EQParam8, eq_in);
-               break;
-       }
        default:
                DEBUG_TRACE (DEBUG::MackieControl, string_compose ("vpot mode %1 not known.\n", p));
                break;
@@ -1691,6 +1774,10 @@ Strip::reset_saved_values ()
 void
 Strip::notify_metering_state_changed()
 {
+       if (_surface->mcp().subview_mode() != MackieControlProtocol::None) {
+               return;
+       }
+
        if (!_route || !_meter) {
                return;
        }
@@ -1714,27 +1801,6 @@ Strip::notify_metering_state_changed()
 }
 
 void
-Strip::hookup_eq (AutomationType param, uint32_t port_number)
+Strip::hookup_eq (AutomationType param, uint32_t band)
 {
-       boost::shared_ptr<Route> r = _surface->mcp().subview_route();
-
-       if (!r) {
-               _vpot->set_control (boost::shared_ptr<AutomationControl>());
-               return;
-       }
-
-       boost::shared_ptr<PluginInsert> eq = r->ch_eq();
-
-       if (!eq) {
-               _vpot->set_control (boost::shared_ptr<AutomationControl>());
-       }
-
-       boost::shared_ptr<AutomationControl> control = boost::dynamic_pointer_cast<ARDOUR::AutomationControl> (eq->control (Evoral::Parameter (ARDOUR::PluginAutomation, 0, port_number)));
-
-       if (control) {
-               control->Changed.connect (subview_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_eq_change, this, param, port_number, false), ui_context());
-               _vpot->set_control (control);
-               control_by_parameter[param] = _vpot;
-               show_route_name ();
-       }
 }
index 1320df0187128260469235027550271f1f8a3e4e..0e925834b80e482df0f2582bd6e2b43aadae5a02 100644 (file)
@@ -57,6 +57,7 @@ public:
 
        void add (Control & control);
        int index() const { return _index; } // zero based
+       Surface* surface() const { return _surface; }
 
        void set_route (boost::shared_ptr<ARDOUR::Route>, bool with_messages = true);
 
@@ -111,6 +112,7 @@ private:
        PBD::ScopedConnectionList route_connections;
        PBD::ScopedConnectionList subview_connections;
        PBD::ScopedConnectionList send_connections;
+       int       eq_band;
 
        ARDOUR::AutomationType  _pan_mode;
        ARDOUR::AutomationType  _trim_mode;
@@ -156,21 +158,22 @@ private:
        void vselect_event (Button&, ButtonState);
        void fader_touch_event (Button&, ButtonState);
 
-       std::vector<Evoral::Parameter> possible_pot_parameters;
-       std::vector<Evoral::Parameter> possible_trim_parameters;
+       std::vector<ARDOUR::AutomationType> possible_pot_parameters;
+       std::vector<ARDOUR::AutomationType> possible_trim_parameters;
        void next_pot_mode ();
-       void set_vpot_parameter (Evoral::Parameter);
+       void set_vpot_parameter (ARDOUR::AutomationType);
        void show_route_name ();
 
        void reset_saved_values ();
 
        bool is_midi_track () const;
 
-       typedef std::map<Evoral::Parameter,Control*> ControlParameterMap;
+       typedef std::map<ARDOUR::AutomationType,Control*> ControlParameterMap;
        ControlParameterMap control_by_parameter;
 
        void hookup_eq (ARDOUR::AutomationType, uint32_t);
-       void notify_eq_change (ARDOUR::AutomationType, uint32_t, bool force);
+       void notify_eq_change (ARDOUR::AutomationType, uint32_t band, bool force);
+       void setup_eq_vpots (boost::shared_ptr<ARDOUR::Route>);
 };
 
 }
index 44a31804e312e73882f51743456ebad113a861b9..7aa047fcf394dc6edf6457493e6736f0df68d57a 100644 (file)
@@ -25,6 +25,8 @@
 
 #include <glibmm/convert.h>
 
+#include "pbd/stacktrace.h"
+
 #include "midi++/port.h"
 
 #include "ardour/audioengine.h"
@@ -941,8 +943,6 @@ Surface::map_routes (const vector<boost::shared_ptr<Route> >& routes)
        for (; s != strips.end(); ++s) {
                (*s)->set_route (boost::shared_ptr<Route>());
        }
-
-
 }
 
 static char