summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.cc108
-rw-r--r--libs/surfaces/mackie/mackie_control_protocol.h1
-rw-r--r--libs/surfaces/mackie/surface.cc25
-rw-r--r--libs/surfaces/mackie/surface_port.cc51
-rw-r--r--libs/surfaces/mackie/surface_port.h2
5 files changed, 138 insertions, 49 deletions
diff --git a/libs/surfaces/mackie/mackie_control_protocol.cc b/libs/surfaces/mackie/mackie_control_protocol.cc
index 1222dc5707..6f81b57c59 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.cc
+++ b/libs/surfaces/mackie/mackie_control_protocol.cc
@@ -696,15 +696,29 @@ 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;
}
+ /* get state from the current setup, and make sure it is stored in
+ the _surface_states node so that if we switch back to this device,
+ we will have its state available.
+ */
+
+ if (!_surfaces_state) {
+ _surfaces_state = new XMLNode (X_("Surfaces"));
+ }
+
+ {
+ Glib::Threads::Mutex::Lock lm (surfaces_lock);
+
+ for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
+ update_surface_state (*s);
+ }
+ }
+
if (set_device_info (device_name)) {
- cerr << "Unknown device name\n";
return -1;
}
@@ -750,12 +764,40 @@ MackieControlProtocol::create_surfaces ()
DEBUG_TRACE (DEBUG::MackieControl, string_compose ("Create %1 surfaces for %2\n", 1 + _device_info.extenders(), _device_info.name()));
+ if (!_device_info.uses_ipmidi()) {
+ _input_bundle.reset (new ARDOUR::Bundle (_("Mackie Control In"), true));
+ _output_bundle.reset (new ARDOUR::Bundle (_("Mackie Control Out"), false));
+ } else {
+ _input_bundle.reset ();
+ _output_bundle.reset ();
+
+ }
for (uint32_t n = 0; n < 1 + _device_info.extenders(); ++n) {
+ bool is_master = false;
+
+ if (_device_info.master_position() == 0) {
+ /* unspecified master position, use first surface */
+ if (n == 0) {
+ is_master = true;
+ if (_device_info.extenders() == 0) {
+ device_name = _device_info.name();
+ } else {
+ device_name = X_("mackie control");
+ }
+ }
+ } else if ((n+1) == _device_info.master_position()) {
+ /* specified master position, uses 1-based counting for user interaction */
+ is_master = true;
+ if (_device_info.extenders() == 0) {
+ device_name = _device_info.name();
+ } else {
+ device_name = X_("mackie control");
+ }
- if (n == 0) {
- device_name = _device_info.name();
- } else {
- device_name = string_compose ("%1 #%2", _device_info.name(), n+1);
+ }
+
+ if (!is_master) {
+ device_name = string_compose (X_("mackie control ext %1"), n+1);
}
boost::shared_ptr<Surface> surface;
@@ -771,12 +813,11 @@ MackieControlProtocol::create_surfaces ()
return -1;
}
- if (n == _device_info.master_position()) {
+ if (is_master) {
_master_surface = surface;
}
if (_surfaces_state) {
- cerr << "Resetting surface state\n";
surface->set_state (*_surfaces_state, _surfaces_version);
}
@@ -787,9 +828,6 @@ MackieControlProtocol::create_surfaces ()
if (!_device_info.uses_ipmidi()) {
- _input_bundle.reset (new ARDOUR::Bundle (_("Mackie Control In"), true));
- _output_bundle.reset (new ARDOUR::Bundle (_("Mackie Control Out"), false));
-
_input_bundle->add_channel (
surface->port().input_port().name(),
ARDOUR::DataType::MIDI,
@@ -801,14 +839,6 @@ MackieControlProtocol::create_surfaces ()
ARDOUR::DataType::MIDI,
session->engine().make_port_name_non_relative (surface->port().output_port().name())
);
-
- session->BundleAddedOrRemoved ();
-
- } else {
- _input_bundle.reset ((ARDOUR::Bundle*) 0);
- _output_bundle.reset ((ARDOUR::Bundle*) 0);
-
- session->BundleAddedOrRemoved ();
}
MIDI::Port& input_port (surface->port().input_port());
@@ -856,6 +886,17 @@ MackieControlProtocol::create_surfaces ()
}
}
+ if (!_device_info.uses_ipmidi()) {
+ Glib::Threads::Mutex::Lock lm (surfaces_lock);
+ for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
+ (*s)->port().reconnect ();
+ }
+ }
+
+ session->BundleAddedOrRemoved ();
+
+ assert (_master_surface);
+
return 0;
}
@@ -870,6 +911,18 @@ MackieControlProtocol::close()
clear_surfaces();
}
+/** Ensure that the _surfaces_state XML node contains an up-to-date
+ * copy of the state node for @param surface. If _surfaces_state already
+ * contains a state node for @param surface, it will deleted and replaced.
+ */
+void
+MackieControlProtocol::update_surface_state (boost::shared_ptr<Surface> surface)
+{
+ assert (_surfaces_state);
+ _surfaces_state->remove_nodes_and_delete (X_("name"), surface->name());
+ _surfaces_state->add_child_nocopy (surface->get_state());
+}
+
XMLNode&
MackieControlProtocol::get_state()
{
@@ -889,12 +942,19 @@ MackieControlProtocol::get_state()
node.add_property (X_("device-profile"), _device_profile.name());
node.add_property (X_("device-name"), _device_info.name());
- XMLNode* snode = new XMLNode (X_("Surfaces"));
- for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
- snode->add_child_nocopy ((*s)->get_state());
+ if (!_surfaces_state) {
+ _surfaces_state = new XMLNode (X_("Surfaces"));
+ }
+
+ {
+ Glib::Threads::Mutex::Lock lm (surfaces_lock);
+ for (Surfaces::iterator s = surfaces.begin(); s != surfaces.end(); ++s) {
+ update_surface_state (*s);
+ }
}
- node.add_child_nocopy (*snode);
+ /* force a copy of the _surfaces_state node, because we want to retain ownership */
+ node.add_child_copy (*_surfaces_state);
DEBUG_TRACE (DEBUG::MackieControl, "MackieControlProtocol::get_state done\n");
diff --git a/libs/surfaces/mackie/mackie_control_protocol.h b/libs/surfaces/mackie/mackie_control_protocol.h
index 091fa3898f..18069dc591 100644
--- a/libs/surfaces/mackie/mackie_control_protocol.h
+++ b/libs/surfaces/mackie/mackie_control_protocol.h
@@ -352,6 +352,7 @@ class MackieControlProtocol
int ipmidi_restart ();
void initialize ();
int set_device_info (const std::string& device_name);
+ void update_surface_state (boost::shared_ptr<Mackie::Surface>);
/* MIDI port connection management */
diff --git a/libs/surfaces/mackie/surface.cc b/libs/surfaces/mackie/surface.cc
index 3b42aa1e8f..005f1fadb2 100644
--- a/libs/surfaces/mackie/surface.cc
+++ b/libs/surfaces/mackie/surface.cc
@@ -229,7 +229,6 @@ Surface::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, b
*/
g_usleep (100000);
-
connected ();
} else {
@@ -243,21 +242,29 @@ Surface::connection_handler (boost::weak_ptr<ARDOUR::Port>, std::string name1, b
XMLNode&
Surface::get_state()
{
- char buf[64];
- snprintf (buf, sizeof (buf), X_("surface-%u"), _number);
- XMLNode* node = new XMLNode (buf);
-
+ XMLNode* node = new XMLNode (X_("Surface"));
+ node->add_property (X_("name"), _name);
node->add_child_nocopy (_port->get_state());
-
return *node;
}
int
Surface::set_state (const XMLNode& node, int version)
{
- char buf[64];
- snprintf (buf, sizeof (buf), X_("surface-%u"), _number);
- XMLNode* mynode = node.child (buf);
+ /* Look for a node named after this surface */
+
+ XMLNodeList const& children = node.children();
+ XMLNode* mynode = 0;
+
+ for (XMLNodeList::const_iterator c = children.begin(); c != children.end(); ++c) {
+ XMLProperty const* prop = (*c)->property (X_("name"));
+ if (prop) {
+ if (prop->value() == _name) {
+ mynode = *c;
+ break;
+ }
+ }
+ }
if (!mynode) {
return 0;
diff --git a/libs/surfaces/mackie/surface_port.cc b/libs/surfaces/mackie/surface_port.cc
index 50bb206cdf..6f243a5444 100644
--- a/libs/surfaces/mackie/surface_port.cc
+++ b/libs/surfaces/mackie/surface_port.cc
@@ -58,8 +58,24 @@ SurfacePort::SurfacePort (Surface& s)
} else {
- _async_in = AudioEngine::instance()->register_input_port (DataType::MIDI, string_compose (_("%1 in"), _surface->name()), true);
- _async_out = AudioEngine::instance()->register_output_port (DataType::MIDI, string_compose (_("%1 out"), _surface->name()), true);
+ string in_name;
+ string out_name;
+
+ if (_surface->mcp().device_info().extenders() > 0) {
+ if (_surface->number() + 1 == _surface->mcp().device_info().master_position()) {
+ in_name = X_("mackie control in");
+ out_name = X_("mackie control out");
+ } else {
+ in_name = string_compose (X_("mackie control in ext %1"), _surface->number());
+ out_name = string_compose (X_("mackie control out ext %1"), _surface->number());
+ }
+ } else {
+ in_name = X_("mackie control in");
+ out_name = X_("mackie control out");
+ }
+
+ _async_in = AudioEngine::instance()->register_input_port (DataType::MIDI, in_name, true);
+ _async_out = AudioEngine::instance()->register_output_port (DataType::MIDI, out_name, true);
if (_async_in == 0 || _async_out == 0) {
throw failed_constructor();
@@ -121,29 +137,33 @@ SurfacePort::set_state (const XMLNode& node, int version)
if (dynamic_cast<MIDI::IPMIDIPort*>(_input_port)) {
return 0;
}
- // the rest should not be run if the device-name changes outside of a session load.
- if ( _surface->mcp().session_load()) {
- XMLNode* child;
+ XMLNode* child;
- if ((child = node.child (X_("Input"))) != 0) {
- XMLNode* portnode = child->child (Port::state_node_name.c_str());
- if (portnode) {
- _async_in->set_state (*portnode, version);
- }
+ if ((child = node.child (X_("Input"))) != 0) {
+ XMLNode* portnode = child->child (Port::state_node_name.c_str());
+ if (portnode) {
+ _async_in->set_state (*portnode, version);
}
+ }
- if ((child = node.child (X_("Output"))) != 0) {
- XMLNode* portnode = child->child (Port::state_node_name.c_str());
- if (portnode) {
- _async_out->set_state (*portnode, version);
- }
+ if ((child = node.child (X_("Output"))) != 0) {
+ XMLNode* portnode = child->child (Port::state_node_name.c_str());
+ if (portnode) {
+ _async_out->set_state (*portnode, version);
}
}
return 0;
}
+void
+SurfacePort::reconnect ()
+{
+ _async_out->reconnect ();
+ _async_in->reconnect ();
+}
+
std::string
SurfacePort::input_name () const
{
@@ -211,4 +231,3 @@ Mackie::operator << (ostream & os, const SurfacePort & port)
os << " }";
return os;
}
-
diff --git a/libs/surfaces/mackie/surface_port.h b/libs/surfaces/mackie/surface_port.h
index 9795a8d5cd..bdc089985d 100644
--- a/libs/surfaces/mackie/surface_port.h
+++ b/libs/surfaces/mackie/surface_port.h
@@ -68,6 +68,8 @@ class SurfacePort
std::string input_name() const;
std::string output_name() const;
+ void reconnect ();
+
XMLNode& get_state ();
int set_state (const XMLNode&, int version);