MCP: start generalizing mapping between surface controls and ARDOUR::AutomationControl; simplify flip mode; more good stuff

git-svn-id: svn://localhost/ardour2/branches/3.0@11949 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2012-04-12 21:02:43 +00:00
parent b4235221ab
commit 939801a8d8
10 changed files with 279 additions and 243 deletions

View file

@ -20,11 +20,12 @@
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
#include "ardour/automation_control.h"
#include "controls.h" #include "controls.h"
#include "types.h" #include "types.h"
#include "surface.h" #include "surface.h"
#include "control_group.h" #include "control_group.h"
#include "button.h" #include "button.h"
#include "led.h" #include "led.h"
#include "pot.h" #include "pot.h"
@ -35,6 +36,7 @@
using namespace Mackie; using namespace Mackie;
using namespace std; using namespace std;
using ARDOUR::AutomationControl;
void Group::add (Control& control) void Group::add (Control& control)
{ {
@ -91,3 +93,57 @@ Jog::factory (Surface& surface, int id, const char* name, Group& group)
return j; return j;
} }
void
Control::set_normal_control (boost::shared_ptr<AutomationControl> ac)
{
normal_ac = ac;
}
void
Control::set_modified_control (boost::shared_ptr<AutomationControl> ac)
{
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 (modified_ac->interface_to_internal (val));
}
}
float
Control::get_value (bool modified)
{
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;
}
void
Control::start_touch (double when, bool modified)
{
if (modified && modified_ac) {
return modified_ac->start_touch (when);
} else if (normal_ac) {
return normal_ac->start_touch (when);
}
}
void
Control::stop_touch (double when, bool mark, bool modified)
{
if (modified && modified_ac) {
return modified_ac->stop_touch (when, mark);
} else if (normal_ac) {
return normal_ac->stop_touch (when, mark);
}
}

View file

@ -25,11 +25,17 @@
#include <string> #include <string>
#include <stdint.h> #include <stdint.h>
#include <boost/smart_ptr.hpp>
#include "pbd/signals.h" #include "pbd/signals.h"
#include "mackie_control_exception.h" #include "mackie_control_exception.h"
#include "midi_byte_array.h" #include "midi_byte_array.h"
namespace ARDOUR {
class AutomationControl;
}
namespace Mackie namespace Mackie
{ {
@ -60,7 +66,25 @@ public:
*/ */
Control* in_use_touch_control; Control* in_use_touch_control;
private: boost::shared_ptr<ARDOUR::AutomationControl> control (bool modified) const { return modified ? modified_ac : normal_ac; }
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);
virtual void start_touch (double when, bool modified);
virtual void stop_touch (double when, bool mark, bool modified);
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; int _id;
std::string _name; std::string _name;
Group& _group; Group& _group;

View file

@ -39,6 +39,7 @@
#include "pbd/memento_command.h" #include "pbd/memento_command.h"
#include "pbd/convert.h" #include "pbd/convert.h"
#include "ardour/automation_control.h"
#include "ardour/dB.h" #include "ardour/dB.h"
#include "ardour/debug.h" #include "ardour/debug.h"
#include "ardour/location.h" #include "ardour/location.h"
@ -98,8 +99,8 @@ MackieControlProtocol::MackieControlProtocol (Session& session)
, _gui (0) , _gui (0)
, _zoom_mode (false) , _zoom_mode (false)
, _scrub_mode (false) , _scrub_mode (false)
, _flip_mode (Normal) , _flip_mode (false)
, _view_mode (Global) , _view_mode (Mixer)
, _current_selected_track (-1) , _current_selected_track (-1)
{ {
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n"); DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n");
@ -227,7 +228,7 @@ MackieControlProtocol::get_sorted_routes()
} }
switch (_view_mode) { switch (_view_mode) {
case Global: case Mixer:
break; break;
case AudioTracks: case AudioTracks:
break; break;
@ -914,19 +915,18 @@ MackieControlProtocol::stop ()
* @param touch_control a touch control to emit an event for, or 0. * @param touch_control a touch control to emit an event for, or 0.
*/ */
void void
MackieControlProtocol::add_in_use_timeout (Surface& surface, Control& in_use_control, Control* touch_control) MackieControlProtocol::add_in_use_timeout (Surface& surface, Control& in_use_control, boost::weak_ptr<AutomationControl> touched)
{ {
Glib::RefPtr<Glib::TimeoutSource> timeout (Glib::TimeoutSource::create (250)); // milliseconds Glib::RefPtr<Glib::TimeoutSource> timeout (Glib::TimeoutSource::create (250)); // milliseconds
in_use_control.in_use_connection.disconnect (); in_use_control.in_use_connection.disconnect ();
in_use_control.in_use_connection = timeout->connect ( in_use_control.in_use_connection = timeout->connect (
sigc::bind (sigc::mem_fun (*this, &MackieControlProtocol::control_in_use_timeout), &surface, &in_use_control, touch_control)); sigc::bind (sigc::mem_fun (*this, &MackieControlProtocol::control_in_use_timeout), &surface, &in_use_control, touched));
in_use_control.in_use_touch_control = touch_control;
timeout->attach (main_loop()->get_context()); timeout->attach (main_loop()->get_context());
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("timeout queued for surface %1, control %2 touch control %3\n", DEBUG_TRACE (DEBUG::MackieControl, string_compose ("timeout queued for surface %1, control %2\n",
surface.number(), &in_use_control, touch_control));} surface.number(), &in_use_control));}
/** Handle timeouts to reset in_use for controls that can't /** Handle timeouts to reset in_use for controls that can't
* do this by themselves (e.g. pots, and faders without touch support). * do this by themselves (e.g. pots, and faders without touch support).
@ -934,15 +934,17 @@ MackieControlProtocol::add_in_use_timeout (Surface& surface, Control& in_use_con
* @param touch_control a touch control to emit an event for, or 0. * @param touch_control a touch control to emit an event for, or 0.
*/ */
bool bool
MackieControlProtocol::control_in_use_timeout (Surface* surface, Control* in_use_control, Control* touch_control) MackieControlProtocol::control_in_use_timeout (Surface* surface, Control* in_use_control, boost::weak_ptr<AutomationControl> wtouched)
{ {
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("timeout elapsed for surface %1, control %2 touch control %3\n", boost::shared_ptr<AutomationControl> touched (wtouched.lock());
surface->number(), in_use_control, touch_control));
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("timeout elapsed for surface %1, control %2\n", surface->number(), in_use_control));
in_use_control->set_in_use (false); in_use_control->set_in_use (false);
if (touch_control) { if (touched) {
/* figure out what to do here */ /* end the touch, and mark the end */
touched->stop_touch (session->transport_frame(), true);
} }
// only call this method once from the timer // only call this method once from the timer
@ -1140,9 +1142,9 @@ MackieControlProtocol::set_view_mode (ViewMode m)
} }
void void
MackieControlProtocol::set_flip_mode (FlipMode m) MackieControlProtocol::set_flip_mode (bool yn)
{ {
_flip_mode = m; _flip_mode = yn;
for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) { for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
(*s)->update_flip_mode_display (); (*s)->update_flip_mode_display ();
@ -1173,7 +1175,7 @@ MackieControlProtocol::force_special_route_to_strip (boost::shared_ptr<Route> r,
Strip* strip = (*s)->nth_strip (strip_number); Strip* strip = (*s)->nth_strip (strip_number);
if (strip) { if (strip) {
strip->set_route (session->master_out()); strip->set_route (session->master_out());
strip->lock_route (); strip->lock_controls ();
} }
} }
} }
@ -1186,3 +1188,9 @@ MackieControlProtocol::gui_track_selection_changed (ARDOUR::RouteNotificationLis
(*s)->gui_selection_changed (rl); (*s)->gui_selection_changed (rl);
} }
} }
framepos_t
MackieControlProtocol::transport_frame() const
{
return session->transport_frame();
}

View file

@ -42,7 +42,9 @@
#include "timer.h" #include "timer.h"
#include "device_info.h" #include "device_info.h"
class RouteTimeAxisView; namespace ARDOUR {
class AutomationControl;
}
namespace MIDI { namespace MIDI {
class Port; class Port;
@ -92,7 +94,7 @@ class MackieControlProtocol
static const int MODIFIER_CMDALT; static const int MODIFIER_CMDALT;
enum ViewMode { enum ViewMode {
Global, Mixer,
Dynamics, Dynamics,
EQ, EQ,
Loop, Loop,
@ -120,11 +122,11 @@ class MackieControlProtocol
int set_active (bool yn); int set_active (bool yn);
void set_device (const std::string&); void set_device (const std::string&);
FlipMode flip_mode () const { return _flip_mode; } bool flip_mode () const { return _flip_mode; }
ViewMode view_mode () const { return _view_mode; } ViewMode view_mode () const { return _view_mode; }
void set_view_mode (ViewMode); void set_view_mode (ViewMode);
void set_flip_mode (FlipMode); void set_flip_mode (bool);
XMLNode& get_state (); XMLNode& get_state ();
int set_state (const XMLNode&, int version); int set_state (const XMLNode&, int version);
@ -175,8 +177,9 @@ class MackieControlProtocol
void update_global_led(const std::string & name, Mackie::LedState); void update_global_led(const std::string & name, Mackie::LedState);
ARDOUR::Session & get_session() { return *session; } ARDOUR::Session & get_session() { return *session; }
framepos_t transport_frame() const;
void add_in_use_timeout (Mackie::Surface& surface, Mackie::Control& in_use_control, Mackie::Control* touch_control);
void add_in_use_timeout (Mackie::Surface& surface, Mackie::Control& in_use_control, boost::weak_ptr<ARDOUR::AutomationControl> touched);
int modifier_state() const { return _modifier_state; } int modifier_state() const { return _modifier_state; }
@ -262,7 +265,7 @@ class MackieControlProtocol
void* _gui; void* _gui;
bool _zoom_mode; bool _zoom_mode;
bool _scrub_mode; bool _scrub_mode;
FlipMode _flip_mode; bool _flip_mode;
ViewMode _view_mode; ViewMode _view_mode;
int _current_selected_track; int _current_selected_track;
int _modifier_state; int _modifier_state;
@ -272,7 +275,7 @@ class MackieControlProtocol
void create_surfaces (); void create_surfaces ();
void port_connected_or_disconnected (std::string, std::string, bool); void port_connected_or_disconnected (std::string, std::string, bool);
bool control_in_use_timeout (Mackie::Surface*, Mackie::Control *, Mackie::Control *); bool control_in_use_timeout (Mackie::Surface*, Mackie::Control *, boost::weak_ptr<ARDOUR::AutomationControl>);
bool periodic(); bool periodic();
void build_gui (); void build_gui ();
bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port); bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);

View file

@ -820,21 +820,8 @@ MackieControlProtocol::dyn_release (Button &)
LedState LedState
MackieControlProtocol::flip_press (Button &) MackieControlProtocol::flip_press (Button &)
{ {
FlipMode m; set_flip_mode (!_flip_mode);
return (_flip_mode ? on : off);
if (_modifier_state == 0) {
if (_flip_mode != Normal) {
m = Normal;
} else {
m = Swap;
}
} else if (_modifier_state & MODIFIER_CONTROL) {
m = Zero;
}
set_flip_mode (m);
return (_flip_mode != Normal ? on : off);
} }
LedState LedState
MackieControlProtocol::flip_release (Button &) MackieControlProtocol::flip_release (Button &)

View file

@ -48,17 +48,10 @@ Pot::set_onoff (bool onoff)
return update_message (); return update_message ();
} }
MidiByteArray
Pot::set_value (float normalized)
{
value = normalized;
return update_message ();
}
MidiByteArray MidiByteArray
Pot::set_all (float val, bool onoff, Mode m) Pot::set_all (float val, bool onoff, Mode m)
{ {
value = val; position = val;
on = onoff; on = onoff;
mode = m; mode = m;
return update_message (); return update_message ();
@ -70,15 +63,15 @@ Pot::update_message ()
// TODO do an exact calc for 0.50? To allow manually re-centering the port. // TODO do an exact calc for 0.50? To allow manually re-centering the port.
// center on or off // center on or off
MIDI::byte msg = (value > 0.45 && value < 0.55 ? 1 : 0) << 6; MIDI::byte msg = (position > 0.45 && position < 0.55 ? 1 : 0) << 6;
// mode // mode
msg |= (mode << 4); msg |= (mode << 4);
// value, but only if off hasn't explicitly been set // position, but only if off hasn't explicitly been set
if (on) { if (on) {
msg += (lrintf (value * 10.0) + 1) & 0x0f; // 0b00001111 msg += (lrintf (position * 10.0) + 1) & 0x0f; // 0b00001111
} }
/* outbound LED message requires 0x20 to be added to the LED's id /* outbound LED message requires 0x20 to be added to the LED's id

View file

@ -40,23 +40,22 @@ public:
Pot (int id, std::string name, Group & group) Pot (int id, std::string name, Group & group)
: Control (id, name, group) : Control (id, name, group)
, value (0.0) , position (0.0)
, mode (dot) , mode (dot)
, on (true) {} , on (true) {}
MidiByteArray set_mode (Mode); MidiByteArray set_mode (Mode);
MidiByteArray set_value (float);
MidiByteArray set_onoff (bool); MidiByteArray set_onoff (bool);
MidiByteArray set_all (float, bool, Mode); MidiByteArray set_all (float, bool, Mode);
MidiByteArray zero() { return set_value (0.0); } MidiByteArray zero() { return set_all (0.0, on, mode); }
MidiByteArray update_message (); MidiByteArray update_message ();
static Control* factory (Surface&, int id, const char*, Group&); static Control* factory (Surface&, int id, const char*, Group&);
private: private:
float value; float position;
Mode mode; Mode mode;
bool on; bool on;
}; };

View file

@ -69,9 +69,9 @@ Strip::Strip (Surface& s, const std::string& name, int index, StripControlDefini
, _fader (0) , _fader (0)
, _index (index) , _index (index)
, _surface (&s) , _surface (&s)
, _route_locked (false) , _controls_locked (false)
, _last_fader_position_written (-1.0) , _last_gain_position_written (-1.0)
, _last_vpot_position_written (-1.0) , _last_pan_position_written (-1.0)
{ {
/* build the controls for this track, which will automatically add them /* build the controls for this track, which will automatically add them
to the Group to the Group
@ -84,7 +84,6 @@ Strip::Strip (Surface& s, const std::string& name, int index, StripControlDefini
Strip::~Strip () Strip::~Strip ()
{ {
} }
/** /**
@ -149,7 +148,7 @@ void Strip::add (Control & control)
void void
Strip::set_route (boost::shared_ptr<Route> r) Strip::set_route (boost::shared_ptr<Route> r)
{ {
if (_route_locked) { if (_controls_locked) {
return; return;
} }
@ -158,16 +157,18 @@ Strip::set_route (boost::shared_ptr<Route> r)
_route = r; _route = r;
if (r) { if (r) {
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 strip %2 now mapping route %3\n", DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Surface %1 strip %2 now mapping route %3\n",
_surface->number(), _index, _route->name())); _surface->number(), _index, _route->name()));
if (_solo) { if (_solo) {
_solo->set_normal_control (_route->solo_control());
_route->solo_control()->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_solo_changed, this), ui_context()); _route->solo_control()->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_solo_changed, this), ui_context());
} }
if (_mute) { if (_mute) {
_mute->set_normal_control (_route->mute_control());
_route->mute_control()->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_mute_changed, this), ui_context()); _route->mute_control()->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_mute_changed, this), ui_context());
} }
@ -179,10 +180,14 @@ Strip::set_route (boost::shared_ptr<Route> r)
_route->pannable()->pan_azimuth_control->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_panner_changed, this, false), ui_context()); _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()); _route->pannable()->pan_width_control->Changed.connect(route_connections, invalidator(), ui_bind (&Strip::notify_panner_changed, this, false), ui_context());
} }
flip_mode_changed (false);
boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<ARDOUR::Track>(_route); boost::shared_ptr<Track> trk = boost::dynamic_pointer_cast<ARDOUR::Track>(_route);
if (trk) { if (trk) {
// XXX FIX ME WHEN rec-enable IS-A AutomationControl
// _recenable->set_normal_control (trk->rec_enable_control());
trk->rec_enable_control()->Changed .connect(route_connections, invalidator(), ui_bind (&Strip::notify_record_enable_changed, this), ui_context()); trk->rec_enable_control()->Changed .connect(route_connections, invalidator(), ui_bind (&Strip::notify_record_enable_changed, this), ui_context());
} }
@ -261,31 +266,29 @@ Strip::notify_gain_changed (bool force_update)
{ {
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("gain changed for strip %1, flip mode %2\n", _index, _surface->mcp().flip_mode())); DEBUG_TRACE (DEBUG::MackieControl, string_compose ("gain changed for strip %1, flip mode %2\n", _index, _surface->mcp().flip_mode()));
if (_route && _fader) { if (_route) {
if (!_fader->in_use()) { Control* control;
double pos; if (_surface->mcp().flip_mode()) {
control = _vpot;
} else {
control = _fader;
}
switch (_surface->mcp().flip_mode()) { if (!control->in_use()) {
case MackieControlProtocol::Normal:
pos = _route->gain_control()->get_value(); float pos = _route->gain_control()->internal_to_interface (_route->gain_control()->get_value());
break;
if (force_update || pos != _last_gain_position_written) {
case MackieControlProtocol::Swap:
case MackieControlProtocol::Zero: if (_surface->mcp().flip_mode()) {
case MackieControlProtocol::Mirror: _surface->write (_vpot->set_all (pos, true, Pot::boost_cut));
/* fader is used for something else and/or } else {
should not move. _surface->write (_fader->set_position (pos));
*/ }
return; _last_gain_position_written = pos;
}
pos = gain_to_slider_position (pos);
if (force_update || pos != _last_fader_position_written) {
_surface->write (_fader->set_position (pos));
_last_fader_position_written = pos;
} else { } else {
DEBUG_TRACE (DEBUG::MackieControl, "value is stale, no message sent\n"); DEBUG_TRACE (DEBUG::MackieControl, "value is stale, no message sent\n");
} }
@ -321,7 +324,7 @@ Strip::notify_property_changed (const PropertyChange& what_changed)
void void
Strip::notify_panner_changed (bool force_update) Strip::notify_panner_changed (bool force_update)
{ {
if (_route && _vpot) { if (_route) {
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));
@ -332,25 +335,26 @@ Strip::notify_panner_changed (bool force_update)
return; return;
} }
double pos; Control* control;
switch (_surface->mcp().flip_mode()) { if (_surface->mcp().flip_mode()) {
case MackieControlProtocol::Swap: control = _fader;
/* pot is controlling the gain */ } else {
return; control = _vpot;
case MackieControlProtocol::Normal:
case MackieControlProtocol::Zero:
case MackieControlProtocol::Mirror:
pos = pannable->pan_azimuth_control->get_value();
break;
} }
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("\t\tnew position %1\n", pos)); if (!control->in_use()) {
if (force_update || pos != _last_vpot_position_written) { double pos = pannable->pan_azimuth_control->internal_to_interface (pannable->pan_azimuth_control->get_value());
_surface->write (_vpot->set_all (pos, true, Pot::dot));
_last_vpot_position_written = pos; if (force_update || pos != _last_pan_position_written) {
if (_surface->mcp().flip_mode()) {
_surface->write (_fader->set_position (pos));
} else {
_surface->write (_vpot->set_all (pos, true, Pot::dot));
}
_last_pan_position_written = pos;
}
} }
} }
} }
@ -360,48 +364,15 @@ Strip::handle_button (Button& button, ButtonState bs)
{ {
button.set_in_use (bs == press); button.set_in_use (bs == press);
if (!_route) { int lock_mod = (MackieControlProtocol::MODIFIER_CONTROL|MackieControlProtocol::MODIFIER_SHIFT);
// no route so always switch the light off int ms = _surface->mcp().modifier_state();
// because no signals will be emitted by a non-route bool modified = (ms & MackieControlProtocol::MODIFIER_CONTROL);
_surface->write (button.set_state (off));
return;
}
if (bs == press) {
if (button.id() >= Button::recenable_base_id &&
button.id() < Button::recenable_base_id + 8) {
_route->set_record_enabled (!_route->record_enabled(), this);
} else if (button.id() >= Button::mute_base_id &&
button.id() < Button::mute_base_id + 8) {
_route->set_mute (!_route->muted(), this);
} else if (button.id() >= Button::solo_base_id &&
button.id() < Button::solo_base_id + 8) {
_route->set_solo (!_route->soloed(), this);
} else if (button.id() >= Button::select_base_id &&
button.id() < Button::select_base_id + 8) {
int lock_mod = (MackieControlProtocol::MODIFIER_CONTROL|MackieControlProtocol::MODIFIER_SHIFT);
if ((_surface->mcp().modifier_state() & lock_mod) == lock_mod) {
if (_route) {
_route_locked = !_route_locked;
}
} else if (_surface->mcp().modifier_state() == MackieControlProtocol::MODIFIER_SHIFT) {
/* reset gain value to unity */
_route->set_gain (1.0, this);
} else {
_surface->mcp().select_track (_route);
}
} else if (button.id() >= Button::vselect_base_id &&
button.id() < Button::vselect_base_id + 8) {
if (button.id() >= Button::select_base_id &&
button.id() < Button::select_base_id + 8) {
if ((ms & lock_mod) == lock_mod) {
_controls_locked = !_controls_locked;
return;
} }
} }
@ -411,13 +382,24 @@ Strip::handle_button (Button& button, ButtonState bs)
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("fader touch, press ? %1\n", (bs == press))); DEBUG_TRACE (DEBUG::MackieControl, string_compose ("fader touch, press ? %1\n", (bs == press)));
bool state = (bs == press); bool state = (bs == press);
_fader->set_in_use (state);
_fader->set_in_use (state);
_fader->start_touch (_surface->mcp().transport_frame(), modified);
if (!_surface->mcp().device_info().has_touch_sense_faders()) { if (!_surface->mcp().device_info().has_touch_sense_faders()) {
/* add a timeout to reset their `in_use' state. _surface->mcp().add_in_use_timeout (*_surface, *_fader, _fader->control (modified));
*/ }
_surface->mcp().add_in_use_timeout (*_surface, *_fader, _fader_touch);
return;
}
if (ms & MackieControlProtocol::MODIFIER_OPTION) {
/* reset to default/normal value */
boost::shared_ptr<AutomationControl> control = button.control (modified);
if (control) {
control->set_value (!control->get_value());
} }
} }
} }
@ -427,26 +409,13 @@ Strip::handle_fader (Fader& fader, float position)
{ {
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("fader to %1\n", position)); DEBUG_TRACE (DEBUG::MackieControl, string_compose ("fader to %1\n", position));
if (!_route) { bool modified = (_surface->mcp().modifier_state() & MackieControlProtocol::MODIFIER_CONTROL);
return;
}
switch (_surface->mcp().flip_mode()) { fader.set_value (position, modified);
case MackieControlProtocol::Normal: fader.start_touch (_surface->mcp().transport_frame(), modified);
_route->gain_control()->set_value (slider_position_to_gain (position));
break;
case MackieControlProtocol::Zero:
break;
case MackieControlProtocol::Mirror:
break;
case MackieControlProtocol::Swap:
_route->pannable()->pan_azimuth_control->set_value (position);
return;
}
if (!_surface->mcp().device_info().has_touch_sense_faders()) { if (!_surface->mcp().device_info().has_touch_sense_faders()) {
/* reset the timeout while we're still moving the fader */ _surface->mcp().add_in_use_timeout (*_surface, fader, fader.control (modified));
_surface->mcp().add_in_use_timeout (*_surface, fader, fader.in_use_touch_control);
} }
// must echo bytes back to slider now, because // must echo bytes back to slider now, because
@ -459,45 +428,19 @@ Strip::handle_fader (Fader& fader, float position)
void void
Strip::handle_pot (Pot& pot, float delta) Strip::handle_pot (Pot& pot, float delta)
{ {
if (!_route) { /* Pots only emit events when they move, not when they
_surface->write (pot.set_onoff (false)); stop moving. So to get a stop event, we need to use a timeout.
return; */
}
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));
boost::shared_ptr<Pannable> pannable = _route->pannable(); double p = pot.get_value (modified);
p += delta;
if (pannable) { p = min (1.0, p);
boost::shared_ptr<AutomationControl> ac; p = max (0.0, p);
pot.set_value (p, modified);
switch (_surface->mcp().flip_mode()) {
case MackieControlProtocol::Normal: /* pot controls pan */
case MackieControlProtocol::Mirror: /* pot + fader control pan */
case MackieControlProtocol::Zero: /* pot controls pan, faders don't move */
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("modifier state %1\n", _surface->mcp().modifier_state()));
if (_surface->mcp().modifier_state() & MackieControlProtocol::MODIFIER_CONTROL) {
DEBUG_TRACE (DEBUG::MackieControl, "pot using control to alter width\n");
ac = pannable->pan_width_control;
} else {
DEBUG_TRACE (DEBUG::MackieControl, "pot using control to alter position\n");
ac = pannable->pan_azimuth_control;
}
break;
case MackieControlProtocol::Swap: /* pot controls gain */
ac = _route->gain_control();
break;
}
if (ac) {
double p = ac->get_value();
// calculate new value, and adjust
p += delta;
p = min (1.0, p);
p = max (0.0, p);
ac->set_value (p);
}
}
} }
void void
@ -596,18 +539,15 @@ Strip::display (uint32_t line_number, const std::string& line)
} }
void void
Strip::lock_route () Strip::lock_controls ()
{ {
/* don't lock unless we have a route */ _controls_locked = true;
if (_route) {
_route_locked = true;
}
} }
void void
Strip::unlock_route () Strip::unlock_controls ()
{ {
_route_locked = false; _controls_locked = false;
} }
MidiByteArray MidiByteArray
@ -623,3 +563,40 @@ Strip::gui_selection_changed (ARDOUR::RouteNotificationListPtr rl)
std::cerr << "Strip " << _index << " NOT selected\n"; std::cerr << "Strip " << _index << " NOT selected\n";
return _select->set_state (off); return _select->set_state (off);
} }
void
Strip::flip_mode_changed (bool notify)
{
if (!_route) {
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, "Pan"));
} else {
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>());
_surface->write (display (1, "Fdr"));
}
if (notify) {
notify_all ();
}
}

View file

@ -69,30 +69,32 @@ public:
MidiByteArray blank_display (uint32_t line_number); MidiByteArray blank_display (uint32_t line_number);
MidiByteArray zero (); MidiByteArray zero ();
void lock_route (); void flip_mode_changed (bool notify=false);
void unlock_route ();
void lock_controls ();
void unlock_controls ();
MidiByteArray gui_selection_changed (ARDOUR::RouteNotificationListPtr); MidiByteArray gui_selection_changed (ARDOUR::RouteNotificationListPtr);
private: private:
Button* _solo; Button* _solo;
Button* _recenable; Button* _recenable;
Button* _mute; Button* _mute;
Button* _select; Button* _select;
Button* _vselect; Button* _vselect;
Button* _fader_touch; Button* _fader_touch;
Pot* _vpot; Pot* _vpot;
Fader* _fader; Fader* _fader;
Meter* _meter; Meter* _meter;
int _index; int _index;
Surface* _surface; Surface* _surface;
bool _route_locked; bool _controls_locked;
boost::shared_ptr<ARDOUR::Route> _route; boost::shared_ptr<ARDOUR::Route> _route;
PBD::ScopedConnectionList route_connections; PBD::ScopedConnectionList route_connections;
float _last_fader_position_written; float _last_gain_position_written;
float _last_vpot_position_written; float _last_pan_position_written;
void notify_solo_changed (); void notify_solo_changed ();
void notify_mute_changed (); void notify_mute_changed ();

View file

@ -412,12 +412,6 @@ Surface::handle_midi_controller_message (MIDI::Parser &, MIDI::EventTwoBytes* ev
ticks = 1; ticks = 1;
} }
float delta = sign * (ticks / (float) 0x3f); float delta = sign * (ticks / (float) 0x3f);
/* Pots only emit events when they move, not when they
stop moving. So to get a stop event, we need to use a timeout.
*/
_mcp.add_in_use_timeout (*this, *pot, pot);
Strip* strip = dynamic_cast<Strip*> (&pot->group()); Strip* strip = dynamic_cast<Strip*> (&pot->group());
@ -772,7 +766,7 @@ void
Surface::update_flip_mode_display () Surface::update_flip_mode_display ()
{ {
for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) { for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
(*s)->notify_all (); (*s)->flip_mode_changed (true);
} }
} }
@ -783,47 +777,38 @@ Surface::update_view_mode_display ()
Button* button = 0; Button* button = 0;
switch (_mcp.view_mode()) { switch (_mcp.view_mode()) {
case MackieControlProtocol::Global: case MackieControlProtocol::Mixer:
_port->write (two_char_display ("Gl")); _port->write (two_char_display ("Mx"));
button = buttons[Button::Pan]; button = buttons[Button::Pan];
text = _("Pan");
break; break;
case MackieControlProtocol::Dynamics: case MackieControlProtocol::Dynamics:
_port->write (two_char_display ("Dy")); _port->write (two_char_display ("Dy"));
button = buttons[Button::Dyn]; button = buttons[Button::Dyn];
text = _("");
break; break;
case MackieControlProtocol::EQ: case MackieControlProtocol::EQ:
_port->write (two_char_display ("EQ")); _port->write (two_char_display ("EQ"));
button = buttons[Button::Eq]; button = buttons[Button::Eq];
text = _("");
break; break;
case MackieControlProtocol::Loop: case MackieControlProtocol::Loop:
_port->write (two_char_display ("LP")); _port->write (two_char_display ("LP"));
button = buttons[Button::Loop]; button = buttons[Button::Loop];
text = _("");
break; break;
case MackieControlProtocol::AudioTracks: case MackieControlProtocol::AudioTracks:
_port->write (two_char_display ("AT")); _port->write (two_char_display ("AT"));
text = _("");
break; break;
case MackieControlProtocol::MidiTracks: case MackieControlProtocol::MidiTracks:
_port->write (two_char_display ("MT")); _port->write (two_char_display ("MT"));
text = _("");
break; break;
case MackieControlProtocol::Busses: case MackieControlProtocol::Busses:
_port->write (two_char_display ("Bs")); _port->write (two_char_display ("Bs"));
text = _("");
break; break;
case MackieControlProtocol::Sends: case MackieControlProtocol::Sends:
_port->write (two_char_display ("Sn")); _port->write (two_char_display ("Sn"));
button = buttons[Button::Sends]; button = buttons[Button::Sends];
text = _("");
break; break;
case MackieControlProtocol::Plugins: case MackieControlProtocol::Plugins:
_port->write (two_char_display ("Pl")); _port->write (two_char_display ("Pl"));
button = buttons[Button::Plugin]; button = buttons[Button::Plugin];
text = _("");
break; break;
} }
@ -831,8 +816,10 @@ Surface::update_view_mode_display ()
_port->write (button->set_state (on)); _port->write (button->set_state (on));
} }
for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) { if (!text.empty()) {
_port->write ((*s)->display (1, text)); for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
_port->write ((*s)->display (1, text));
}
} }
} }