summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2015-10-08 12:49:58 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2015-10-08 12:51:44 -0400
commit0cb1c7b58c614ba2096bcbd57cb7e9d5c2689a43 (patch)
treeb8f058c59bd3068e39061a2b7f10a81694d1eb89
parent4677d047a537a4d459055bb4b0395f2dd821ca32 (diff)
lots of changes to try to get the Mackie Control display be more useful and usable
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc18
-rw-r--r--libs/surfaces/mackie/midi_byte_array.cc7
-rw-r--r--libs/surfaces/mackie/strip.cc92
-rw-r--r--libs/surfaces/mackie/strip.h13
-rw-r--r--libs/surfaces/mackie/surface.cc130
-rw-r--r--libs/surfaces/mackie/surface.h8
6 files changed, 177 insertions, 91 deletions
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index 167a0053a6..c195916df9 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -461,11 +461,17 @@ MackieControlProtocol::periodic ()
initialize();
}
- struct timeval now;
- uint64_t now_usecs;
- gettimeofday (&now, 0);
+ ARDOUR::microseconds_t now_usecs = ARDOUR::get_microseconds ();
- now_usecs = (now.tv_sec * 1000000) + now.tv_usec;
+ static int cnt = 0;
+
+ cnt++;
+ if ((cnt != 1) && (cnt % 25 == 0)) {
+ if (_master_surface) {
+ cerr << string_compose ("Cnt now %1 ", cnt) << endl;
+ _master_surface->display_message_for (string_compose ("Cnt now %1\n12Hey Paul", cnt), 1000);
+ }
+ }
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
@@ -496,11 +502,13 @@ MackieControlProtocol::redisplay ()
initialize();
}
+ ARDOUR::microseconds_t now = ARDOUR::get_microseconds ();
+
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
- (*s)->redisplay ();
+ (*s)->redisplay (now);
}
}
diff --git a/libs/surfaces/mackie/midi_byte_array.cc b/libs/surfaces/mackie/midi_byte_array.cc
index ffb94a03a9..45d0439a75 100644
--- a/libs/surfaces/mackie/midi_byte_array.cc
+++ b/libs/surfaces/mackie/midi_byte_array.cc
@@ -88,8 +88,9 @@ ostream & operator << (ostream & os, const MidiByteArray & mba)
MidiByteArray & operator << (MidiByteArray & mba, const std::string & st)
{
- for (string::const_iterator it = st.begin(); it != st.end(); ++it) {
- mba << *it;
- }
+ /* note that this assumes that "st" is ASCII encoded
+ */
+
+ mba.insert (mba.end(), st.begin(), st.end());
return mba;
}
diff --git a/libs/surfaces/mackie/strip.cc b/libs/surfaces/mackie/strip.cc
index fdd1bf7b1a..6be3c79b5d 100644
--- a/libs/surfaces/mackie/strip.cc
+++ b/libs/surfaces/mackie/strip.cc
@@ -61,8 +61,6 @@ using namespace PBD;
using namespace ArdourSurface;
using namespace Mackie;
-uint64_t Strip::_global_block_redisplay_until = 0;
-
#ifndef timeradd /// only avail with __USE_BSD
#define timeradd(a,b,result) \
do { \
@@ -94,7 +92,8 @@ Strip::Strip (Surface& s, const std::string& name, int index, const map<Button::
, _controls_locked (false)
, _transport_is_rolling (false)
, _metering_active (true)
- , _block_redisplay_until (0)
+ , _block_vpot_mode_redisplay_until (0)
+ , _block_screen_redisplay_until (0)
, _pan_mode (PanAzimuthAutomation)
, _last_gain_position_written (-1.0)
, _last_pan_azi_position_written (-1.0)
@@ -345,7 +344,6 @@ Strip::notify_gain_changed (bool force_update)
queue_parameter_display (GainAutomation, gain_coefficient);
}
- block_display_for (2000);
_last_gain_position_written = normalized_position;
}
}
@@ -502,7 +500,7 @@ Strip::select_event (Button&, ButtonState bs)
if (ms & MackieControlProtocol::MODIFIER_CMDALT) {
_controls_locked = !_controls_locked;
_surface->write (display (1,_controls_locked ? "Locked" : "Unlock"));
- block_display_for (1000);
+ block_vpot_mode_display_for (1000);
return;
}
@@ -571,7 +569,6 @@ Strip::fader_touch_event (Button&, ButtonState bs)
if (ac) {
queue_parameter_display ((AutomationType) ac->parameter().type(), ac->internal_to_interface (ac->get_value()));
- block_display_for (2000);
}
}
@@ -666,6 +663,8 @@ Strip::queue_parameter_display (AutomationType type, float val)
void
Strip::do_parameter_display (AutomationType type, float val)
{
+ bool screen_hold = false;
+
switch (type) {
case GainAutomation:
if (val == 0.0) {
@@ -675,6 +674,7 @@ Strip::do_parameter_display (AutomationType type, float val)
float dB = accurate_coefficient_to_dB (val);
snprintf (buf, sizeof (buf), "%6.1f", dB);
_surface->write (display (1, buf));
+ screen_hold = true;
}
break;
@@ -684,6 +684,7 @@ Strip::do_parameter_display (AutomationType type, float val)
if (p && _route->panner()) {
string str =_route->panner()->value_as_string (p->pan_azimuth_control);
_surface->write (display (1, str));
+ screen_hold = true;
}
}
break;
@@ -693,6 +694,7 @@ Strip::do_parameter_display (AutomationType type, float val)
char buf[16];
snprintf (buf, sizeof (buf), "%5ld%%", lrintf ((val * 200.0)-100));
_surface->write (display (1, buf));
+ screen_hold = true;
}
break;
@@ -708,6 +710,10 @@ Strip::do_parameter_display (AutomationType type, float val)
default:
break;
}
+
+ if (screen_hold) {
+ block_vpot_mode_display_for (1000);
+ }
}
void
@@ -756,30 +762,50 @@ Strip::handle_pot (Pot& pot, float delta)
}
void
-Strip::periodic (uint64_t usecs)
+Strip::periodic (ARDOUR::microseconds_t now)
{
+ bool reshow_vpot_mode = false;
+
if (!_route) {
return;
}
- if (_global_block_redisplay_until >= usecs) {
+
+ if (_block_screen_redisplay_until >= now) {
+
+ /* no drawing here, for now */
return;
- } else {
- /* reset since timer has expired */
- _global_block_redisplay_until = 0;
+
+ } else if (_block_screen_redisplay_until) {
+
+ /* timeout reached, reset */
+
+ _block_screen_redisplay_until = 0;
+ reshow_vpot_mode = true;
}
- if (_block_redisplay_until >= usecs) {
+ if (_block_vpot_mode_redisplay_until >= now) {
return;
- } else if (_block_redisplay_until) {
+ } else if (_block_vpot_mode_redisplay_until) {
+
+ /* timeout reached, reset */
+
+ _block_vpot_mode_redisplay_until = 0;
+ reshow_vpot_mode = true;
+ }
+
+ if (reshow_vpot_mode) {
return_to_vpot_mode_display ();
} else {
+ /* no point doing this if we just switched back to vpot mode
+ display */
update_automation ();
- update_meter ();
}
+
+ update_meter ();
}
void
-Strip::redisplay ()
+Strip::redisplay (ARDOUR::microseconds_t now)
{
RedisplayRequest req;
bool have_request = false;
@@ -789,6 +815,10 @@ Strip::redisplay ()
have_request = true;
}
+ if (_block_screen_redisplay_until >= now) {
+ return;
+ }
+
if (have_request) {
do_parameter_display (req.type, req.val);
}
@@ -1004,35 +1034,15 @@ Strip::flip_mode_changed (bool notify)
}
void
-Strip::block_display_for (uint32_t msecs)
+Strip::block_screen_display_for (uint32_t msecs)
{
- struct timeval now;
- struct timeval delta;
- struct timeval when;
- gettimeofday (&now, 0);
-
- delta.tv_sec = msecs/1000;
- delta.tv_usec = (msecs - ((msecs/1000) * 1000)) * 1000;
-
- timeradd (&now, &delta, &when);
-
- _block_redisplay_until = (when.tv_sec * 1000000) + when.tv_usec;
+ _block_screen_redisplay_until = ARDOUR::get_microseconds() + (msecs * 1000);
}
void
-Strip::block_all_strip_redisplay_for (uint32_t msecs)
+Strip::block_vpot_mode_display_for (uint32_t msecs)
{
- struct timeval now;
- struct timeval delta;
- struct timeval when;
- gettimeofday (&now, 0);
-
- delta.tv_sec = msecs/1000;
- delta.tv_usec = (msecs - ((msecs/1000) * 1000)) * 1000;
-
- timeradd (&now, &delta, &when);
-
- _global_block_redisplay_until = (when.tv_sec * 1000000) + when.tv_usec;
+ _block_vpot_mode_redisplay_until = ARDOUR::get_microseconds() + (msecs * 1000);
}
void
@@ -1047,8 +1057,6 @@ Strip::return_to_vpot_mode_display ()
} else {
_surface->write (blank_display (1));
}
-
- _block_redisplay_until = 0;
}
struct RouteCompareByName {
@@ -1137,7 +1145,7 @@ Strip::next_pot_mode ()
/* do not change vpot mode while in flipped mode */
DEBUG_TRACE (DEBUG::MackieControl, "not stepping pot mode - in flip mode\n");
_surface->write (display (1, "Flip"));
- block_display_for (1000);
+ block_vpot_mode_display_for (1000);
return;
}
diff --git a/libs/surfaces/mackie/strip.h b/libs/surfaces/mackie/strip.h
index 61bab7c352..1832871a3b 100644
--- a/libs/surfaces/mackie/strip.h
+++ b/libs/surfaces/mackie/strip.h
@@ -67,8 +67,8 @@ public:
void handle_fader_touch (Fader&, bool touch_on);
void handle_pot (Pot&, float delta);
- void periodic (uint64_t now_usecs);
- void redisplay ();
+ void periodic (ARDOUR::microseconds_t now_usecs);
+ void redisplay (ARDOUR::microseconds_t now_usecs);
MidiByteArray display (uint32_t line_number, const std::string&);
MidiByteArray blank_display (uint32_t line_number);
@@ -86,7 +86,8 @@ public:
void notify_metering_state_changed();
- static void block_all_strip_redisplay_for (uint32_t msecs);
+ void block_screen_display_for (uint32_t msecs);
+ void block_vpot_mode_display_for (uint32_t msecs);
private:
Button* _solo;
@@ -103,7 +104,8 @@ private:
bool _controls_locked;
bool _transport_is_rolling;
bool _metering_active;
- uint64_t _block_redisplay_until;
+ uint64_t _block_vpot_mode_redisplay_until;
+ uint64_t _block_screen_redisplay_until;
boost::shared_ptr<ARDOUR::Route> _route;
PBD::ScopedConnectionList route_connections;
@@ -130,7 +132,6 @@ private:
std::string vpot_mode_string () const;
- void block_display_for (uint32_t msecs);
void return_to_vpot_mode_display ();
struct RedisplayRequest {
@@ -162,8 +163,6 @@ private:
void reset_saved_values ();
std::map<Evoral::Parameter,Control*> control_by_parameter;
-
- static uint64_t _global_block_redisplay_until;
};
}
diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc
index 411a4ea475..5551c5d0de 100644
--- a/libs/surfaces/mackie/surface.cc
+++ b/libs/surfaces/mackie/surface.cc
@@ -23,6 +23,8 @@
#include <cstdio>
#include <cmath>
+#include <glibmm/convert.h>
+
#include "midi++/port.h"
#include "ardour/audioengine.h"
@@ -845,10 +847,10 @@ Surface::periodic (uint64_t now_usecs)
}
void
-Surface::redisplay ()
+Surface::redisplay (ARDOUR::microseconds_t now)
{
for (Strips::iterator s = strips.begin(); s != strips.end(); ++s) {
- (*s)->redisplay ();
+ (*s)->redisplay (now);
}
}
@@ -1088,13 +1090,11 @@ Surface::reset ()
{
if (_port) {
/* reset msg for Mackie Control */
- MidiByteArray msg (8, MIDI::sysex, 0x00, 0x00, 0x66, 0x14, 0x08, 0x00, MIDI::eox);
- _port->write (msg);
- msg[4] = 0x15; /* reset Mackie XT */
- _port->write (msg);
- msg[4] = 0x10; /* reset Logic Control */
- _port->write (msg);
- msg[4] = 0x11; /* reset Logic Control XT */
+ MidiByteArray msg;
+ msg << sysex_hdr();
+ msg << 0x08;
+ msg << 0x00;
+ msg << MIDI::eox;
_port->write (msg);
}
}
@@ -1104,13 +1104,11 @@ Surface::toggle_backlight ()
{
if (_port) {
int onoff = random() %2;
- MidiByteArray msg (8, MIDI::sysex, 0x00, 0x00, 0x66, 0x14, 0x0a, onoff, MIDI::eox);
- _port->write (msg);
- msg[4] = 0x15; /* reset Mackie XT */
- _port->write (msg);
- msg[4] = 0x10; /* reset Logic Control */
- _port->write (msg);
- msg[4] = 0x11; /* reset Logic Control XT */
+ MidiByteArray msg;
+ msg << sysex_hdr ();
+ msg << 0xa;
+ msg << (onoff ? 0x1 : 0x0);
+ msg << MIDI::eox;
_port->write (msg);
}
}
@@ -1119,13 +1117,11 @@ void
Surface::recalibrate_faders ()
{
if (_port) {
- MidiByteArray msg (8, MIDI::sysex, 0x00, 0x00, 0x66, 0x14, 0x09, 0x00, MIDI::eox);
- _port->write (msg);
- msg[4] = 0x15; /* reset Mackie XT */
- _port->write (msg);
- msg[4] = 0x10; /* reset Logic Control */
- _port->write (msg);
- msg[4] = 0x11; /* reset Logic Control XT */
+ MidiByteArray msg;
+ msg << sysex_hdr ();
+ msg << 0x09;
+ msg << 0x00;
+ msg << MIDI::eox;
_port->write (msg);
}
}
@@ -1138,19 +1134,17 @@ Surface::set_touch_sensitivity (int sensitivity)
/* sensitivity already clamped by caller */
if (_port) {
- MidiByteArray msg (9, MIDI::sysex, 0x00, 0x00, 0x66, 0x14, 0x0e, 0xff, sensitivity, MIDI::eox);
+ MidiByteArray msg;
+
+ msg << sysex_hdr ();
+ msg << 0x0e;
+ msg << 0xff; /* overwritten for each fader below */
+ msg << (sensitivity & 0x7f);
+ msg << MIDI::eox;
for (int fader = 0; fader < 9; ++fader) {
msg[6] = fader;
-
_port->write (msg);
- msg[4] = 0x15; /* reset Mackie XT */
- _port->write (msg);
- msg[4] = 0x10; /* reset Logic Control */
- _port->write (msg);
- msg[4] = 0x11; /* reset Logic Control XT */
-
- g_usleep (1000); /* milliseconds */
}
}
}
@@ -1177,3 +1171,75 @@ Surface::connected ()
turn_it_on ();
}
}
+
+MidiByteArray
+Surface::display_line (string const& msg, int line_num)
+{
+ MidiByteArray midi_msg;
+ midi_msg << sysex_hdr ();
+ midi_msg << 0x12;
+ midi_msg << (line_num ? 0x38 : 0x0); /* offsets into char array
+ * on device that
+ * correspond to line
+ * starts
+ */
+ if (msg.empty()) {
+
+ midi_msg.insert (midi_msg.end(), 55, ' ');
+
+ } else {
+
+ /* ascii data to display. @param msg is UTF-8 which is not legal. */
+ string ascii = Glib::convert_with_fallback (msg, "UTF-8", "ISO-8859-1", "_");
+ string::size_type len = ascii.length();
+
+ if (len > 55) {
+ midi_msg << ascii.substr (0, 55);
+ } else {
+ midi_msg << ascii;
+
+ for (string::size_type i = len; i < 55; ++i) {
+ midi_msg << ' ';
+ }
+ }
+ }
+
+ midi_msg << MIDI::eox;
+
+ return midi_msg;
+}
+
+/** display @param msg on the 55x2 screen for @param msecs milliseconds
+ *
+ * @param msg is assumed to be UTF-8 encoded, and will be converted
+ * to ASCII with an underscore as fallback character before being
+ * sent to the device.
+ */
+void
+Surface::display_message_for (string const& msg, uint64_t msecs)
+{
+ string::size_type newline;
+
+ if ((newline = msg.find ('\n')) == string::npos) {
+
+ _port->write (display_line (msg, 0));
+ _port->write (display_line (string(), 1));
+
+ } else if (newline == 0) {
+
+ _port->write (display_line (string(), 0));
+ _port->write (display_line (msg.substr (1), 1));
+
+ } else {
+
+ string first_line = msg.substr (0, newline-1);
+ string second_line = msg.substr (newline+1);
+
+ _port->write (display_line (first_line, 0));
+ _port->write (display_line (second_line.substr (0, second_line.find_first_of ('\n')), 1));
+ }
+
+ for (Strips::const_iterator s = strips.begin(); s != strips.end(); ++s) {
+ (*s)->block_screen_display_for (msecs);
+ }
+}
diff --git a/libs/surfaces/mackie/surface.h b/libs/surfaces/mackie/surface.h
index b43c9e3962..4168ec23ab 100644
--- a/libs/surfaces/mackie/surface.h
+++ b/libs/surfaces/mackie/surface.h
@@ -89,8 +89,8 @@ public:
const MidiByteArray& sysex_hdr() const;
- void periodic (uint64_t now_usecs);
- void redisplay ();
+ void periodic (ARDOUR::microseconds_t now_usecs);
+ void redisplay (ARDOUR::microseconds_t now_usecs);
void hui_heartbeat ();
void handle_midi_pitchbend_message (MIDI::Parser&, MIDI::pitchbend_t, uint32_t channel_id);
@@ -163,6 +163,8 @@ public:
void notify_metering_state_changed();
void turn_it_on ();
+ void display_message_for (std::string const& msg, uint64_t msecs);
+
XMLNode& get_state ();
int set_state (const XMLNode&, int version);
@@ -198,6 +200,8 @@ public:
};
int connection_state;
+
+ MidiByteArray display_line (std::string const& msg, int line_num);
};
}