diff options
-rw-r--r-- | libs/surfaces/mackie/mackie_control_protocol.cc | 108 | ||||
-rw-r--r-- | libs/surfaces/mackie/mackie_control_protocol.h | 1 | ||||
-rw-r--r-- | libs/surfaces/mackie/surface.cc | 25 | ||||
-rw-r--r-- | libs/surfaces/mackie/surface_port.cc | 51 | ||||
-rw-r--r-- | libs/surfaces/mackie/surface_port.h | 2 |
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); |