summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2012-04-22 17:37:52 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2012-04-22 17:37:52 +0000
commitac1b2a664711ce6e66c1bd37565c8066103a722a (patch)
treee8335287eeb2f4abcc860255a2dcf937a297f0c2 /libs
parent4901f9d1d20ea5878b34db025a3dc305d3a78c2e (diff)
MCP: another bevy of changes, including working jog wheel
git-svn-id: svn://localhost/ardour2/branches/3.0@12056 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/surfaces/mackie/jog_wheel.cc50
-rw-r--r--libs/surfaces/mackie/jog_wheel.h34
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc5
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.h3
-rw-r--r--libs/surfaces/mackie/mackie_jog_wheel.cc198
-rw-r--r--libs/surfaces/mackie/mackie_jog_wheel.h102
-rw-r--r--libs/surfaces/mackie/mcp_buttons.cc8
-rw-r--r--libs/surfaces/mackie/pot.cc2
-rw-r--r--libs/surfaces/mackie/strip.cc288
-rw-r--r--libs/surfaces/mackie/strip.h36
-rw-r--r--libs/surfaces/mackie/surface.cc149
-rw-r--r--libs/surfaces/mackie/surface.h10
-rw-r--r--libs/surfaces/mackie/wscript2
13 files changed, 317 insertions, 570 deletions
diff --git a/libs/surfaces/mackie/jog_wheel.cc b/libs/surfaces/mackie/jog_wheel.cc
new file mode 100644
index 0000000000..6d8980d78e
--- /dev/null
+++ b/libs/surfaces/mackie/jog_wheel.cc
@@ -0,0 +1,50 @@
+#include <cmath>
+
+#include "ardour/session.h"
+
+#include "jog_wheel.h"
+#include "mackie_control_protocol.h"
+#include "surface_port.h"
+#include "controls.h"
+#include "surface.h"
+
+#include <algorithm>
+
+using namespace Mackie;
+
+JogWheel::JogWheel (MackieControlProtocol & mcp)
+ : _mcp (mcp)
+ , _mode (scroll)
+{
+}
+
+void
+JogWheel::set_mode (Mode m)
+{
+ _mode = m;
+}
+
+void JogWheel::jog_event (float delta)
+{
+ if (_mcp.zoom_mode()) {
+ if (delta > 0) {
+ for (unsigned int i = 0; i < fabs (delta); ++i) {
+ _mcp.ZoomIn();
+ }
+ } else {
+ for (unsigned int i = 0; i < fabs (delta); ++i) {
+ _mcp.ZoomOut();
+ }
+ }
+ return;
+ }
+
+ switch (_mode) {
+ case scroll:
+ _mcp.ScrollTimeline (delta/4.0);
+ break;
+ default:
+ break;
+ }
+}
+
diff --git a/libs/surfaces/mackie/jog_wheel.h b/libs/surfaces/mackie/jog_wheel.h
new file mode 100644
index 0000000000..0750775bdd
--- /dev/null
+++ b/libs/surfaces/mackie/jog_wheel.h
@@ -0,0 +1,34 @@
+#ifndef mackie_jog_wheel
+#define mackie_jog_wheel
+
+#include "timer.h"
+
+#include <stack>
+#include <deque>
+#include <queue>
+
+class MackieControlProtocol;
+
+namespace Mackie
+{
+
+class JogWheel
+{
+ public:
+ enum Mode { scroll };
+
+ JogWheel (MackieControlProtocol & mcp);
+
+ /// As the wheel turns...
+ void jog_event (float delta);
+ void set_mode (Mode m);
+ Mode mode() const { return _mode; }
+
+private:
+ MackieControlProtocol & _mcp;
+ Mode _mode;
+};
+
+}
+
+#endif
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index c74acd06f0..db00546eef 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -1023,7 +1023,8 @@ MackieControlProtocol::handle_button_event (Surface& surface, Button& button, Bu
return;
}
- DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Handling %1 for button %2\n", (bs == press ? "press" : "release"), button.id()));
+ DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Handling %1 for button %2 (%3)\n", (bs == press ? "press" : "release"), button.id(),
+ Button::id_to_name (button.bid())));
/* check profile first */
@@ -1160,6 +1161,8 @@ MackieControlProtocol::force_special_route_to_strip (boost::shared_ptr<Route> r,
void
MackieControlProtocol::gui_track_selection_changed (ARDOUR::RouteNotificationListPtr rl)
{
+ cerr << "GUI Selection changed, " << rl->size() << " routes\n";
+
for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
(*s)->gui_selection_changed (rl);
}
diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h
index 2b29cde63a..ad01c2d1de 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.h
+++ b/libs/surfaces/mackie/mackie_control_protocol.h
@@ -38,7 +38,7 @@
#include "types.h"
#include "midi_byte_array.h"
#include "controls.h"
-#include "mackie_jog_wheel.h"
+#include "jog_wheel.h"
#include "timer.h"
#include "device_info.h"
#include "device_profile.h"
@@ -127,6 +127,7 @@ class MackieControlProtocol
bool flip_mode () const { return _flip_mode; }
ViewMode view_mode () const { return _view_mode; }
+ bool zoom_mode () const { return _zoom_mode; }
void set_view_mode (ViewMode);
void set_flip_mode (bool);
diff --git a/libs/surfaces/mackie/mackie_jog_wheel.cc b/libs/surfaces/mackie/mackie_jog_wheel.cc
deleted file mode 100644
index 86ea84ff65..0000000000
--- a/libs/surfaces/mackie/mackie_jog_wheel.cc
+++ /dev/null
@@ -1,198 +0,0 @@
-#include <cmath>
-
-#include "ardour/session.h"
-
-#include "mackie_jog_wheel.h"
-#include "mackie_control_protocol.h"
-#include "surface_port.h"
-#include "controls.h"
-#include "surface.h"
-
-#include <algorithm>
-
-using namespace Mackie;
-
-JogWheel::JogWheel (MackieControlProtocol & mcp)
-: _mcp (mcp)
-, _transport_speed (4.0)
-, _transport_direction (0)
-, _shuttle_speed (0.0)
-{
-}
-
-JogWheel::State JogWheel::jog_wheel_state() const
-{
- if (!_jog_wheel_states.empty())
- return _jog_wheel_states.top();
- else
- return scroll;
-}
-
-void JogWheel::zoom_event (SurfacePort &, Control &, const ControlState &)
-{
-}
-
-void JogWheel::scrub_event (SurfacePort &, Control &, const ControlState &)
-{
-}
-
-void JogWheel::speed_event (SurfacePort &, Control &, const ControlState &)
-{
-}
-
-void JogWheel::scroll_event (SurfacePort &, Control &, const ControlState &)
-{
-}
-
-void JogWheel::jog_event (SurfacePort &, Control &, float delta)
-{
- // TODO use current snap-to setting?
- switch (jog_wheel_state())
- {
- case scroll:
- _mcp.ScrollTimeline (delta);
- break;
-
- case zoom:
- // Chunky Zoom.
- // TODO implement something similar to ScrollTimeline which
- // ends up in Editor::control_scroll for smoother zooming.
- if (delta > 0) {
- for (unsigned int i = 0; i < fabs (delta); ++i) {
- _mcp.ZoomIn();
- }
- } else {
- for (unsigned int i = 0; i < fabs (delta); ++i) {
- _mcp.ZoomOut();
- }
- }
- break;
-
- case speed:
- // locally, _transport_speed is an positive value
- _transport_speed += _mcp.surfaces.front()->scaled_delta (delta, _mcp.get_session().transport_speed());
-
- // make sure no weirdness gets to the session
- if (_transport_speed < 0 || isnan (_transport_speed))
- {
- _transport_speed = 0.0;
- }
-
- // translate _transport_speed speed to a signed transport velocity
- _mcp.get_session().request_transport_speed_nonzero (transport_speed() * transport_direction());
- break;
-
- case scrub:
- {
- if (delta != 0) {
- add_scrub_interval (_scrub_timer.restart());
- // x clicks per second => speed == 1.0
- float speed = _mcp.surfaces.front()->scrub_scaling_factor() / average_scrub_interval() * delta;
- _mcp.get_session().request_transport_speed_nonzero (speed);
- }
- else
- {
- // we have a stop event
- check_scrubbing();
- }
- break;
- }
-
- case shuttle:
- _shuttle_speed = _mcp.get_session().transport_speed();
- _shuttle_speed += _mcp.surfaces.front()->scaled_delta (delta, _mcp.get_session().transport_speed());
- _mcp.get_session().request_transport_speed_nonzero (_shuttle_speed);
- break;
-
- case select:
- std::cout << "JogWheel select not implemented" << std::endl;
- break;
- }
-}
-
-void JogWheel::check_scrubbing()
-{
- // if the last elapsed is greater than the average + std deviation, then stop
- if (!_scrub_intervals.empty() && _scrub_timer.elapsed() > average_scrub_interval() + std_dev_scrub_interval())
- {
- _mcp.get_session().request_transport_speed (0.0);
- _scrub_intervals.clear();
- }
-}
-
-void JogWheel::push (State state)
-{
- _jog_wheel_states.push (state);
-}
-
-void JogWheel::pop()
-{
- if (_jog_wheel_states.size() > 0)
- {
- _jog_wheel_states.pop();
- }
-}
-
-void JogWheel::zoom_state_toggle()
-{
- if (jog_wheel_state() == zoom)
- pop();
- else
- push (zoom);
-}
-
-JogWheel::State JogWheel::scrub_state_cycle()
-{
- State top = jog_wheel_state();
- if (top == scrub)
- {
- // stop scrubbing and go to shuttle
- pop();
- push (shuttle);
- _shuttle_speed = 0.0;
- }
- else if (top == shuttle)
- {
- // default to scroll, or the last selected
- pop();
- }
- else
- {
- // start with scrub
- push (scrub);
- }
-
- return jog_wheel_state();
-}
-
-void JogWheel::add_scrub_interval (unsigned long elapsed)
-{
- if (_scrub_intervals.size() > 5)
- {
- _scrub_intervals.pop_front();
- }
- _scrub_intervals.push_back (elapsed);
-}
-
-float JogWheel::average_scrub_interval()
-{
- float sum = 0.0;
- for (std::deque<unsigned long>::iterator it = _scrub_intervals.begin(); it != _scrub_intervals.end(); ++it)
- {
- sum += *it;
- }
- return sum / _scrub_intervals.size();
-}
-
-float JogWheel::std_dev_scrub_interval()
-{
- float average = average_scrub_interval();
-
- // calculate standard deviation
- float sum = 0.0;
- for (std::deque<unsigned long>::iterator it = _scrub_intervals.begin(); it != _scrub_intervals.end(); ++it)
- {
- sum += pow (*it - average, 2);
- }
- return sqrt (sum / _scrub_intervals.size() -1);
-}
diff --git a/libs/surfaces/mackie/mackie_jog_wheel.h b/libs/surfaces/mackie/mackie_jog_wheel.h
deleted file mode 100644
index 7a3e016cff..0000000000
--- a/libs/surfaces/mackie/mackie_jog_wheel.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#ifndef mackie_jog_wheel
-#define mackie_jog_wheel
-
-#include "timer.h"
-
-#include <stack>
-#include <deque>
-#include <queue>
-
-class MackieControlProtocol;
-
-namespace Mackie
-{
-
-class SurfacePort;
-class Control;
-class ControlState;
-
-/**
- A jog wheel can be used to control many things. This
- handles all of the states and state transitions.
-
- Mainly it exists to avoid putting a bunch of messy
- stuff in MackieControlProtocol.
-
- But it doesn't really know who it is, with stacks, queues and various
- boolean state variables.
-*/
-class JogWheel
-{
-public:
- enum State { scroll, zoom, speed, scrub, shuttle, select };
-
- JogWheel (MackieControlProtocol & mcp);
-
- /// As the wheel turns...
- void jog_event (SurfacePort & port, Control & control, float delta);
-
- // These are for incoming button presses that change the internal state
- // but they're not actually used at the moment.
- void zoom_event (SurfacePort & port, Control & control, const ControlState & state);
- void scrub_event (SurfacePort & port, Control & control, const ControlState & state);
- void speed_event (SurfacePort & port, Control & control, const ControlState & state);
- void scroll_event (SurfacePort & port, Control & control, const ControlState & state);
-
- /// Return the current jog wheel mode, which defaults to Scroll
- State jog_wheel_state() const;
-
- /// The current transport speed for ffwd and rew. Can be
- /// set by wheel when they're pressed.
- float transport_speed() const { return _transport_speed; }
-
- /// one of -1,0,1
- int transport_direction() const { return _transport_direction; }
- void transport_direction (int rhs) { _transport_direction = rhs; }
-
- void push (State state);
- void pop();
-
- /// Turn zoom mode on and off
- void zoom_state_toggle();
-
- /**
- Cycle scrub -> shuttle -> previous
- */
- State scrub_state_cycle();
-
- /// Check to see when the last scrub event was
- /// And stop scrubbing if it was too long ago.
- /// Intended to be called from a periodic timer of
- /// some kind.
- void check_scrubbing();
-
-protected:
- void add_scrub_interval (unsigned long elapsed);
- float average_scrub_interval();
- float std_dev_scrub_interval();
-
-private:
- MackieControlProtocol & _mcp;
-
- /// transport speed for ffwd and rew, controller by jog
- float _transport_speed;
- int _transport_direction;
-
- /// Speed for shuttle
- float _shuttle_speed;
-
- /// a stack for keeping track of states
- std::stack<State> _jog_wheel_states;
-
- /// So we know how fast to set the transport speed while scrubbing
- Timer _scrub_timer;
-
- /// to keep track of what the current scrub rate is
- /// so we can calculate a moving average
- std::deque<unsigned long> _scrub_intervals;
-};
-
-}
-
-#endif
diff --git a/libs/surfaces/mackie/mcp_buttons.cc b/libs/surfaces/mackie/mcp_buttons.cc
index 616cdc1e76..576267d09d 100644
--- a/libs/surfaces/mackie/mcp_buttons.cc
+++ b/libs/surfaces/mackie/mcp_buttons.cc
@@ -317,14 +317,16 @@ MackieControlProtocol::zoom_release (Mackie::Button &)
Mackie::LedState
MackieControlProtocol::scrub_press (Mackie::Button &)
{
- _scrub_mode = !_scrub_mode;
- return (_scrub_mode ? on : off);
+ if (!surfaces.empty()) {
+ surfaces.front()->next_jog_mode ();
+ }
+ return none;
}
Mackie::LedState
MackieControlProtocol::scrub_release (Mackie::Button &)
{
- return (_scrub_mode ? on : off);
+ return none;
}
LedState
diff --git a/libs/surfaces/mackie/pot.cc b/libs/surfaces/mackie/pot.cc
index ceec0ea940..78973b40df 100644
--- a/libs/surfaces/mackie/pot.cc
+++ b/libs/surfaces/mackie/pot.cc
@@ -46,7 +46,7 @@ Pot::set (float val, bool onoff, Mode mode)
MIDI::byte msg = (val > 0.45 && val < 0.55 ? 1 : 0) << 6;
// mode
- msg |= (onoff << 4);
+ msg |= (mode << 4);
// val, but only if off hasn't explicitly been set
diff --git a/libs/surfaces/mackie/strip.cc b/libs/surfaces/mackie/strip.cc
index bf3ff0d588..ccb9137185 100644
--- a/libs/surfaces/mackie/strip.cc
+++ b/libs/surfaces/mackie/strip.cc
@@ -73,15 +73,14 @@ 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)
, _controls_locked (false)
, _reset_display_at (0)
, _last_gain_position_written (-1.0)
- , _last_pan_position_written (-1.0)
+ , _last_pan_azi_position_written (-1.0)
+ , _last_pan_width_position_written (-1.0)
{
_fader = dynamic_cast<Fader*> (Fader::factory (*_surface, index, "fader", *this));
_vpot = dynamic_cast<Pot*> (Pot::factory (*_surface, Pot::ID + index, "vpot", *this));
@@ -154,6 +153,9 @@ Strip::set_route (boost::shared_ptr<Route> r, bool with_messages)
_route = r;
+ control_by_parameter.clear ();
+ reset_saved_values ();
+
if (!r) {
return;
}
@@ -163,7 +165,8 @@ Strip::set_route (boost::shared_ptr<Route> r, bool with_messages)
_solo->set_control (_route->solo_control());
_mute->set_control (_route->mute_control());
- set_vpot_mode (PanAzimuth);
+
+ set_vpot_parameter (PanAzimuthAutomation);
_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());
@@ -182,6 +185,8 @@ Strip::set_route (boost::shared_ptr<Route> r, bool with_messages)
if (trk) {
_recenable->set_control (trk->rec_enable_control());
trk->rec_enable_control()->Changed .connect(route_connections, invalidator(), ui_bind (&Strip::notify_record_enable_changed, this), ui_context());
+
+
}
// TODO this works when a currently-banked route is made inactive, but not
@@ -208,11 +213,11 @@ Strip::set_route (boost::shared_ptr<Route> r, bool with_messages)
set<Evoral::Parameter>::iterator a;
if ((a = automatable.find (PanAzimuthAutomation)) != automatable.end()) {
- current_pot_modes.push_back (PanAzimuth);
+ current_pot_modes.push_back (PanAzimuthAutomation);
}
if ((a = automatable.find (PanWidthAutomation)) != automatable.end()) {
- current_pot_modes.push_back (PanWidth);
+ current_pot_modes.push_back (PanWidthAutomation);
}
}
}
@@ -349,35 +354,27 @@ Strip::notify_panner_azi_changed (bool force_update)
return;
}
- Control* control;
+ Control* control = control_by_parameter[PanAzimuthAutomation];
- if (_surface->mcp().flip_mode()) {
- control = _fader;
- } else {
- if (_vpot_mode != PanAzimuth) {
- return;
- }
- control = _vpot;
+ if (!control) {
+ return;
}
- if (!control->in_use()) {
-
- 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()) {
-
+ double pos = pannable->pan_azimuth_control->internal_to_interface (pannable->pan_azimuth_control->get_value());
+
+ if (force_update || pos != _last_pan_azi_position_written) {
+
+ if (control == _fader) {
+ if (!_fader->in_use()) {
_surface->write (_fader->set_position (pos));
- do_parameter_display (PanAzimuthAutomation, pos);
- } else {
- _surface->write (_vpot->set (pos, true, Pot::dot));
- do_parameter_display (PanAzimuthAutomation, pos);
}
-
- queue_display_reset (2000);
- _last_pan_position_written = pos;
+ } else if (control == _vpot) {
+ _surface->write (_vpot->set (pos, true, Pot::dot));
}
+
+ do_parameter_display (PanAzimuthAutomation, pos);
+ queue_display_reset (2000);
+ _last_pan_azi_position_written = pos;
}
}
}
@@ -396,35 +393,32 @@ Strip::notify_panner_width_changed (bool force_update)
return;
}
- Control* control;
- if (_surface->mcp().flip_mode()) {
- control = _fader;
- } else {
- if (_vpot_mode != PanWidth) {
- return;
- }
- control = _vpot;
- }
+ Control* control = control_by_parameter[PanWidthAutomation];
- if (!control->in_use()) {
+ if (!control) {
+ return;
+ }
- double pos = pannable->pan_width_control->internal_to_interface (pannable->pan_width_control->get_value());
+ double pos = pannable->pan_width_control->internal_to_interface (pannable->pan_width_control->get_value());
+
+ if (force_update || pos != _last_pan_azi_position_written) {
- if (force_update || pos != _last_pan_position_written) {
-
- if (_surface->mcp().flip_mode()) {
-
- _surface->write (_fader->set_position (pos));
- do_parameter_display (PanWidthAutomation, pos);
- } else {
- _surface->write (_vpot->set (pos, true, Pot::spread));
- do_parameter_display (PanWidthAutomation, pos);
+ if (_surface->mcp().flip_mode()) {
+
+ if (control == _fader) {
+ if (!control->in_use()) {
+ _surface->write (_fader->set_position (pos));
+ }
}
- queue_display_reset (2000);
- _last_pan_position_written = pos;
+ } else if (control == _vpot) {
+ _surface->write (_vpot->set (pos, true, Pot::spread));
}
+
+ do_parameter_display (PanWidthAutomation, pos);
+ queue_display_reset (2000);
+ _last_pan_azi_position_written = pos;
}
}
}
@@ -442,12 +436,12 @@ Strip::select_event (Button& button, ButtonState bs)
_controls_locked = !_controls_locked;
_surface->write (display (1,_controls_locked ? "Locked" : "Unlock"));
queue_display_reset (1000);
- return;
+ return;
}
if (ms & MackieControlProtocol::MODIFIER_SHIFT) {
/* reset to default */
- boost::shared_ptr<AutomationControl> ac = _vpot->control ();
+ boost::shared_ptr<AutomationControl> ac = _fader->control ();
if (ac) {
ac->set_value (ac->normal());
}
@@ -494,17 +488,24 @@ 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 (_surface->mcp().modifier_state() == MackieControlProtocol::MODIFIER_SHIFT) {
+ if (ac) {
+ ac->set_value (ac->normal());
+ }
+ } else {
+
+ _fader->set_in_use (true);
+ _fader->start_touch (_surface->mcp().transport_frame());
+
if (ac) {
do_parameter_display ((AutomationType) ac->parameter().type(), ac->internal_to_interface (ac->get_value()));
queue_display_reset (2000);
}
+ }
} else {
@@ -758,54 +759,43 @@ Strip::unlock_controls ()
_controls_locked = false;
}
-MidiByteArray
+void
Strip::gui_selection_changed (ARDOUR::RouteNotificationListPtr rl)
{
for (ARDOUR::RouteNotificationList::iterator i = rl->begin(); i != rl->end(); ++i) {
if ((*i) == _route) {
- return _select->set_state (on);
+ cerr << "Surface " << _surface->number() << "Strip " << _index << " found its route in the selection, turn button on\n";
+ _surface->write (_select->set_state (on));
+ return;
}
}
- return _select->set_state (off);
+ cerr << "Surface " << _surface->number() << "Strip " << _index << " did NOT find its route in the selection, turn button OFF\n";
+ _surface->write (_select->set_state (off));
}
string
Strip::vpot_mode_string () const
{
- switch (_vpot_mode) {
- case Gain:
+ boost::shared_ptr<AutomationControl> ac = _vpot->control();
+
+ if (!ac) {
+ return string();
+ }
+
+ switch (ac->parameter().type()) {
+ case GainAutomation:
return "Fader";
- case PanAzimuth:
+ case PanAzimuthAutomation:
return "Pan";
- case PanWidth:
+ case PanWidthAutomation:
return "Width";
- case PanElevation:
+ case PanElevationAutomation:
return "Elev";
- case PanFrontBack:
+ case PanFrontBackAutomation:
return "F/Rear";
- case PanLFE:
+ case PanLFEAutomation:
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 "???";
@@ -818,13 +808,7 @@ Strip::flip_mode_changed (bool notify)
return;
}
- if (_surface->mcp().flip_mode()) {
- /* flip mode is on - save what it used to be */
- _preflip_vpot_mode = _vpot_mode;
- } else {
- /* flip mode is off - restore flip mode to what it used to be */
- _vpot_mode = _preflip_vpot_mode;
- }
+ reset_saved_values ();
boost::shared_ptr<AutomationControl> fader_controllable = _fader->control ();
boost::shared_ptr<AutomationControl> vpot_controllable = _vpot->control ();
@@ -832,6 +816,9 @@ Strip::flip_mode_changed (bool notify)
_fader->set_control (vpot_controllable);
_vpot->set_control (fader_controllable);
+ control_by_parameter[fader_controllable->parameter()] = _vpot;
+ control_by_parameter[vpot_controllable->parameter()] = _fader;
+
_surface->write (display (1, vpot_mode_string ()));
if (notify) {
@@ -953,7 +940,7 @@ Strip::build_output_list (const ChanCount& channels)
void
Strip::next_pot_mode ()
{
- vector<PotMode>::iterator i;
+ vector<Evoral::Parameter>::iterator i;
if (_surface->mcp().flip_mode()) {
/* do not change vpot mode while in flipped mode */
@@ -963,8 +950,14 @@ Strip::next_pot_mode ()
return;
}
+ boost::shared_ptr<AutomationControl> ac = _vpot->control();
+
+ if (!ac) {
+ return;
+ }
+
for (i = current_pot_modes.begin(); i != current_pot_modes.end(); ++i) {
- if ((*i) == _vpot_mode) {
+ if ((*i) == ac->parameter()) {
break;
}
}
@@ -981,112 +974,91 @@ Strip::next_pot_mode ()
i = current_pot_modes.begin();
}
- set_vpot_mode (*i);
+ set_vpot_parameter (*i);
}
void
-Strip::set_vpot_mode (PotMode m)
+Strip::set_vpot_parameter (Evoral::Parameter p)
{
- boost::shared_ptr<Send> send;
boost::shared_ptr<Pannable> pannable;
- DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch to vpot mode %1\n", m));
+ DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch to vpot mode %1\n", p));
- if (!_route) {
- return;
- }
-
- _vpot_mode = m;
+ reset_saved_values ();
- /* one of these is unnecessary, but its not worth trying to find
- out which - it will just cause one additional message to be
- sent to the surface.
- */
-
- _last_pan_position_written = -1;
- _last_gain_position_written = -1;
-
- switch (_vpot_mode) {
- case Gain:
- break;
- case PanAzimuth:
+ switch (p.type()) {
+ case PanAzimuthAutomation:
pannable = _route->pannable ();
if (pannable) {
if (_surface->mcp().flip_mode()) {
/* gain to vpot, pan azi to fader */
_vpot->set_control (_route->gain_control());
+ control_by_parameter[GainAutomation] = _vpot;
if (pannable) {
_fader->set_control (pannable->pan_azimuth_control);
+ control_by_parameter[PanAzimuthAutomation] = _fader;
+ } else {
+ _fader->set_control (boost::shared_ptr<AutomationControl>());
+ control_by_parameter[PanAzimuthAutomation] = 0;
}
- _vpot_mode = Gain;
} else {
/* gain to fader, pan azi to vpot */
_fader->set_control (_route->gain_control());
+ control_by_parameter[GainAutomation] = _fader;
if (pannable) {
_vpot->set_control (pannable->pan_azimuth_control);
+ control_by_parameter[PanAzimuthAutomation] = _vpot;
+ } else {
+ _vpot->set_control (boost::shared_ptr<AutomationControl>());
+ control_by_parameter[PanAzimuthAutomation] = 0;
}
}
}
break;
- case PanWidth:
+ case PanWidthAutomation:
pannable = _route->pannable ();
if (pannable) {
if (_surface->mcp().flip_mode()) {
/* gain to vpot, pan width to fader */
_vpot->set_control (_route->gain_control());
+ control_by_parameter[GainAutomation] = _vpot;
if (pannable) {
_fader->set_control (pannable->pan_width_control);
+ control_by_parameter[PanWidthAutomation] = _fader;
+ } else {
+ _fader->set_control (boost::shared_ptr<AutomationControl>());
+ control_by_parameter[PanWidthAutomation] = 0;
}
- _vpot_mode = Gain;
} else {
/* gain to fader, pan width to vpot */
_fader->set_control (_route->gain_control());
+ control_by_parameter[GainAutomation] = _fader;
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;
+ control_by_parameter[PanWidthAutomation] = _vpot;
} else {
- /* route gain to fader, send gain to vpot */
- _vpot->set_control (send->amp()->gain_control());
- _fader->set_control (_route->gain_control());
+ _vpot->set_control (boost::shared_ptr<AutomationControl>());
+ control_by_parameter[PanWidthAutomation] = 0;
+ }
}
}
break;
- case Send2:
- break;
- case Send3:
- break;
- case Send4:
- break;
- case Send5:
- break;
- case Send6:
+ case PanElevationAutomation:
break;
- case Send7:
+ case PanFrontBackAutomation:
break;
- case Send8:
+ case PanLFEAutomation:
break;
- };
+ }
_surface->write (display (1, vpot_mode_string()));
}
+
+void
+Strip::reset_saved_values ()
+{
+ _last_pan_azi_position_written = -1.0;
+ _last_pan_width_position_written = -1.0;
+ _last_gain_position_written = -1.0;
+
+}
diff --git a/libs/surfaces/mackie/strip.h b/libs/surfaces/mackie/strip.h
index dfa0fbf33a..9123ef6b70 100644
--- a/libs/surfaces/mackie/strip.h
+++ b/libs/surfaces/mackie/strip.h
@@ -4,6 +4,8 @@
#include <string>
#include <iostream>
+#include "evoral/Parameter.hpp"
+
#include "pbd/property_basics.h"
#include "pbd/signals.h"
@@ -79,28 +81,9 @@ public:
void lock_controls ();
void unlock_controls ();
- MidiByteArray gui_selection_changed (ARDOUR::RouteNotificationListPtr);
+ void 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;
@@ -108,8 +91,6 @@ private:
Button* _vselect;
Button* _fader_touch;
Pot* _vpot;
- PotMode _vpot_mode;
- PotMode _preflip_vpot_mode;
Fader* _fader;
Meter* _meter;
int _index;
@@ -120,7 +101,8 @@ private:
PBD::ScopedConnectionList route_connections;
float _last_gain_position_written;
- float _last_pan_position_written;
+ float _last_pan_azi_position_written;
+ float _last_pan_width_position_written;
void notify_solo_changed ();
void notify_mute_changed ();
@@ -154,9 +136,13 @@ private:
void vselect_event (Button&, ButtonState);
void fader_touch_event (Button&, ButtonState);
- std::vector<PotMode> current_pot_modes;
+ std::vector<Evoral::Parameter> current_pot_modes;
void next_pot_mode ();
- void set_vpot_mode (PotMode);
+ void set_vpot_parameter (Evoral::Parameter);
+
+ void reset_saved_values ();
+
+ std::map<Evoral::Parameter,Control*> control_by_parameter;
};
}
diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc
index 053761fd3e..c53ea0fdc0 100644
--- a/libs/surfaces/mackie/surface.cc
+++ b/libs/surfaces/mackie/surface.cc
@@ -21,7 +21,7 @@
#include "surface.h"
#include "strip.h"
#include "mackie_control_protocol.h"
-#include "mackie_jog_wheel.h"
+#include "jog_wheel.h"
#include "strip.h"
#include "button.h"
@@ -223,7 +223,9 @@ float
Surface::scaled_delta (float delta, float current_speed)
{
/* XXX needs work before use */
- return (std::pow (float(delta + 1), 2) + current_speed) / 100.0;
+ const float sign = delta < 0.0 ? -1.0 : 1.0;
+
+ return ((sign * std::pow (delta + 1.0, 2.0)) + current_speed) / 100.0;
}
void
@@ -231,10 +233,10 @@ Surface::display_bank_start (uint32_t current_bank)
{
if (current_bank == 0) {
// send Ar. to 2-char display on the master
- _port->write (two_char_display ("Ar", ".."));
+ show_two_char_display ("Ar", "..");
} else {
// write the current first remote_id to the 2-char display
- _port->write (two_char_display (current_bank));
+ show_two_char_display (current_bank);
}
}
@@ -352,9 +354,29 @@ Surface::handle_midi_controller_message (MIDI::Parser &, MIDI::EventTwoBytes* ev
Pot* pot = pots[ev->controller_number];
+ if (!pot) {
+ if (ev->controller_number == Jog::ID && _jog_wheel) {
+
+ // bit 6 gives the sign
+ float sign = (ev->value & 0x40) == 0 ? 1.0 : -1.0;
+ // bits 0..5 give the velocity. we interpret this as "ticks
+ // moved before this message was sent"
+ float ticks = (ev->value & 0x3f);
+ if (ticks == 0) {
+ /* euphonix and perhaps other devices send zero
+ when they mean 1, we think.
+ */
+ ticks = 1;
+ }
+ float delta = sign * (ticks / (float) 0x3f);
+
+ DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Jog wheel moved %1\n", ticks));
+ _jog_wheel->jog_event (delta);
+ return;
+ }
+ }
+
if (pot) {
- ControlState state;
-
// bit 6 gives the sign
float sign = (ev->value & 0x40) == 0 ? 1.0 : -1.0;
// bits 0..5 give the velocity. we interpret this as "ticks
@@ -372,16 +394,7 @@ Surface::handle_midi_controller_message (MIDI::Parser &, MIDI::EventTwoBytes* ev
if (strip) {
strip->handle_pot (*pot, delta);
- } else {
- JogWheel* wheel = dynamic_cast<JogWheel*> (pot);
- if (wheel) {
- DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Jog wheel moved %1\n", state.ticks));
- wheel->jog_event (*_port, *pot, delta);
- } else {
- DEBUG_TRACE (DEBUG::MackieControl, string_compose ("External controller moved %1\n", state.ticks));
- cout << "external controller" << delta << endl;
- }
- }
+ }
} else {
DEBUG_TRACE (DEBUG::MackieControl, "pot not found\n");
}
@@ -578,7 +591,7 @@ Surface::zero_controls ()
if (_number == 0 && _mcp.device_info().has_two_character_display()) {
// any hardware-specific stuff
// clear 2-char display
- _port->write (two_char_display ("aa"));
+ show_two_char_display ("aa");
}
// and the led ring for the master strip
@@ -601,31 +614,6 @@ Surface::write (const MidiByteArray& data)
}
}
-void
-Surface::jog_wheel_state_display (JogWheel::State state)
-{
- switch (state) {
- case JogWheel::zoom:
- _port->write (two_char_display ("Zm"));
- break;
- case JogWheel::scroll:
- _port->write (two_char_display ("Sc"));
- break;
- case JogWheel::scrub:
- _port->write (two_char_display ("Sb"));
- break;
- case JogWheel::shuttle:
- _port->write (two_char_display ("Sh"));
- break;
- case JogWheel::speed:
- _port->write (two_char_display ("Sp"));
- break;
- case JogWheel::select:
- _port->write (two_char_display ("Se"));
- break;
- }
-}
-
void
Surface::map_routes (const vector<boost::shared_ptr<Route> >& routes)
{
@@ -643,43 +631,43 @@ Surface::map_routes (const vector<boost::shared_ptr<Route> >& routes)
}
-static char translate_seven_segment (char achar)
+static char
+translate_seven_segment (char achar)
{
achar = toupper (achar);
- if (achar >= 0x40 && achar <= 0x60)
+
+ if (achar >= 0x40 && achar <= 0x60) {
return achar - 0x40;
- else if (achar >= 0x21 && achar <= 0x3f)
- return achar;
- else
- return 0x00;
+ } else if (achar >= 0x21 && achar <= 0x3f) {
+ return achar;
+ } else {
+ return 0x00;
+ }
}
-MidiByteArray
-Surface::two_char_display (const std::string & msg, const std::string & dots)
+void
+Surface::show_two_char_display (const std::string & msg, const std::string & dots)
{
- if (_stype != mcu || !_mcp.device_info().has_two_character_display()) {
- return MidiByteArray();
+ if (_stype != mcu || !_mcp.device_info().has_two_character_display() || msg.length() != 2 || dots.length() != 2) {
+ return;
}
-
- if (msg.length() != 2) throw MackieControlException ("MackieMidiBuilder::two_char_display: msg must be exactly 2 characters");
- if (dots.length() != 2) throw MackieControlException ("MackieMidiBuilder::two_char_display: dots must be exactly 2 characters");
- MidiByteArray bytes (6, 0xb0, 0x4a, 0x00, 0xb0, 0x4b, 0x00);
+ MidiByteArray right (3, 0xb0, 0x4b, 0x00);
+ MidiByteArray left (3, 0xb0, 0x4a, 0x00);
- // chars are understood by the surface in right-to-left order
- // could also exchange the 0x4a and 0x4b, above
- bytes[5] = translate_seven_segment (msg[0]) + (dots[0] == '.' ? 0x40 : 0x00);
- bytes[2] = translate_seven_segment (msg[1]) + (dots[1] == '.' ? 0x40 : 0x00);
+ right[2] = translate_seven_segment (msg[0]) + (dots[0] == '.' ? 0x40 : 0x00);
+ left[2] = translate_seven_segment (msg[1]) + (dots[1] == '.' ? 0x40 : 0x00);
- return bytes;
+ _port->write (right);
+ _port->write (left);
}
-MidiByteArray
-Surface::two_char_display (unsigned int value, const std::string & /*dots*/)
+void
+Surface::show_two_char_display (unsigned int value, const std::string & /*dots*/)
{
ostringstream os;
os << setfill('0') << setw(2) << value % 100;
- return two_char_display (os.str());
+ show_two_char_display (os.str());
}
void
@@ -753,38 +741,37 @@ Surface::update_view_mode_display ()
switch (_mcp.view_mode()) {
case MackieControlProtocol::Mixer:
- _port->write (two_char_display ("Mx"));
+ show_two_char_display ("Mx");
button = buttons[Button::Pan];
break;
case MackieControlProtocol::Dynamics:
- _port->write (two_char_display ("Dy"));
+ show_two_char_display ("Dy");
button = buttons[Button::Dyn];
break;
case MackieControlProtocol::EQ:
- _port->write (two_char_display ("EQ"));
+ show_two_char_display ("EQ");
button = buttons[Button::Eq];
break;
case MackieControlProtocol::Loop:
- _port->write (two_char_display ("LP"));
+ show_two_char_display ("LP");
button = buttons[Button::Loop];
break;
case MackieControlProtocol::AudioTracks:
- _port->write (two_char_display ("AT"));
+ show_two_char_display ("AT");
break;
case MackieControlProtocol::MidiTracks:
- _port->write (two_char_display ("MT"));
- break;
- case MackieControlProtocol::Busses:
- _port->write (two_char_display ("Bs"));
+ show_two_char_display ("MT");
break;
case MackieControlProtocol::Sends:
- _port->write (two_char_display ("Sn"));
+ show_two_char_display ("Sn");
button = buttons[Button::Sends];
break;
case MackieControlProtocol::Plugins:
- _port->write (two_char_display ("Pl"));
+ show_two_char_display ("Pl");
button = buttons[Button::Plugin];
break;
+ default:
+ break;
}
if (button) {
@@ -802,7 +789,7 @@ void
Surface::gui_selection_changed (ARDOUR::RouteNotificationListPtr routes)
{
for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
- _port->write ((*s)->gui_selection_changed (routes));
+ (*s)->gui_selection_changed (routes);
}
}
@@ -822,3 +809,13 @@ Surface::say_hello ()
zero_all ();
}
+
+void
+Surface::next_jog_mode ()
+{
+}
+
+void
+Surface::set_jog_mode (JogWheel::Mode m)
+{
+}
diff --git a/libs/surfaces/mackie/surface.h b/libs/surfaces/mackie/surface.h
index 747abad0cf..5ef29ca72a 100644
--- a/libs/surfaces/mackie/surface.h
+++ b/libs/surfaces/mackie/surface.h
@@ -9,7 +9,7 @@
#include "controls.h"
#include "types.h"
-#include "mackie_jog_wheel.h"
+#include "jog_wheel.h"
namespace MIDI {
class Parser;
@@ -131,8 +131,8 @@ public:
// display the first 2 chars of the msg in the 2 char display
// . is appended to the previous character, so A.B. would
// be two characters
- MidiByteArray two_char_display (const std::string & msg, const std::string & dots = " ");
- MidiByteArray two_char_display (unsigned int value, const std::string & dots = " ");
+ void show_two_char_display (const std::string & msg, const std::string & dots = " ");
+ void show_two_char_display (unsigned int value, const std::string & dots = " ");
/**
Timecode display. Only the difference between timecode and last_timecode will
@@ -148,6 +148,9 @@ public:
MackieControlProtocol& mcp() const { return _mcp; }
+ void next_jog_mode ();
+ void set_jog_mode (Mackie::JogWheel::Mode);
+
protected:
private:
@@ -161,7 +164,6 @@ public:
Mackie::JogWheel* _jog_wheel;
Fader* _master_fader;
- void jog_wheel_state_display (Mackie::JogWheel::State state);
void handle_midi_sysex (MIDI::Parser&, MIDI::byte *, size_t count);
MidiByteArray host_connection_query (MidiByteArray& bytes);
MidiByteArray host_connection_confirmation (const MidiByteArray& bytes);
diff --git a/libs/surfaces/mackie/wscript b/libs/surfaces/mackie/wscript
index 5f0bb1aa2d..fe276c4e82 100644
--- a/libs/surfaces/mackie/wscript
+++ b/libs/surfaces/mackie/wscript
@@ -29,9 +29,9 @@ def build(bld):
gui.cc
interface.cc
jog.cc
+ jog_wheel.cc
led.cc
mackie_control_protocol.cc
- mackie_jog_wheel.cc
mcp_buttons.cc
meter.cc
midi_byte_array.cc