mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-10 16:46:35 +01:00
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:
parent
b4235221ab
commit
939801a8d8
10 changed files with 279 additions and 243 deletions
|
|
@ -20,11 +20,12 @@
|
|||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "ardour/automation_control.h"
|
||||
|
||||
#include "controls.h"
|
||||
#include "types.h"
|
||||
#include "surface.h"
|
||||
#include "control_group.h"
|
||||
|
||||
#include "button.h"
|
||||
#include "led.h"
|
||||
#include "pot.h"
|
||||
|
|
@ -35,6 +36,7 @@
|
|||
|
||||
using namespace Mackie;
|
||||
using namespace std;
|
||||
using ARDOUR::AutomationControl;
|
||||
|
||||
void Group::add (Control& control)
|
||||
{
|
||||
|
|
@ -91,3 +93,57 @@ Jog::factory (Surface& surface, int id, const char* name, Group& group)
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,11 +25,17 @@
|
|||
#include <string>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <boost/smart_ptr.hpp>
|
||||
|
||||
#include "pbd/signals.h"
|
||||
|
||||
#include "mackie_control_exception.h"
|
||||
#include "midi_byte_array.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
class AutomationControl;
|
||||
}
|
||||
|
||||
namespace Mackie
|
||||
{
|
||||
|
||||
|
|
@ -60,7 +66,25 @@ public:
|
|||
*/
|
||||
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;
|
||||
std::string _name;
|
||||
Group& _group;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include "pbd/memento_command.h"
|
||||
#include "pbd/convert.h"
|
||||
|
||||
#include "ardour/automation_control.h"
|
||||
#include "ardour/dB.h"
|
||||
#include "ardour/debug.h"
|
||||
#include "ardour/location.h"
|
||||
|
|
@ -98,8 +99,8 @@ MackieControlProtocol::MackieControlProtocol (Session& session)
|
|||
, _gui (0)
|
||||
, _zoom_mode (false)
|
||||
, _scrub_mode (false)
|
||||
, _flip_mode (Normal)
|
||||
, _view_mode (Global)
|
||||
, _flip_mode (false)
|
||||
, _view_mode (Mixer)
|
||||
, _current_selected_track (-1)
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::MackieControlProtocol\n");
|
||||
|
|
@ -227,7 +228,7 @@ MackieControlProtocol::get_sorted_routes()
|
|||
}
|
||||
|
||||
switch (_view_mode) {
|
||||
case Global:
|
||||
case Mixer:
|
||||
break;
|
||||
case AudioTracks:
|
||||
break;
|
||||
|
|
@ -914,19 +915,18 @@ MackieControlProtocol::stop ()
|
|||
* @param touch_control a touch control to emit an event for, or 0.
|
||||
*/
|
||||
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
|
||||
|
||||
in_use_control.in_use_connection.disconnect ();
|
||||
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));
|
||||
in_use_control.in_use_touch_control = touch_control;
|
||||
sigc::bind (sigc::mem_fun (*this, &MackieControlProtocol::control_in_use_timeout), &surface, &in_use_control, touched));
|
||||
|
||||
timeout->attach (main_loop()->get_context());
|
||||
|
||||
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("timeout queued for surface %1, control %2 touch control %3\n",
|
||||
surface.number(), &in_use_control, touch_control));}
|
||||
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("timeout queued for surface %1, control %2\n",
|
||||
surface.number(), &in_use_control));}
|
||||
|
||||
/** Handle timeouts to reset in_use for controls that can't
|
||||
* 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.
|
||||
*/
|
||||
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",
|
||||
surface->number(), in_use_control, touch_control));
|
||||
boost::shared_ptr<AutomationControl> touched (wtouched.lock());
|
||||
|
||||
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);
|
||||
|
||||
if (touch_control) {
|
||||
/* figure out what to do here */
|
||||
if (touched) {
|
||||
/* end the touch, and mark the end */
|
||||
touched->stop_touch (session->transport_frame(), true);
|
||||
}
|
||||
|
||||
// only call this method once from the timer
|
||||
|
|
@ -1140,9 +1142,9 @@ MackieControlProtocol::set_view_mode (ViewMode m)
|
|||
}
|
||||
|
||||
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) {
|
||||
(*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);
|
||||
if (strip) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
framepos_t
|
||||
MackieControlProtocol::transport_frame() const
|
||||
{
|
||||
return session->transport_frame();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@
|
|||
#include "timer.h"
|
||||
#include "device_info.h"
|
||||
|
||||
class RouteTimeAxisView;
|
||||
namespace ARDOUR {
|
||||
class AutomationControl;
|
||||
}
|
||||
|
||||
namespace MIDI {
|
||||
class Port;
|
||||
|
|
@ -92,7 +94,7 @@ class MackieControlProtocol
|
|||
static const int MODIFIER_CMDALT;
|
||||
|
||||
enum ViewMode {
|
||||
Global,
|
||||
Mixer,
|
||||
Dynamics,
|
||||
EQ,
|
||||
Loop,
|
||||
|
|
@ -120,11 +122,11 @@ class MackieControlProtocol
|
|||
int set_active (bool yn);
|
||||
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; }
|
||||
|
||||
void set_view_mode (ViewMode);
|
||||
void set_flip_mode (FlipMode);
|
||||
void set_flip_mode (bool);
|
||||
|
||||
XMLNode& get_state ();
|
||||
int set_state (const XMLNode&, int version);
|
||||
|
|
@ -175,8 +177,9 @@ class MackieControlProtocol
|
|||
void update_global_led(const std::string & name, Mackie::LedState);
|
||||
|
||||
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; }
|
||||
|
||||
|
|
@ -262,7 +265,7 @@ class MackieControlProtocol
|
|||
void* _gui;
|
||||
bool _zoom_mode;
|
||||
bool _scrub_mode;
|
||||
FlipMode _flip_mode;
|
||||
bool _flip_mode;
|
||||
ViewMode _view_mode;
|
||||
int _current_selected_track;
|
||||
int _modifier_state;
|
||||
|
|
@ -272,7 +275,7 @@ class MackieControlProtocol
|
|||
|
||||
void create_surfaces ();
|
||||
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();
|
||||
void build_gui ();
|
||||
bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
|
||||
|
|
|
|||
|
|
@ -820,21 +820,8 @@ MackieControlProtocol::dyn_release (Button &)
|
|||
LedState
|
||||
MackieControlProtocol::flip_press (Button &)
|
||||
{
|
||||
FlipMode m;
|
||||
|
||||
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);
|
||||
set_flip_mode (!_flip_mode);
|
||||
return (_flip_mode ? on : off);
|
||||
}
|
||||
LedState
|
||||
MackieControlProtocol::flip_release (Button &)
|
||||
|
|
|
|||
|
|
@ -48,17 +48,10 @@ Pot::set_onoff (bool onoff)
|
|||
return update_message ();
|
||||
}
|
||||
|
||||
MidiByteArray
|
||||
Pot::set_value (float normalized)
|
||||
{
|
||||
value = normalized;
|
||||
return update_message ();
|
||||
}
|
||||
|
||||
MidiByteArray
|
||||
Pot::set_all (float val, bool onoff, Mode m)
|
||||
{
|
||||
value = val;
|
||||
position = val;
|
||||
on = onoff;
|
||||
mode = m;
|
||||
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.
|
||||
|
||||
// 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
|
||||
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) {
|
||||
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
|
||||
|
|
|
|||
|
|
@ -40,23 +40,22 @@ public:
|
|||
|
||||
Pot (int id, std::string name, Group & group)
|
||||
: Control (id, name, group)
|
||||
, value (0.0)
|
||||
, position (0.0)
|
||||
, mode (dot)
|
||||
, on (true) {}
|
||||
|
||||
MidiByteArray set_mode (Mode);
|
||||
MidiByteArray set_value (float);
|
||||
MidiByteArray set_onoff (bool);
|
||||
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 ();
|
||||
|
||||
static Control* factory (Surface&, int id, const char*, Group&);
|
||||
|
||||
private:
|
||||
float value;
|
||||
float position;
|
||||
Mode mode;
|
||||
bool on;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -69,9 +69,9 @@ Strip::Strip (Surface& s, const std::string& name, int index, StripControlDefini
|
|||
, _fader (0)
|
||||
, _index (index)
|
||||
, _surface (&s)
|
||||
, _route_locked (false)
|
||||
, _last_fader_position_written (-1.0)
|
||||
, _last_vpot_position_written (-1.0)
|
||||
, _controls_locked (false)
|
||||
, _last_gain_position_written (-1.0)
|
||||
, _last_pan_position_written (-1.0)
|
||||
{
|
||||
/* build the controls for this track, which will automatically add them
|
||||
to the Group
|
||||
|
|
@ -84,7 +84,6 @@ Strip::Strip (Surface& s, const std::string& name, int index, StripControlDefini
|
|||
|
||||
Strip::~Strip ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -149,7 +148,7 @@ void Strip::add (Control & control)
|
|||
void
|
||||
Strip::set_route (boost::shared_ptr<Route> r)
|
||||
{
|
||||
if (_route_locked) {
|
||||
if (_controls_locked) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -164,10 +163,12 @@ Strip::set_route (boost::shared_ptr<Route> r)
|
|||
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
@ -180,9 +181,13 @@ Strip::set_route (boost::shared_ptr<Route> r)
|
|||
_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);
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
@ -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()));
|
||||
|
||||
if (_route && _fader) {
|
||||
if (_route) {
|
||||
|
||||
if (!_fader->in_use()) {
|
||||
Control* control;
|
||||
|
||||
double pos;
|
||||
|
||||
switch (_surface->mcp().flip_mode()) {
|
||||
case MackieControlProtocol::Normal:
|
||||
pos = _route->gain_control()->get_value();
|
||||
break;
|
||||
|
||||
case MackieControlProtocol::Swap:
|
||||
case MackieControlProtocol::Zero:
|
||||
case MackieControlProtocol::Mirror:
|
||||
/* fader is used for something else and/or
|
||||
should not move.
|
||||
*/
|
||||
return;
|
||||
if (_surface->mcp().flip_mode()) {
|
||||
control = _vpot;
|
||||
} else {
|
||||
control = _fader;
|
||||
}
|
||||
|
||||
pos = gain_to_slider_position (pos);
|
||||
if (!control->in_use()) {
|
||||
|
||||
if (force_update || pos != _last_fader_position_written) {
|
||||
float pos = _route->gain_control()->internal_to_interface (_route->gain_control()->get_value());
|
||||
|
||||
if (force_update || pos != _last_gain_position_written) {
|
||||
|
||||
if (_surface->mcp().flip_mode()) {
|
||||
_surface->write (_vpot->set_all (pos, true, Pot::boost_cut));
|
||||
} else {
|
||||
_surface->write (_fader->set_position (pos));
|
||||
_last_fader_position_written = pos;
|
||||
}
|
||||
_last_gain_position_written = pos;
|
||||
|
||||
} else {
|
||||
DEBUG_TRACE (DEBUG::MackieControl, "value is stale, no message sent\n");
|
||||
}
|
||||
|
|
@ -321,7 +324,7 @@ Strip::notify_property_changed (const PropertyChange& what_changed)
|
|||
void
|
||||
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));
|
||||
|
||||
|
|
@ -332,25 +335,26 @@ Strip::notify_panner_changed (bool force_update)
|
|||
return;
|
||||
}
|
||||
|
||||
double pos;
|
||||
Control* control;
|
||||
|
||||
switch (_surface->mcp().flip_mode()) {
|
||||
case MackieControlProtocol::Swap:
|
||||
/* pot is controlling the gain */
|
||||
return;
|
||||
|
||||
case MackieControlProtocol::Normal:
|
||||
case MackieControlProtocol::Zero:
|
||||
case MackieControlProtocol::Mirror:
|
||||
pos = pannable->pan_azimuth_control->get_value();
|
||||
break;
|
||||
if (_surface->mcp().flip_mode()) {
|
||||
control = _fader;
|
||||
} else {
|
||||
control = _vpot;
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
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_vpot_position_written = pos;
|
||||
}
|
||||
_last_pan_position_written = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -360,48 +364,15 @@ Strip::handle_button (Button& button, ButtonState bs)
|
|||
{
|
||||
button.set_in_use (bs == press);
|
||||
|
||||
if (!_route) {
|
||||
// no route so always switch the light off
|
||||
// because no signals will be emitted by a non-route
|
||||
_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);
|
||||
int ms = _surface->mcp().modifier_state();
|
||||
bool modified = (ms & MackieControlProtocol::MODIFIER_CONTROL);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -413,11 +384,22 @@ Strip::handle_button (Button& button, ButtonState bs)
|
|||
bool state = (bs == press);
|
||||
|
||||
_fader->set_in_use (state);
|
||||
_fader->start_touch (_surface->mcp().transport_frame(), modified);
|
||||
|
||||
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_touch);
|
||||
_surface->mcp().add_in_use_timeout (*_surface, *_fader, _fader->control (modified));
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
if (!_route) {
|
||||
return;
|
||||
}
|
||||
bool modified = (_surface->mcp().modifier_state() & MackieControlProtocol::MODIFIER_CONTROL);
|
||||
|
||||
switch (_surface->mcp().flip_mode()) {
|
||||
case MackieControlProtocol::Normal:
|
||||
_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;
|
||||
}
|
||||
fader.set_value (position, modified);
|
||||
fader.start_touch (_surface->mcp().transport_frame(), modified);
|
||||
|
||||
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.in_use_touch_control);
|
||||
_surface->mcp().add_in_use_timeout (*_surface, fader, fader.control (modified));
|
||||
}
|
||||
|
||||
// must echo bytes back to slider now, because
|
||||
|
|
@ -459,45 +428,19 @@ Strip::handle_fader (Fader& fader, float position)
|
|||
void
|
||||
Strip::handle_pot (Pot& pot, float delta)
|
||||
{
|
||||
if (!_route) {
|
||||
_surface->write (pot.set_onoff (false));
|
||||
return;
|
||||
}
|
||||
/* Pots only emit events when they move, not when they
|
||||
stop moving. So to get a stop event, we need to use a timeout.
|
||||
*/
|
||||
|
||||
boost::shared_ptr<Pannable> pannable = _route->pannable();
|
||||
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));
|
||||
|
||||
if (pannable) {
|
||||
boost::shared_ptr<AutomationControl> ac;
|
||||
|
||||
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
|
||||
double p = pot.get_value (modified);
|
||||
p += delta;
|
||||
p = min (1.0, p);
|
||||
p = max (0.0, p);
|
||||
|
||||
ac->set_value (p);
|
||||
}
|
||||
}
|
||||
pot.set_value (p, modified);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -596,18 +539,15 @@ Strip::display (uint32_t line_number, const std::string& line)
|
|||
}
|
||||
|
||||
void
|
||||
Strip::lock_route ()
|
||||
Strip::lock_controls ()
|
||||
{
|
||||
/* don't lock unless we have a route */
|
||||
if (_route) {
|
||||
_route_locked = true;
|
||||
}
|
||||
_controls_locked = true;
|
||||
}
|
||||
|
||||
void
|
||||
Strip::unlock_route ()
|
||||
Strip::unlock_controls ()
|
||||
{
|
||||
_route_locked = false;
|
||||
_controls_locked = false;
|
||||
}
|
||||
|
||||
MidiByteArray
|
||||
|
|
@ -623,3 +563,40 @@ Strip::gui_selection_changed (ARDOUR::RouteNotificationListPtr rl)
|
|||
std::cerr << "Strip " << _index << " NOT selected\n";
|
||||
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 ();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,8 +69,10 @@ public:
|
|||
MidiByteArray blank_display (uint32_t line_number);
|
||||
MidiByteArray zero ();
|
||||
|
||||
void lock_route ();
|
||||
void unlock_route ();
|
||||
void flip_mode_changed (bool notify=false);
|
||||
|
||||
void lock_controls ();
|
||||
void unlock_controls ();
|
||||
|
||||
MidiByteArray gui_selection_changed (ARDOUR::RouteNotificationListPtr);
|
||||
|
||||
|
|
@ -86,13 +88,13 @@ private:
|
|||
Meter* _meter;
|
||||
int _index;
|
||||
Surface* _surface;
|
||||
bool _route_locked;
|
||||
bool _controls_locked;
|
||||
|
||||
boost::shared_ptr<ARDOUR::Route> _route;
|
||||
PBD::ScopedConnectionList route_connections;
|
||||
|
||||
float _last_fader_position_written;
|
||||
float _last_vpot_position_written;
|
||||
float _last_gain_position_written;
|
||||
float _last_pan_position_written;
|
||||
|
||||
void notify_solo_changed ();
|
||||
void notify_mute_changed ();
|
||||
|
|
|
|||
|
|
@ -413,12 +413,6 @@ Surface::handle_midi_controller_message (MIDI::Parser &, MIDI::EventTwoBytes* ev
|
|||
}
|
||||
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());
|
||||
|
||||
if (strip) {
|
||||
|
|
@ -772,7 +766,7 @@ void
|
|||
Surface::update_flip_mode_display ()
|
||||
{
|
||||
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;
|
||||
|
||||
switch (_mcp.view_mode()) {
|
||||
case MackieControlProtocol::Global:
|
||||
_port->write (two_char_display ("Gl"));
|
||||
case MackieControlProtocol::Mixer:
|
||||
_port->write (two_char_display ("Mx"));
|
||||
button = buttons[Button::Pan];
|
||||
text = _("Pan");
|
||||
break;
|
||||
case MackieControlProtocol::Dynamics:
|
||||
_port->write (two_char_display ("Dy"));
|
||||
button = buttons[Button::Dyn];
|
||||
text = _("");
|
||||
break;
|
||||
case MackieControlProtocol::EQ:
|
||||
_port->write (two_char_display ("EQ"));
|
||||
button = buttons[Button::Eq];
|
||||
text = _("");
|
||||
break;
|
||||
case MackieControlProtocol::Loop:
|
||||
_port->write (two_char_display ("LP"));
|
||||
button = buttons[Button::Loop];
|
||||
text = _("");
|
||||
break;
|
||||
case MackieControlProtocol::AudioTracks:
|
||||
_port->write (two_char_display ("AT"));
|
||||
text = _("");
|
||||
break;
|
||||
case MackieControlProtocol::MidiTracks:
|
||||
_port->write (two_char_display ("MT"));
|
||||
text = _("");
|
||||
break;
|
||||
case MackieControlProtocol::Busses:
|
||||
_port->write (two_char_display ("Bs"));
|
||||
text = _("");
|
||||
break;
|
||||
case MackieControlProtocol::Sends:
|
||||
_port->write (two_char_display ("Sn"));
|
||||
button = buttons[Button::Sends];
|
||||
text = _("");
|
||||
break;
|
||||
case MackieControlProtocol::Plugins:
|
||||
_port->write (two_char_display ("Pl"));
|
||||
button = buttons[Button::Plugin];
|
||||
text = _("");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -831,9 +816,11 @@ Surface::update_view_mode_display ()
|
|||
_port->write (button->set_state (on));
|
||||
}
|
||||
|
||||
if (!text.empty()) {
|
||||
for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
|
||||
_port->write ((*s)->display (1, text));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue