summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2015-10-02 22:03:17 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2015-10-02 22:08:14 -0400
commit4d47760d61a5d1f73d47c16663480c9353bfb318 (patch)
tree760a682e1179c07b6da596ee196778fff5926044
parent05a8107ff689284c22b2a89498ade31493c06cfc (diff)
add new (fast) redisplay timer that pushes parameter display text to MCP device.
Changes are queued in a FIFO, and pulled when a timeout in the MCP event loop fires.
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc41
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.h2
-rw-r--r--libs/surfaces/mackie/strip.cc56
-rw-r--r--libs/surfaces/mackie/surface.cc8
-rw-r--r--libs/surfaces/mackie/surface.h1
5 files changed, 94 insertions, 14 deletions
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index d52deb115c..1b66528754 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -421,7 +421,13 @@ MackieControlProtocol::set_active (bool yn)
Glib::RefPtr<Glib::TimeoutSource> periodic_timeout = Glib::TimeoutSource::create (100); // milliseconds
periodic_connection = periodic_timeout->connect (sigc::mem_fun (*this, &MackieControlProtocol::periodic));
periodic_timeout->attach (main_loop()->get_context());
+
+ /* a faster periodic task used to display parameter updates */
+ Glib::RefPtr<Glib::TimeoutSource> redisplay_timeout = Glib::TimeoutSource::create (10); // milliseconds
+ redisplay_connection = redisplay_timeout->connect (sigc::mem_fun (*this, &MackieControlProtocol::redisplay));
+ redisplay_timeout->attach (main_loop()->get_context());
+
} else {
BaseUI::quit ();
@@ -471,6 +477,33 @@ MackieControlProtocol::periodic ()
return true;
}
+bool
+MackieControlProtocol::redisplay ()
+{
+ if (!active()) {
+ return false;
+ }
+
+ if (needs_ipmidi_restart) {
+ ipmidi_restart ();
+ return true;
+ }
+
+ if (!_initialized) {
+ initialize();
+ }
+
+ {
+ Glib::Threads::Mutex::Lock lm (surfaces_lock);
+
+ for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
+ (*s)->redisplay ();
+ }
+ }
+
+ return true;
+}
+
void
MackieControlProtocol::update_timecode_beats_led()
{
@@ -1244,7 +1277,7 @@ void
MackieControlProtocol::handle_button_event (Surface& surface, Button& button, ButtonState bs)
{
Button::ID button_id = button.bid();
-
+
if (bs != press && bs != release) {
update_led (surface, button, none);
return;
@@ -1258,9 +1291,9 @@ MackieControlProtocol::handle_button_event (Surface& surface, Button& button, Bu
string action = _device_profile.get_button_action (button.bid(), _modifier_state);
if (!action.empty()) {
-
+
if (action.find ('/') != string::npos) { /* good chance that this is really an action */
-
+
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Looked up action for button %1 with modifier %2, got [%3]\n",
button.bid(), _modifier_state, action));
@@ -1273,7 +1306,9 @@ MackieControlProtocol::handle_button_event (Surface& surface, Button& button, Bu
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("executing action %1\n", action));
access_action (action);
}
+
return;
+
} else {
/* "action" is more likely to be a button name. We use this to
diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h
index 140fdd8996..2008d9c887 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.h
+++ b/libs/surfaces/mackie/mackie_control_protocol.h
@@ -281,6 +281,7 @@ class MackieControlProtocol
Mackie::DeviceInfo _device_info;
Mackie::DeviceProfile _device_profile;
sigc::connection periodic_connection;
+ sigc::connection redisplay_connection;
uint32_t _current_initial_bank;
PBD::ScopedConnectionList audio_engine_connections;
PBD::ScopedConnectionList session_connections;
@@ -322,6 +323,7 @@ class MackieControlProtocol
int create_surfaces ();
bool periodic();
+ bool redisplay();
void build_gui ();
bool midi_input_handler (Glib::IOCondition ioc, MIDI::Port* port);
void clear_ports ();
diff --git a/libs/surfaces/mackie/strip.cc b/libs/surfaces/mackie/strip.cc
index 9447b4121c..68978b3de9 100644
--- a/libs/surfaces/mackie/strip.cc
+++ b/libs/surfaces/mackie/strip.cc
@@ -96,6 +96,7 @@ Strip::Strip (Surface& s, const std::string& name, int index, const map<Button::
, _last_gain_position_written (-1.0)
, _last_pan_azi_position_written (-1.0)
, _last_pan_width_position_written (-1.0)
+ , redisplay_requests (256)
{
_fader = dynamic_cast<Fader*> (Fader::factory (*_surface, index, "fader", *this));
_vpot = dynamic_cast<Pot*> (Pot::factory (*_surface, Pot::ID + index, "vpot", *this));
@@ -318,18 +319,19 @@ Strip::notify_gain_changed (bool force_update)
float gain_coefficient = ac->get_value();
float normalized_position = ac->internal_to_interface (gain_coefficient);
+
if (force_update || normalized_position != _last_gain_position_written) {
if (_surface->mcp().flip_mode() != MackieControlProtocol::Normal) {
if (!control->in_use()) {
_surface->write (_vpot->set (normalized_position, true, Pot::wrap));
}
- do_parameter_display (GainAutomation, gain_coefficient);
+ queue_parameter_display (GainAutomation, gain_coefficient);
} else {
if (!control->in_use()) {
_surface->write (_fader->set_position (normalized_position));
}
- do_parameter_display (GainAutomation, gain_coefficient);
+ queue_parameter_display (GainAutomation, gain_coefficient);
}
queue_display_reset (2000);
@@ -391,7 +393,7 @@ Strip::notify_panner_azi_changed (bool force_update)
_surface->write (_vpot->set (pos, true, Pot::dot));
}
- do_parameter_display (PanAzimuthAutomation, pos);
+ queue_parameter_display (PanAzimuthAutomation, pos);
queue_display_reset (2000);
_last_pan_azi_position_written = pos;
}
@@ -435,7 +437,7 @@ Strip::notify_panner_width_changed (bool force_update)
_surface->write (_vpot->set (pos, true, Pot::spread));
}
- do_parameter_display (PanWidthAutomation, pos);
+ queue_parameter_display (PanWidthAutomation, pos);
queue_display_reset (2000);
_last_pan_azi_position_written = pos;
}
@@ -512,17 +514,17 @@ Strip::fader_touch_event (Button&, ButtonState bs)
boost::shared_ptr<AutomationControl> ac = _fader->control ();
- if (_surface->mcp().modifier_state() == MackieControlProtocol::MODIFIER_SHIFT) {
+ if (_surface->mcp().main_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_parameter_display ((AutomationType) ac->parameter().type(), ac->internal_to_interface (ac->get_value()));
queue_display_reset (2000);
}
}
@@ -605,6 +607,17 @@ Strip::handle_button (Button& button, ButtonState bs)
}
void
+Strip::queue_parameter_display (AutomationType type, float val)
+{
+ RedisplayRequest req;
+
+ req.type = type;
+ req.val = val;
+
+ redisplay_requests.write (&req, 1);
+}
+
+void
Strip::do_parameter_display (AutomationType type, float val)
{
switch (type) {
@@ -658,11 +671,16 @@ Strip::handle_fader (Fader& fader, float position)
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("fader to %1\n", position));
fader.set_value (position);
- queue_display_reset (2000);
- // must echo bytes back to slider now, because
- // the notifier only works if the fader is not being
- // touched. Which it is if we're getting input.
+ /* From the Mackie Control MIDI implementation docs:
+
+ In order to ensure absolute synchronization with the host software,
+ Mackie Control uses a closed-loop servo system for the faders,
+ meaning the faders will always move to their last received position.
+ When a host receives a Fader Position Message, it must then
+ re-transmit that message to the Mackie Control or else the faders
+ will return to their last position.
+ */
_surface->write (fader.set_position (position));
}
@@ -697,6 +715,22 @@ Strip::periodic (uint64_t usecs)
}
}
+void
+Strip::redisplay ()
+{
+ RedisplayRequest req;
+ bool have_request = false;
+
+ while (redisplay_requests.read (&req, 1) == 1) {
+ /* read them all */
+ have_request = true;
+ }
+
+ if (have_request) {
+ do_parameter_display (req.type, req.val);
+ }
+}
+
void
Strip::update_automation ()
{
diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc
index eb77e32c97..b448a7ca19 100644
--- a/libs/surfaces/mackie/surface.cc
+++ b/libs/surfaces/mackie/surface.cc
@@ -758,6 +758,14 @@ Surface::periodic (uint64_t now_usecs)
}
void
+Surface::redisplay ()
+{
+ for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
+ (*s)->redisplay ();
+ }
+}
+
+void
Surface::write (const MidiByteArray& data)
{
if (_active) {
diff --git a/libs/surfaces/mackie/surface.h b/libs/surfaces/mackie/surface.h
index 2473930528..cc9ba58e7f 100644
--- a/libs/surfaces/mackie/surface.h
+++ b/libs/surfaces/mackie/surface.h
@@ -87,6 +87,7 @@ public:
const MidiByteArray& sysex_hdr() const;
void periodic (uint64_t now_usecs);
+ void redisplay ();
void handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t, uint32_t channel_id);
void handle_midi_controller_message (MIDI::Parser&, MIDI::EventTwoBytes*);