diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2012-04-16 19:05:27 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2012-04-16 19:05:27 +0000 |
commit | 72d17d326e5ffe744ac89570410c38712ab7f79e (patch) | |
tree | 1f39db60171f9805c7b069eedb8e56148bd3b257 | |
parent | a2897ecef6da6a458aa1de8c2d9973a1e809dca2 (diff) |
MCP: a fistful of changes
git-svn-id: svn://localhost/ardour2/branches/3.0@11987 d708f5d6-7413-0410-9779-e7cbd77b26cf
-rw-r--r-- | libs/surfaces/mackie/controls.cc | 42 | ||||
-rw-r--r-- | libs/surfaces/mackie/controls.h | 18 | ||||
-rw-r--r-- | libs/surfaces/mackie/strip.cc | 678 | ||||
-rw-r--r-- | libs/surfaces/mackie/strip.h | 42 | ||||
-rw-r--r-- | libs/surfaces/mackie/surface.cc | 6 |
5 files changed, 525 insertions, 261 deletions
diff --git a/libs/surfaces/mackie/controls.cc b/libs/surfaces/mackie/controls.cc index 24b59fd744..29d8d165ce 100644 --- a/libs/surfaces/mackie/controls.cc +++ b/libs/surfaces/mackie/controls.cc @@ -84,56 +84,32 @@ ostream & Mackie::operator << (ostream & os, const Mackie::Control & control) } void -Control::set_normal_control (boost::shared_ptr<AutomationControl> ac) +Control::set_control (boost::shared_ptr<AutomationControl> ac) { normal_ac = ac; } void -Control::set_modified_control (boost::shared_ptr<AutomationControl> ac) +Control::set_value (float val) { - modified_ac = ac; -} - -void -Control::set_value (float val, bool modified) -{ - if (modified && modified_ac) { - modified_ac->set_value (modified_ac->interface_to_internal (val)); - } else if (normal_ac) { - normal_ac->set_value (normal_ac->interface_to_internal (val)); - } + normal_ac->set_value (normal_ac->interface_to_internal (val)); } float -Control::get_value (bool modified) +Control::get_value () { - if (modified && modified_ac) { - return modified_ac->internal_to_interface (modified_ac->get_value()); - } else if (normal_ac) { - return normal_ac->internal_to_interface (normal_ac->get_value()); - } - - return 0.0; + return normal_ac->internal_to_interface (normal_ac->get_value()); } void -Control::start_touch (double when, bool modified) +Control::start_touch (double when) { - if (modified && modified_ac) { - return modified_ac->start_touch (when); - } else if (normal_ac) { - return normal_ac->start_touch (when); - } + return normal_ac->start_touch (when); } void -Control::stop_touch (double when, bool mark, bool modified) +Control::stop_touch (double when, bool mark) { - if (modified && modified_ac) { - return modified_ac->stop_touch (when, mark); - } else if (normal_ac) { - return normal_ac->stop_touch (when, mark); - } + return normal_ac->stop_touch (when, mark); } diff --git a/libs/surfaces/mackie/controls.h b/libs/surfaces/mackie/controls.h index eb9a691972..38dad7ef7f 100644 --- a/libs/surfaces/mackie/controls.h +++ b/libs/surfaces/mackie/controls.h @@ -66,23 +66,17 @@ public: */ Control* in_use_touch_control; - boost::shared_ptr<ARDOUR::AutomationControl> control (bool modified) const { return modified ? modified_ac : normal_ac; } + boost::shared_ptr<ARDOUR::AutomationControl> control () const { return normal_ac; } + virtual void set_control (boost::shared_ptr<ARDOUR::AutomationControl>); - virtual void set_normal_control (boost::shared_ptr<ARDOUR::AutomationControl>); - virtual void set_modified_control (boost::shared_ptr<ARDOUR::AutomationControl>); - - float get_value (bool modified = false); - void set_value (float val, bool modified = false); + float get_value (); + void set_value (float val); - virtual void start_touch (double when, bool modified); - virtual void stop_touch (double when, bool mark, bool modified); + virtual void start_touch (double when); + virtual void stop_touch (double when, bool mark); protected: - /* a control can operate up to 2 different AutomationControls - in any given mode. both of them may be unset at any time. - */ boost::shared_ptr<ARDOUR::AutomationControl> normal_ac; - boost::shared_ptr<ARDOUR::AutomationControl> modified_ac; private: int _id; /* possibly device-dependent ID */ diff --git a/libs/surfaces/mackie/strip.cc b/libs/surfaces/mackie/strip.cc index e8a2415cfe..a043a874f6 100644 --- a/libs/surfaces/mackie/strip.cc +++ b/libs/surfaces/mackie/strip.cc @@ -28,15 +28,20 @@ #include "pbd/compose.h" #include "pbd/convert.h" +#include "ardour/amp.h" +#include "ardour/bundle.h" #include "ardour/debug.h" #include "ardour/midi_ui.h" -#include "ardour/route.h" -#include "ardour/track.h" +#include "ardour/meter.h" #include "ardour/pannable.h" #include "ardour/panner.h" #include "ardour/panner_shell.h" #include "ardour/rc_configuration.h" -#include "ardour/meter.h" +#include "ardour/route.h" +#include "ardour/session.h" +#include "ardour/send.h" +#include "ardour/track.h" +#include "ardour/user_bundle.h" #include "mackie_control_protocol.h" #include "surface_port.h" @@ -68,6 +73,8 @@ Strip::Strip (Surface& s, const std::string& name, int index, const map<Button:: , _vselect (0) , _fader_touch (0) , _vpot (0) + , _vpot_mode (PanAzimuth) + , _preflip_vpot_mode (PanAzimuth) , _fader (0) , _index (index) , _surface (&s) @@ -132,64 +139,105 @@ Strip::set_route (boost::shared_ptr<Route> r) } route_connections.drop_connections (); + + _solo->set_control (boost::shared_ptr<AutomationControl>()); + _mute->set_control (boost::shared_ptr<AutomationControl>()); + _select->set_control (boost::shared_ptr<AutomationControl>()); + _recenable->set_control (boost::shared_ptr<AutomationControl>()); + _fader->set_control (boost::shared_ptr<AutomationControl>()); + _vpot->set_control (boost::shared_ptr<AutomationControl>()); _route = r; - if (r) { - - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 strip %2 now mapping route %3\n", - _surface->number(), _index, _route->name())); - + if (!r) { + return; + } - if (_solo) { - _solo->set_normal_control (_route->solo_control()); - _solo->set_modified_control (boost::shared_ptr<AutomationControl>()); - _route->solo_control()->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_solo_changed, this), ui_context()); - } + DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 strip %2 now mapping route %3\n", + _surface->number(), _index, _route->name())); + + _solo->set_control (_route->solo_control()); + _mute->set_control (_route->mute_control()); + set_vpot_mode (PanAzimuth); + + _route->solo_control()->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_solo_changed, this), ui_context()); + _route->mute_control()->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_mute_changed, this), ui_context()); - if (_mute) { - _mute->set_normal_control (_route->mute_control()); - _mute->set_modified_control (boost::shared_ptr<AutomationControl>()); - _route->mute_control()->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_mute_changed, this), ui_context()); - } - - _route->gain_control()->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_gain_changed, this, false), ui_context()); - - _route->PropertyChanged.connect (route_connections, invalidator(), ui_bind (&Strip::notify_property_changed, this, _1), ui_context()); - - if (_route->pannable()) { - _route->pannable()->pan_azimuth_control->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_panner_changed, this, false), ui_context()); - _route->pannable()->pan_width_control->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_panner_changed, this, false), ui_context()); - } + boost::shared_ptr<Pannable> pannable = _route->pannable(); - /* bind fader & pan pot, as appropriate for current flip mode */ + if (pannable) { + pannable->pan_azimuth_control->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_panner_changed, this, false), ui_context()); + pannable->pan_width_control->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_panner_changed, this, false), ui_context()); + } + _route->gain_control()->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_gain_changed, this, false), ui_context()); + _route->PropertyChanged.connect (route_connections, invalidator(), ui_bind (&Strip::notify_property_changed, this, _1), ui_context()); + + boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<ARDOUR::Track>(_route); + + if (trk) { + _recenable->set_control (trk->rec_enable_control()); + trk->rec_enable_control()->Changed .connect(route_connections, invalidator(), ui_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. + + _route->active_changed.connect (route_connections, invalidator(), ui_bind (&Strip::notify_active_changed, this), ui_context()); + _route->DropReferences.connect (route_connections, invalidator(), ui_bind (&Strip::notify_route_deleted, this), ui_context()); + + /* Update */ + + notify_all (); - flip_mode_changed (false); - - boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<ARDOUR::Track>(_route); + /* setup legal VPot modes for this route */ - if (trk) { - _recenable->set_normal_control (trk->rec_enable_control()); - _recenable->set_modified_control (boost::shared_ptr<AutomationControl>()); - trk->rec_enable_control()->Changed .connect(route_connections, invalidator(), ui_bind (&Strip::notify_record_enable_changed, this), ui_context()); + build_input_list (_route->input()->n_ports()); + build_output_list (_route->output()->n_ports()); + + current_pot_modes.clear(); + + if (pannable) { + boost::shared_ptr<Panner> panner = pannable->panner(); + if (panner) { + set<Evoral::Parameter> automatable = panner->what_can_be_automated (); + set<Evoral::Parameter>::iterator a; + + if ((a = automatable.find (PanAzimuthAutomation)) != automatable.end()) { + current_pot_modes.push_back (PanAzimuth); + } + + if ((a = automatable.find (PanWidthAutomation)) != automatable.end()) { + current_pot_modes.push_back (PanWidth); + } } - - // TODO this works when a currently-banked route is made inactive, but not - // when a route is activated which should be currently banked. - - _route->active_changed.connect (route_connections, invalidator(), ui_bind (&Strip::notify_active_changed, this), ui_context()); - _route->DropReferences.connect (route_connections, invalidator(), ui_bind (&Strip::notify_route_deleted, this), ui_context()); - - // TODO - // SelectedChanged - // RemoteControlIDChanged. Better handled at Session level. + } - /* Update */ + current_pot_modes.push_back (Input); + current_pot_modes.push_back (Output); - notify_all (); - } else { - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 strip %2 now unmapped\n", - _surface->number(), _index)); + if (_route->nth_send (0) != 0) { + current_pot_modes.push_back (Send1); + } + if (_route->nth_send (1) != 0) { + current_pot_modes.push_back (Send2); + } + if (_route->nth_send (2) != 0) { + current_pot_modes.push_back (Send3); + } + if (_route->nth_send (3) != 0) { + current_pot_modes.push_back (Send4); + } + if (_route->nth_send (4) != 0) { + current_pot_modes.push_back (Send5); + } + if (_route->nth_send (5) != 0) { + current_pot_modes.push_back (Send6); + } + if (_route->nth_send (6) != 0) { + current_pot_modes.push_back (Send7); + } + if (_route->nth_send (7) != 0) { + current_pot_modes.push_back (Send8); } } @@ -353,132 +401,153 @@ Strip::notify_panner_changed (bool force_update) } void -Strip::handle_button (Button& button, ButtonState bs) +Strip::select_event (Button& button, ButtonState bs) { - if (bs == press) { - button.set_in_use (true); - } else { - button.set_in_use (false); - } - - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("strip %1 handling button %2 press ? %3\n", _index, button.bid(), (bs == press))); + DEBUG_TRACE (DEBUG::MackieControl, "select button\n"); - int ms = _surface->mcp().modifier_state(); - bool modified = (ms & MackieControlProtocol::MODIFIER_CONTROL); - - if (button.bid() == Button::Select) { - - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("select touch, modifiers %1\n", ms)); - - if (bs == press) { - - if (ms & MackieControlProtocol::MODIFIER_CMDALT) { - _controls_locked = !_controls_locked; - _surface->write (display (1,_controls_locked ? "Locked" : "Unlock")); - queue_display_reset (1000); - return; - } + if (bs == press) { + + int ms = _surface->mcp().modifier_state(); - if (ms & MackieControlProtocol::MODIFIER_SHIFT) { - /* reset to default */ - boost::shared_ptr<AutomationControl> ac = _vpot->control (modified); - if (ac) { - ac->set_value (ac->normal()); - } + if (ms & MackieControlProtocol::MODIFIER_CMDALT) { + _controls_locked = !_controls_locked; + _surface->write (display (1,_controls_locked ? "Locked" : "Unlock")); + queue_display_reset (1000); return; - } - - DEBUG_TRACE (DEBUG::MackieControl, "add select button on press\n"); - _surface->mcp().add_down_select_button (_surface->number(), _index); - _surface->mcp().select_range (); - - } else { - DEBUG_TRACE (DEBUG::MackieControl, "remove select button on release\n"); - _surface->mcp().remove_down_select_button (_surface->number(), _index); } - - return; - } - - if (button.bid() == Button::VSelect) { - if (bs == press) { - /* swap controls on the vpot */ - boost::shared_ptr<AutomationControl> ac = button.control (true); - button.set_modified_control (button.control (false)); - button.set_normal_control (ac); - _surface->write (display (1, static_display_string ())); + + if (ms & MackieControlProtocol::MODIFIER_SHIFT) { + /* reset to default */ + boost::shared_ptr<AutomationControl> ac = _vpot->control (); + if (ac) { + ac->set_value (ac->normal()); + } + return; } - - return; + + DEBUG_TRACE (DEBUG::MackieControl, "add select button on press\n"); + _surface->mcp().add_down_select_button (_surface->number(), _index); + _surface->mcp().select_range (); + + } else { + DEBUG_TRACE (DEBUG::MackieControl, "remove select button on release\n"); + _surface->mcp().remove_down_select_button (_surface->number(), _index); } +} - if (button.bid() == Button::FaderTouch) { +void +Strip::vselect_event (Button& button, ButtonState bs) +{ + if (bs == press) { - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("fader touch, press ? %1\n", (bs == press))); + boost::shared_ptr<AutomationControl> ac = button.control (); - /* never use the modified control for fader stuff */ + if (ac) { + + int ms = _surface->mcp().modifier_state(); + + if (ms & MackieControlProtocol::MODIFIER_SHIFT) { + /* reset to default/normal value */ + ac->set_value (ac->normal()); - if (bs == press) { + } else { + next_pot_mode (); + } + } + } +} - _fader->set_in_use (true); - _fader->start_touch (_surface->mcp().transport_frame(), false); - boost::shared_ptr<AutomationControl> ac = _fader->control (false); +void +Strip::fader_touch_event (Button& button, ButtonState bs) +{ + DEBUG_TRACE (DEBUG::MackieControl, string_compose ("fader touch, press ? %1\n", (bs == press))); + + /* never use the modified control for fader stuff */ + + if (bs == press) { + + _fader->set_in_use (true); + _fader->start_touch (_surface->mcp().transport_frame()); + boost::shared_ptr<AutomationControl> ac = _fader->control (); if (ac) { do_parameter_display ((AutomationType) ac->parameter().type(), ac->internal_to_interface (ac->get_value())); queue_display_reset (2000); } + + } else { + + _fader->set_in_use (false); + _fader->stop_touch (_surface->mcp().transport_frame(), true); + + } +} - } else { - _fader->set_in_use (false); - _fader->stop_touch (_surface->mcp().transport_frame(), true, false); +void +Strip::handle_button (Button& button, ButtonState bs) +{ + boost::shared_ptr<AutomationControl> control; - } - - return; + if (bs == press) { + button.set_in_use (true); + } else { + button.set_in_use (false); } - boost::shared_ptr<AutomationControl> control = button.control (modified); + DEBUG_TRACE (DEBUG::MackieControl, string_compose ("strip %1 handling button %2 press ? %3\n", _index, button.bid(), (bs == press))); + + switch (button.bid()) { + case Button::Select: + select_event (button, bs); + break; - if (control) { - - if (bs == press) { - DEBUG_TRACE (DEBUG::MackieControl, "add button on release\n"); - _surface->mcp().add_down_button ((AutomationType) control->parameter().type(), _surface->number(), _index); - - float new_value; + case Button::VSelect: + vselect_event (button, bs); + break; - if (ms & MackieControlProtocol::MODIFIER_OPTION) { - /* reset to default/normal value */ - new_value = control->normal(); - } else { - new_value = control->get_value() ? 0.0 : 1.0; - } + case Button::FaderTouch: + fader_touch_event (button, bs); + break; - /* get all controls that either have their - * button down or are within a range of - * several down buttons - */ - - MackieControlProtocol::ControlList controls = _surface->mcp().down_controls ((AutomationType) control->parameter().type()); - - - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("there are %1 buttons down for control type %2, new value = %3\n", + default: + if ((control = button.control ())) { + if (bs == press) { + DEBUG_TRACE (DEBUG::MackieControl, "add button on release\n"); + _surface->mcp().add_down_button ((AutomationType) control->parameter().type(), _surface->number(), _index); + + float new_value; + int ms = _surface->mcp().modifier_state(); + + if (ms & MackieControlProtocol::MODIFIER_SHIFT) { + /* reset to default/normal value */ + new_value = control->normal(); + } else { + new_value = control->get_value() ? 0.0 : 1.0; + } + + /* get all controls that either have their + * button down or are within a range of + * several down buttons + */ + + MackieControlProtocol::ControlList controls = _surface->mcp().down_controls ((AutomationType) control->parameter().type()); + + + DEBUG_TRACE (DEBUG::MackieControl, string_compose ("there are %1 buttons down for control type %2, new value = %3\n", controls.size(), control->parameter().type(), new_value)); - /* apply change */ - - for (MackieControlProtocol::ControlList::iterator c = controls.begin(); c != controls.end(); ++c) { - (*c)->set_value (new_value); + /* apply change */ + + for (MackieControlProtocol::ControlList::iterator c = controls.begin(); c != controls.end(); ++c) { + (*c)->set_value (new_value); + } + + } else { + DEBUG_TRACE (DEBUG::MackieControl, "remove button on release\n"); + _surface->mcp().remove_down_button ((AutomationType) control->parameter().type(), _surface->number(), _index); } - - } else { - DEBUG_TRACE (DEBUG::MackieControl, "remove button on release\n"); - _surface->mcp().remove_down_button ((AutomationType) control->parameter().type(), _surface->number(), _index); } - - } else { - DEBUG_TRACE (DEBUG::MackieControl, string_compose ("button has no control at present (modified ? %1)\n", modified)); + break; } } @@ -518,10 +587,8 @@ Strip::handle_fader (Fader& fader, float position) { DEBUG_TRACE (DEBUG::MackieControl, string_compose ("fader to %1\n", position)); - bool modified = (_surface->mcp().modifier_state() & MackieControlProtocol::MODIFIER_CONTROL); - - fader.set_value (position, modified); - fader.start_touch (_surface->mcp().transport_frame(), modified); + fader.set_value (position); + fader.start_touch (_surface->mcp().transport_frame()); queue_display_reset (2000); // must echo bytes back to slider now, because @@ -538,15 +605,14 @@ Strip::handle_pot (Pot& pot, float delta) stop moving. So to get a stop event, we need to use a timeout. */ - bool modified = (_surface->mcp().modifier_state() & MackieControlProtocol::MODIFIER_CONTROL); - pot.start_touch (_surface->mcp().transport_frame(), modified); - _surface->mcp().add_in_use_timeout (*_surface, pot, pot.control (modified)); + pot.start_touch (_surface->mcp().transport_frame()); + _surface->mcp().add_in_use_timeout (*_surface, pot, pot.control ()); - double p = pot.get_value (modified); + double p = pot.get_value (); p += delta; p = min (1.0, p); p = max (0.0, p); - pot.set_value (p, modified); + pot.set_value (p); } void @@ -673,41 +739,41 @@ Strip::gui_selection_changed (ARDOUR::RouteNotificationListPtr rl) } string -Strip::static_display_string () const +Strip::vpot_mode_string () const { - if (!_vpot) { - return string(); - } - - boost::shared_ptr<AutomationControl> ac = _vpot->control (false); - - if (!ac) { - return string(); - } - - /* don't use canonical controllable names here because we're - * limited by space concerns - */ - - switch((AutomationType)ac->parameter().type()) { - case GainAutomation: + switch (_vpot_mode) { + case Gain: return "Fader"; - break; - case PanAzimuthAutomation: + case PanAzimuth: return "Pan"; - break; - case PanWidthAutomation: + case PanWidth: return "Width"; - break; - case PanElevationAutomation: - case PanFrontBackAutomation: - case PanLFEAutomation: - break; - case PluginAutomation: - return string_compose ("Param %d", ac->parameter().id()); - break; - default: - break; + case PanElevation: + return "Elev"; + case PanFrontBack: + return "F/Rear"; + case PanLFE: + return "LFE"; + case Input: + return "Input"; + case Output: + return "Output"; + case Send1: + return "Send 1"; + case Send2: + return "Send 2"; + case Send3: + return "Send 3"; + case Send4: + return "Send 4"; + case Send5: + return "Send 5"; + case Send6: + return "Send 6"; + case Send7: + return "Send 7"; + case Send8: + return "Send 8"; } return "???"; @@ -720,30 +786,13 @@ Strip::flip_mode_changed (bool notify) return; } - boost::shared_ptr<Pannable> pannable = _route->pannable(); - - if (_surface->mcp().flip_mode()) { - - if (pannable) { - _fader->set_normal_control (pannable->pan_azimuth_control); - _fader->set_modified_control (pannable->pan_width_control); - } - _vpot->set_normal_control (_route->gain_control()); - _vpot->set_modified_control (boost::shared_ptr<AutomationControl>()); - - _surface->write (display (1, static_display_string ())); - - } else { + boost::shared_ptr<AutomationControl> fader_controllable = _fader->control (); + boost::shared_ptr<AutomationControl> vpot_controllable = _vpot->control (); - if (pannable) { - _vpot->set_normal_control (pannable->pan_azimuth_control); - _vpot->set_modified_control (pannable->pan_width_control); - } - _fader->set_normal_control (_route->gain_control()); - _fader->set_modified_control (boost::shared_ptr<AutomationControl>()); + _fader->set_control (vpot_controllable); + _vpot->set_control (fader_controllable); - _surface->write (display (1, static_display_string())); - } + _surface->write (display (1, vpot_mode_string ())); if (notify) { notify_all (); @@ -775,7 +824,214 @@ Strip::clear_display_reset () void Strip::reset_display () { - _surface->write (display (1, static_display_string())); + _surface->write (display (1, vpot_mode_string())); clear_display_reset (); } +struct RouteCompareByName { + bool operator() (boost::shared_ptr<Route> a, boost::shared_ptr<Route> b) { + return a->name().compare (b->name()) < 0; + } +}; + +void +Strip::maybe_add_to_bundle_map (BundleMap& bm, boost::shared_ptr<Bundle> b, bool for_input, const ChanCount& channels) +{ + if (b->ports_are_outputs() == !for_input || b->nchannels() != channels) { + return; + } + + bm[b->name()] = b; +} + +void +Strip::build_input_list (const ChanCount& channels) +{ + boost::shared_ptr<ARDOUR::BundleList> b = _surface->mcp().get_session().bundles (); + + input_bundles.clear (); + + /* give user bundles first chance at being in the menu */ + + for (ARDOUR::BundleList::iterator i = b->begin(); i != b->end(); ++i) { + if (boost::dynamic_pointer_cast<UserBundle> (*i)) { + maybe_add_to_bundle_map (input_bundles, *i, true, channels); + } + } + + for (ARDOUR::BundleList::iterator i = b->begin(); i != b->end(); ++i) { + if (boost::dynamic_pointer_cast<UserBundle> (*i) == 0) { + maybe_add_to_bundle_map (input_bundles, *i, true, channels); + } + } + + boost::shared_ptr<ARDOUR::RouteList> routes = _surface->mcp().get_session().get_routes (); + RouteList copy = *routes; + copy.sort (RouteCompareByName ()); + + for (ARDOUR::RouteList::const_iterator i = copy.begin(); i != copy.end(); ++i) { + maybe_add_to_bundle_map (input_bundles, (*i)->output()->bundle(), true, channels); + } + +} + +void +Strip::build_output_list (const ChanCount& channels) +{ + boost::shared_ptr<ARDOUR::BundleList> b = _surface->mcp().get_session().bundles (); + + output_bundles.clear (); + + /* give user bundles first chance at being in the menu */ + + for (ARDOUR::BundleList::iterator i = b->begin(); i != b->end(); ++i) { + if (boost::dynamic_pointer_cast<UserBundle> (*i)) { + maybe_add_to_bundle_map (output_bundles, *i, false, channels); + } + } + + for (ARDOUR::BundleList::iterator i = b->begin(); i != b->end(); ++i) { + if (boost::dynamic_pointer_cast<UserBundle> (*i) == 0) { + maybe_add_to_bundle_map (output_bundles, *i, false, channels); + } + } + + boost::shared_ptr<ARDOUR::RouteList> routes = _surface->mcp().get_session().get_routes (); + RouteList copy = *routes; + copy.sort (RouteCompareByName ()); + + for (ARDOUR::RouteList::const_iterator i = copy.begin(); i != copy.end(); ++i) { + maybe_add_to_bundle_map (output_bundles, (*i)->input()->bundle(), false, channels); + } +} + +void +Strip::next_pot_mode () +{ + vector<PotMode>::iterator i; + + if (_surface->mcp().flip_mode()) { + /* do not change vpot mode while in flipped mode */ + _surface->write (display (1, "Flip")); + queue_display_reset (2000); + return; + } + + for (i = current_pot_modes.begin(); i != current_pot_modes.end(); ++i) { + if ((*i) == _vpot_mode) { + break; + } + } + + /* move to the next mode in the list, or back to the start (which will + also happen if the current mode is not in the current pot mode list) + */ + + if (i != current_pot_modes.end()) { + ++i; + } + + if (i == current_pot_modes.end()) { + i = current_pot_modes.begin(); + } + + set_vpot_mode (*i); +} + +void +Strip::set_vpot_mode (PotMode m) +{ + boost::shared_ptr<Send> send; + boost::shared_ptr<Pannable> pannable; + + if (!_route) { + return; + } + + _vpot_mode = m; + + switch (_vpot_mode) { + case Gain: + break; + case PanAzimuth: + pannable = _route->pannable (); + if (pannable) { + if (_surface->mcp().flip_mode()) { + /* gain to vpot, pan azi to fader */ + _vpot->set_control (_route->gain_control()); + if (pannable) { + _fader->set_control (pannable->pan_azimuth_control); + } + _vpot_mode = Gain; + } else { + /* gain to fader, pan azi to vpot */ + _fader->set_control (_route->gain_control()); + if (pannable) { + _vpot->set_control (pannable->pan_azimuth_control); + } + _vpot_mode = PanAzimuth; + } + } + break; + case PanWidth: + pannable = _route->pannable (); + if (pannable) { + if (_surface->mcp().flip_mode()) { + /* gain to vpot, pan width to fader */ + _vpot->set_control (_route->gain_control()); + if (pannable) { + _fader->set_control (pannable->pan_width_control); + } + _vpot_mode = Gain; + } else { + /* gain to fader, pan width to vpot */ + _fader->set_control (_route->gain_control()); + if (pannable) { + _vpot->set_control (pannable->pan_width_control); + } + } + } + break; + case PanElevation: + break; + case PanFrontBack: + break; + case PanLFE: + break; + case Input: + break; + case Output: + break; + case Send1: + send = boost::dynamic_pointer_cast<Send> (_route->nth_send (0)); + if (send) { + if (_surface->mcp().flip_mode()) { + /* route gain to vpot, send gain to fader */ + _fader->set_control (send->amp()->gain_control()); + _vpot->set_control (_route->gain_control()); + _vpot_mode = Gain; + } else { + /* route gain to fader, send gain to vpot */ + _vpot->set_control (send->amp()->gain_control()); + _fader->set_control (_route->gain_control()); + } + } + break; + case Send2: + break; + case Send3: + break; + case Send4: + break; + case Send5: + break; + case Send6: + break; + case Send7: + break; + case Send8: + break; + }; + + _surface->write (display (1, vpot_mode_string())); +} diff --git a/libs/surfaces/mackie/strip.h b/libs/surfaces/mackie/strip.h index 56c6a2f720..7de9d27f01 100644 --- a/libs/surfaces/mackie/strip.h +++ b/libs/surfaces/mackie/strip.h @@ -17,6 +17,8 @@ namespace ARDOUR { class Route; + class Bundle; + class ChannelCount; } namespace Mackie { @@ -79,6 +81,25 @@ public: MidiByteArray gui_selection_changed (ARDOUR::RouteNotificationListPtr); private: + enum PotMode { + Gain, + PanAzimuth, + PanWidth, + PanElevation, + PanFrontBack, + PanLFE, + Input, + Output, + Send1, + Send2, + Send3, + Send4, + Send5, + Send6, + Send7, + Send8, + }; + Button* _solo; Button* _recenable; Button* _mute; @@ -86,13 +107,14 @@ private: Button* _vselect; Button* _fader_touch; Pot* _vpot; + PotMode _vpot_mode; + PotMode _preflip_vpot_mode; Fader* _fader; Meter* _meter; int _index; Surface* _surface; bool _controls_locked; uint64_t _reset_display_at; - boost::shared_ptr<ARDOUR::Route> _route; PBD::ScopedConnectionList route_connections; @@ -111,12 +133,28 @@ private: void update_automation (); void update_meter (); - std::string static_display_string () const; + std::string vpot_mode_string () const; void queue_display_reset (uint32_t msecs); void clear_display_reset (); void reset_display (); void do_parameter_display (ARDOUR::AutomationType, float val); + + typedef std::map<std::string,boost::shared_ptr<ARDOUR::Bundle> > BundleMap; + BundleMap input_bundles; + BundleMap output_bundles; + + void build_input_list (const ARDOUR::ChanCount&); + void build_output_list (const ARDOUR::ChanCount&); + void maybe_add_to_bundle_map (BundleMap& bm, boost::shared_ptr<ARDOUR::Bundle>, bool for_input, const ARDOUR::ChanCount&); + + void select_event (Button&, ButtonState); + void vselect_event (Button&, ButtonState); + void fader_touch_event (Button&, ButtonState); + + std::vector<PotMode> current_pot_modes; + void next_pot_mode (); + void set_vpot_mode (PotMode); }; } diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc index aeb0649fa1..f1f308209c 100644 --- a/libs/surfaces/mackie/surface.cc +++ b/libs/surfaces/mackie/surface.cc @@ -221,14 +221,14 @@ Surface::setup_master () return; } - _master_fader->set_normal_control (m->gain_control()); + _master_fader->set_control (m->gain_control()); m->gain_control()->Changed.connect (*this, invalidator(), ui_bind (&Surface::master_gain_changed, this), ui_context()); } void Surface::master_gain_changed () { - boost::shared_ptr<AutomationControl> ac = _master_fader->control(false); + boost::shared_ptr<AutomationControl> ac = _master_fader->control(); float pos = ac->internal_to_interface (ac->get_value()); _port->write (_master_fader->set_position (pos)); } @@ -333,7 +333,7 @@ Surface::handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t pb, uin strip->handle_fader (*fader, pos); } else { /* master fader */ - fader->set_value (pos, false); // alter master gain + fader->set_value (pos); // alter master gain _port->write (fader->set_position (pos)); // write back value (required for servo) } } else { |