summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2015-10-10 17:13:04 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2015-10-10 17:14:30 -0400
commit965b13584213319b0edd7e0a95992c1ea69f16c9 (patch)
tree227dafec1ed7c14aa1c480300769dfc2e0751c35
parent7c58b4de5f269083df2201df1976b98afb823cd5 (diff)
numerous changes to Mackie support, generally offering better robustness
-rw-r--r--libs/surfaces/mackie/gui.cc68
-rw-r--r--libs/surfaces/mackie/gui.h7
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc102
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.h1
-rw-r--r--libs/surfaces/mackie/strip.cc64
-rw-r--r--libs/surfaces/mackie/strip.h3
-rw-r--r--libs/surfaces/mackie/surface.cc15
-rw-r--r--libs/surfaces/mackie/surface.h4
8 files changed, 157 insertions, 107 deletions
diff --git a/libs/surfaces/mackie/gui.cc b/libs/surfaces/mackie/gui.cc
index e627d797e5..4b33126c8d 100644
--- a/libs/surfaces/mackie/gui.cc
+++ b/libs/surfaces/mackie/gui.cc
@@ -118,6 +118,7 @@ MackieControlProtocolGUI::MackieControlProtocolGUI (MackieControlProtocol& p)
_surface_combo.signal_changed().connect (sigc::mem_fun (*this, &MackieControlProtocolGUI::surface_combo_changed));
_cp.DeviceChanged.connect (device_change_connection, invalidator (*this), boost::bind (&MackieControlProtocolGUI::device_changed, this), gui_context());
+ _cp.ConnectionChange.connect (connection_change_connection, invalidator (*this), boost::bind (&MackieControlProtocolGUI::connection_handler, this), gui_context());
ipmidi_base_port_adjustment.signal_value_changed().connect (sigc::mem_fun (*this, &MackieControlProtocolGUI::ipmidi_spinner_changed));
@@ -240,6 +241,29 @@ MackieControlProtocolGUI::MackieControlProtocolGUI (MackieControlProtocol& p)
}
void
+MackieControlProtocolGUI::connection_handler ()
+{
+ vector<Gtk::ComboBoxText*>::iterator ic;
+ vector<Gtk::ComboBoxText*>::iterator oc;
+
+ vector<string> midi_inputs;
+ vector<string> midi_outputs;
+
+ ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsOutput|ARDOUR::IsPhysical), midi_inputs);
+ ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsInput|ARDOUR::IsPhysical), midi_outputs);
+
+
+ for (ic = input_combos.begin(), oc = output_combos.begin(); ic != input_combos.end() && oc != output_combos.end(); ++ic, ++oc) {
+
+ boost::shared_ptr<Surface> surface = _cp.get_surface_by_raw_pointer ((*ic)->get_data ("surface"));
+
+ if (surface) {
+ update_port_combos (midi_inputs, midi_outputs, *ic, *oc, surface);
+ }
+ }
+}
+
+void
MackieControlProtocolGUI::update_port_combos (vector<string> const& midi_inputs, vector<string> const& midi_outputs,
Gtk::ComboBoxText* input_combo,
Gtk::ComboBoxText* output_combo,
@@ -827,47 +851,3 @@ MackieControlProtocolGUI::touch_sensitive_change ()
int sensitivity = (int) touch_sensitivity_adjustment.get_value ();
_cp.set_touch_sensitivity (sensitivity);
}
-
-void
-MackieControlProtocolGUI::surface_connectivity_change (Surface* raw_surface)
-{
- boost::shared_ptr<Surface> surface;
-
- for (MackieControlProtocol::Surfaces::iterator s = _cp.surfaces.begin(); s != _cp.surfaces.end(); ++s) {
- if ((*s).get() == raw_surface) {
- surface = *s;
- break;
- }
- }
-
- if (!surface) {
- return;
- }
-
- Gtk::ComboBoxText* input_combo = 0;
- Gtk::ComboBoxText* output_combo = 0;
-
- for (vector<Gtk::ComboBoxText*>::iterator c = input_combos.begin(); c != input_combos.end(); ++c) {
- if ((*c)->get_data ("surface") == raw_surface) {
- input_combo = *c;
- }
- }
-
- for (vector<Gtk::ComboBoxText*>::iterator c = output_combos.begin(); c != output_combos.end(); ++c) {
- if ((*c)->get_data ("surface") == raw_surface) {
- output_combo = *c;
- }
- }
-
- if (!input_combo || !output_combo) {
- return;
- }
-
- vector<string> midi_inputs;
- vector<string> midi_outputs;
-
- ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsOutput|ARDOUR::IsPhysical), midi_inputs);
- ARDOUR::AudioEngine::instance()->get_ports ("", ARDOUR::DataType::MIDI, ARDOUR::PortFlags (ARDOUR::IsInput|ARDOUR::IsPhysical), midi_outputs);
-
- update_port_combos (midi_inputs, midi_outputs, input_combo, output_combo, surface);
-}
diff --git a/libs/surfaces/mackie/gui.h b/libs/surfaces/mackie/gui.h
index 8421068fd8..b2df91ed7a 100644
--- a/libs/surfaces/mackie/gui.h
+++ b/libs/surfaces/mackie/gui.h
@@ -135,11 +135,8 @@ class MackieControlProtocolGUI : public Gtk::Notebook
Gtk::ComboBoxText* output_combo,
boost::shared_ptr<Mackie::Surface> surface);
- /* this takes a raw pointer to Surface, because it connects to a signal
- emitted by a Surface and we don't want to use
- boost::shared_from_this.
- */
- void surface_connectivity_change (Mackie::Surface* raw_surface);
+ PBD::ScopedConnection connection_change_connection;
+ void connection_handler ();
};
}
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index 6f942445f8..0334431d81 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -400,11 +400,11 @@ MackieControlProtocol::set_active (bool yn)
BaseUI::run ();
- if (create_surfaces ()) {
- return -1;
- }
connect_session_signals ();
- update_surfaces ();
+
+ if (!_device_info.name().empty()) {
+ set_device (_device_info.name(), true);
+ }
/* set up periodic task for metering and automation
*/
@@ -534,6 +534,10 @@ MackieControlProtocol::update_global_button (int id, LedState ls)
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
+ if (surfaces.empty()) {
+ return;
+ }
+
if (!_device_info.has_global_controls()) {
return;
}
@@ -554,6 +558,10 @@ MackieControlProtocol::update_global_led (int id, LedState ls)
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
+ if (surfaces.empty()) {
+ return;
+ }
+
if (!_device_info.has_global_controls()) {
return;
}
@@ -688,6 +696,8 @@ MackieControlProtocol::set_device_info (const string& device_name)
int
MackieControlProtocol::set_device (const string& device_name, bool force)
{
+ cerr << "Set Device\n\n\n\n\n\n";
+
if (device_name == device_info().name() && !force) {
/* already using that device, nothing to do */
return 0;
@@ -708,15 +718,17 @@ MackieControlProtocol::set_device (const string& device_name, bool force)
hui_timeout->attach (main_loop()->get_context());
}
- if (create_surfaces ()) {
- return -1;
- }
-
if (!_device_info.uses_ipmidi()) {
+ /* notice that the handler for this will execute in our event
+ loop, not in the thread where the
+ PortConnectedOrDisconnected signal is emitted.
+ */
ARDOUR::AudioEngine::instance()->PortConnectedOrDisconnected.connect (port_connection, MISSING_INVALIDATOR, boost::bind (&MackieControlProtocol::connection_handler, this, _1, _2, _3, _4, _5), this);
}
- switch_banks (0, true);
+ if (create_surfaces ()) {
+ return -1;
+ }
DeviceChanged ();
@@ -735,18 +747,17 @@ MackieControlProtocol::create_surfaces ()
{
string device_name;
surface_type_t stype = mcu; // type not yet determined
- char buf[128];
-
- if (_device_info.extenders() == 0) {
- device_name = X_("mackie control");
- } else {
- device_name = X_("mackie control #1");
- }
- DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Create %1 surfaces\n", 1 + _device_info.extenders()));
+ DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Create %1 surfaces for %2\n", 1 + _device_info.extenders(), _device_info.name()));
for (uint32_t n = 0; n < 1 + _device_info.extenders(); ++n) {
+ if (n == 0) {
+ device_name = _device_info.name();
+ } else {
+ device_name = string_compose ("%1 #%2", _device_info.name(), n+1);
+ }
+
boost::shared_ptr<Surface> surface;
if (n == _device_info.master_position()) {
@@ -765,6 +776,7 @@ MackieControlProtocol::create_surfaces ()
}
if (_surfaces_state) {
+ cerr << "Resetting surface state\n";
surface->set_state (*_surfaces_state, _surfaces_version);
}
@@ -773,13 +785,6 @@ MackieControlProtocol::create_surfaces ()
surfaces.push_back (surface);
}
- if (_device_info.extenders() < 2) {
- device_name = X_("mackie control #2");
- } else {
- snprintf (buf, sizeof (buf), X_("mackie control #%d"), n+2);
- device_name = buf;
- }
-
if (!_device_info.uses_ipmidi()) {
_input_bundle.reset (new ARDOUR::Bundle (_("Mackie Control In"), true));
@@ -857,6 +862,7 @@ MackieControlProtocol::create_surfaces ()
void
MackieControlProtocol::close()
{
+ port_connection.disconnect ();
session_connections.drop_connections ();
route_connections.drop_connections ();
periodic_connection.disconnect ();
@@ -1050,6 +1056,14 @@ void MackieControlProtocol::notify_parameter_changed (std::string const & p)
void
MackieControlProtocol::notify_route_added (ARDOUR::RouteList & rl)
{
+ {
+ Glib::Threads::Mutex::Lock lm (surfaces_lock);
+
+ if (surfaces.empty()) {
+ return;
+ }
+ }
+
// currently assigned banks are less than the full set of
// strips, so activate the new strip now.
@@ -1072,6 +1086,11 @@ MackieControlProtocol::notify_solo_active_changed (bool active)
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
+
+ if (surfaces.empty()) {
+ return;
+ }
+
surface = _master_surface;
}
@@ -1087,6 +1106,14 @@ MackieControlProtocol::notify_solo_active_changed (bool active)
void
MackieControlProtocol::notify_remote_id_changed()
{
+ {
+ Glib::Threads::Mutex::Lock lm (surfaces_lock);
+
+ if (surfaces.empty()) {
+ return;
+ }
+ }
+
Sorted sorted = get_sorted_routes();
uint32_t sz = n_strips();
@@ -1150,6 +1177,9 @@ MackieControlProtocol::notify_record_state_changed ()
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
+ if (surfaces.empty()) {
+ return;
+ }
surface = _master_surface;
}
@@ -1771,7 +1801,6 @@ MackieControlProtocol::ipmidi_restart ()
void
MackieControlProtocol::clear_surfaces ()
{
- port_connection.disconnect ();
clear_ports ();
{
@@ -1815,6 +1844,20 @@ MackieControlProtocol::toggle_backlight ()
}
boost::shared_ptr<Surface>
+MackieControlProtocol::get_surface_by_raw_pointer (void* ptr) const
+{
+ Glib::Threads::Mutex::Lock lm (surfaces_lock);
+
+ for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
+ if ((*s).get() == (Surface*) ptr) {
+ return *s;
+ }
+ }
+
+ return boost::shared_ptr<Surface> ();
+}
+
+boost::shared_ptr<Surface>
MackieControlProtocol::nth_surface (uint32_t n) const
{
Glib::Threads::Mutex::Lock lm (surfaces_lock);
@@ -1831,11 +1874,14 @@ MackieControlProtocol::nth_surface (uint32_t n) const
void
MackieControlProtocol::connection_handler (boost::weak_ptr<ARDOUR::Port> wp1, std::string name1, boost::weak_ptr<ARDOUR::Port> wp2, std::string name2, bool yn)
{
- Glib::Threads::Mutex::Lock lm (surfaces_lock);
+ Surfaces scopy;
+ {
+ Glib::Threads::Mutex::Lock lm (surfaces_lock);
+ scopy = surfaces;
+ }
- for (Surfaces::const_iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
+ for (Surfaces::const_iterator s = scopy.begin(); s != scopy.end(); ++s) {
if ((*s)->connection_handler (wp1, name1, wp2, name2, yn)) {
- cerr << (*s)->name() << " Connected, or disconnected\n";
ConnectionChange (*s);
break;
}
diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h
index 14beb707f4..091fa3898f 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.h
+++ b/libs/surfaces/mackie/mackie_control_protocol.h
@@ -166,6 +166,7 @@ class MackieControlProtocol
typedef std::list<boost::shared_ptr<Mackie::Surface> > Surfaces;
Surfaces surfaces;
+ boost::shared_ptr<Mackie::Surface> get_surface_by_raw_pointer (void*) const;
boost::shared_ptr<Mackie::Surface> nth_surface (uint32_t) const;
std::list<boost::shared_ptr<ARDOUR::Bundle> > bundles ();
diff --git a/libs/surfaces/mackie/strip.cc b/libs/surfaces/mackie/strip.cc
index dad5eb098a..a2eb2843fd 100644
--- a/libs/surfaces/mackie/strip.cc
+++ b/libs/surfaces/mackie/strip.cc
@@ -200,7 +200,6 @@ Strip::set_route (boost::shared_ptr<Route> r, bool /*with_messages*/)
_pan_mode = PanAzimuthAutomation;
potmode_changed (true);
-
_route->solo_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_solo_changed, this), ui_context());
_route->listen_changed.connect (route_connections, MISSING_INVALIDATOR, boost::bind (&Strip::notify_solo_changed, this), ui_context());
@@ -368,7 +367,14 @@ Strip::notify_trim_changed (bool force_update)
_surface->write (_vpot->zero());
return;
}
- Control* control = control_by_parameter[TrimAutomation];
+ Control* control = 0;
+ ControlParameterMap::iterator i = control_by_parameter.find (TrimAutomation);
+
+ if (i == control_by_parameter.end()) {
+ return;
+ }
+
+ control = i->second;
boost::shared_ptr<AutomationControl> ac = _route->trim_control();
@@ -432,12 +438,15 @@ Strip::notify_panner_azi_changed (bool force_update)
return;
}
- Control* control = control_by_parameter[PanAzimuthAutomation];
+ Control* control = 0;
+ ControlParameterMap::iterator i = control_by_parameter.find (PanAzimuthAutomation);
- if (!control) {
+ if (i == control_by_parameter.end()) {
return;
}
+ control = i->second;
+
double pos = pannable->pan_azimuth_control->internal_to_interface (pannable->pan_azimuth_control->get_value());
if (force_update || pos != _last_pan_azi_position_written) {
@@ -472,13 +481,15 @@ Strip::notify_panner_width_changed (bool force_update)
return;
}
+ Control* control = 0;
+ ControlParameterMap::iterator i = control_by_parameter.find (PanWidthAutomation);
- Control* control = control_by_parameter[PanWidthAutomation];
-
- if (!control) {
+ if (i == control_by_parameter.end()) {
return;
}
+ control = i->second;
+
double pos = pannable->pan_width_control->internal_to_interface (pannable->pan_width_control->get_value());
if (force_update || pos != _last_pan_azi_position_written) {
@@ -1007,22 +1018,23 @@ Strip::potmode_changed (bool notify)
// WIP
int pm = _surface->mcp().pot_mode();
switch (pm) {
- case MackieControlProtocol::Pan:
- // This needs to set current pan mode (azimuth or width... or whatever)
- set_vpot_parameter (_pan_mode);
- DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Pan mode.\n");
- break;
- case MackieControlProtocol::Tracks: // should change the Tracks to Trim
- DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Trim mode.\n");
+ case MackieControlProtocol::Pan:
+ // This needs to set current pan mode (azimuth or width... or whatever)
+ set_vpot_parameter (_pan_mode);
+ DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Pan mode.\n");
+ break;
+ case MackieControlProtocol::Tracks: // should change the Tracks to Trim
+ DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Trim mode.\n");
set_vpot_parameter (TrimAutomation);
break;
- case MackieControlProtocol::Send:
- DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Send mode.\n");
- // set to current send
- break;
- default:
- break;
- }
+ case MackieControlProtocol::Send:
+ DEBUG_TRACE (DEBUG::MackieControl, "Assign pot to Send mode.\n");
+ // set to current send
+ break;
+ default:
+ cerr << "Pot mode " << pm << " not yet handled\n";
+ break;
+ }
if (notify) {
notify_all ();
@@ -1133,9 +1145,13 @@ Strip::set_vpot_parameter (Evoral::Parameter p)
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("switch to vpot mode %1\n", p));
reset_saved_values ();
- for (int i = 0; i <= TrimAutomation; ++i) {
- if (control_by_parameter[i] == _vpot) {
- control_by_parameter[i] = 0;
+
+ /* unset any mapping between the vpot and any existing parameters */
+
+ for (ControlParameterMap::iterator i = control_by_parameter.begin(); i != control_by_parameter.end(); ++i) {
+
+ if (i != control_by_parameter.end() && i->second == _vpot) {
+ i->second = 0;
}
}
diff --git a/libs/surfaces/mackie/strip.h b/libs/surfaces/mackie/strip.h
index e06eccf25f..f0c972aa73 100644
--- a/libs/surfaces/mackie/strip.h
+++ b/libs/surfaces/mackie/strip.h
@@ -155,7 +155,8 @@ private:
void reset_saved_values ();
- std::map<Evoral::Parameter,Control*> control_by_parameter;
+ typedef std::map<Evoral::Parameter,Control*> ControlParameterMap;
+ ControlParameterMap control_by_parameter;
};
}
diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc
index 7709ebb264..3b42aa1e8f 100644
--- a/libs/surfaces/mackie/surface.cc
+++ b/libs/surfaces/mackie/surface.cc
@@ -37,6 +37,8 @@
#include "ardour/session.h"
#include "ardour/utils.h"
+#include <gtkmm2ext/gui_thread.h>
+
#include "control_group.h"
#include "surface_port.h"
#include "surface.h"
@@ -221,6 +223,13 @@ Surface::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, b
to queue it with the MCP event loop.
*/
+ /* XXX this is a horrible hack. Without a short sleep here,
+ something prevents the device wakeup messages from being
+ sent and/or the responses from being received.
+ */
+
+ g_usleep (100000);
+
connected ();
} else {
@@ -662,9 +671,7 @@ Surface::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count
write_sysex (host_connection_query (bytes));
} else {
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Mackie Control Device ready, current status = %1\n", _active));
- if (!_active) {
- turn_it_on ();
- }
+ turn_it_on ();
}
break;
@@ -672,7 +679,7 @@ Surface::handle_midi_sysex (MIDI::Parser &, MIDI::byte * raw_bytes, size_t count
DEBUG_TRACE (DEBUG::MackieControl, "Logic Control Device confirms connection, ardour replies\n");
if (bytes[4] == 0x10 || bytes[4] == 0x11) {
write_sysex (host_connection_confirmation (bytes));
- _active = true;
+ turn_it_on ();
}
break;
diff --git a/libs/surfaces/mackie/surface.h b/libs/surfaces/mackie/surface.h
index c0a2cff871..166b8ed4bf 100644
--- a/libs/surfaces/mackie/surface.h
+++ b/libs/surfaces/mackie/surface.h
@@ -3,6 +3,8 @@
#include <stdint.h>
+#include <sigc++/trackable.h>
+
#include "pbd/signals.h"
#include "pbd/xml++.h"
#include "midi++/types.h"
@@ -43,7 +45,7 @@ class Jog;
class Pot;
class Led;
-class Surface : public PBD::ScopedConnectionList
+class Surface : public PBD::ScopedConnectionList, public sigc::trackable
{
public:
Surface (MackieControlProtocol&, const std::string& name, uint32_t number, surface_type_t stype);