X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fport.cc;h=81290aa021187d3a4d7b62ee51e9f46223a43edb;hb=7613c9cb34a6f9a27225c6251f7755723272136f;hp=70c6a604d76b6ac33aef031cc70854fc61fea5cb;hpb=3c3d62c18a88c9a3ce8ae4d5f7a44470d302a1bf;p=ardour.git diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc index 70c6a604d7..81290aa021 100644 --- a/libs/ardour/port.cc +++ b/libs/ardour/port.cc @@ -30,7 +30,7 @@ #include "ardour/port.h" #include "ardour/port_engine.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace std; using namespace ARDOUR; @@ -38,6 +38,7 @@ using namespace PBD; PBD::Signal2, boost::shared_ptr > Port::PostDisconnect; PBD::Signal0 Port::PortDrop; +PBD::Signal0 Port::PortSignalDrop; bool Port::_connecting_blocked = false; pframes_t Port::_global_port_buffer_offset = 0; @@ -55,7 +56,7 @@ Port::Port (std::string const & n, DataType t, PortFlags f) : _port_buffer_offset (0) , _name (n) , _flags (f) - , _last_monitor (false) + , _last_monitor (false) { _private_playback_latency.min = 0; _private_playback_latency.max = 0; @@ -69,12 +70,19 @@ Port::Port (std::string const & n, DataType t, PortFlags f) assert (_name.find_first_of (':') == std::string::npos); - if ((_port_handle = port_engine.register_port (_name, t, _flags)) == 0) { + if (!port_engine.available ()) { + DEBUG_TRACE (DEBUG::Ports, string_compose ("port-engine n/a postpone registering %1\n", name())); + _port_handle = 0; // created during ::reestablish() later + } else if ((_port_handle = port_engine.register_port (_name, t, _flags)) == 0) { cerr << "Failed to register port \"" << _name << "\", reason is unknown from here\n"; throw failed_constructor (); } - + DEBUG_TRACE (DEBUG::Ports, string_compose ("registed port %1 handle %2\n", name(), _port_handle)); + PortDrop.connect_same_thread (drop_connection, boost::bind (&Port::drop, this)); + PortSignalDrop.connect_same_thread (drop_connection, boost::bind (&Port::signal_drop, this)); + port_manager->PortConnectedOrDisconnected.connect_same_thread (engine_connection, + boost::bind (&Port::port_connected_or_disconnected, this, _1, _3, _5)); } /** Port destructor */ @@ -103,6 +111,25 @@ Port::pretty_name(bool fallback_to_name) const return ""; } +bool +Port::set_pretty_name(const std::string& n) +{ + if (_port_handle) { + if (0 == port_engine.set_port_property (_port_handle, + "http://jackaudio.org/metadata/pretty-name", n, "")) + { + return true; + } + } + return false; +} + +void +Port::signal_drop () +{ + engine_connection.disconnect (); +} + void Port::drop () { @@ -113,13 +140,33 @@ Port::drop () } } +void +Port::port_connected_or_disconnected (boost::weak_ptr w0, boost::weak_ptr w1, bool con) +{ + if (con) { + /* we're only interested in disconnect */ + return; + } + boost::shared_ptr p0 = w0.lock (); + boost::shared_ptr p1 = w1.lock (); + /* a cheaper, less hacky way to do boost::shared_from_this() ... */ + boost::shared_ptr pself = AudioEngine::instance()->get_port_by_name (name()); + + if (p0 == pself) { + PostDisconnect (p0, p1); // emit signal + } + if (p1 == pself) { + PostDisconnect (p1, p0); // emit signal + } +} + /** @return true if this port is connected to anything */ bool Port::connected () const { if (_port_handle) { return (port_engine.connected (_port_handle) != 0); - } + } return false; } @@ -127,14 +174,22 @@ int Port::disconnect_all () { if (_port_handle) { - + + std::vector connections; + get_connections (connections); + port_engine.disconnect_all (_port_handle); _connections.clear (); - - /* a cheaper, less hacky way to do boost::shared_from_this() ... + + /* a cheaper, less hacky way to do boost::shared_from_this() ... */ boost::shared_ptr pself = port_manager->get_port_by_name (name()); - PostDisconnect (pself, boost::shared_ptr()); // emit signal + for (vector::const_iterator c = connections.begin(); c != connections.end() && pself; ++c) { + boost::shared_ptr pother = AudioEngine::instance()->get_port_by_name (*c); + if (pother) { + PostDisconnect (pself, pother); // emit signal + } + } } return 0; @@ -147,7 +202,7 @@ bool Port::connected_to (std::string const & o) const { if (!_port_handle) { - return false; + return false; } if (!port_engine.available()) { @@ -167,7 +222,6 @@ Port::get_connections (std::vector & c) const if (_port_handle) { return port_engine.get_connections (_port_handle, c); - return c.size(); } return 0; @@ -218,8 +272,7 @@ Port::disconnect (std::string const & other) _connections.erase (other); } - /* a cheaper, less hacky way to do boost::shared_from_this() ... - */ + /* a cheaper, less hacky way to do boost::shared_from_this() ... */ boost::shared_ptr pself = AudioEngine::instance()->get_port_by_name (name()); boost::shared_ptr pother = AudioEngine::instance()->get_port_by_name (other); @@ -228,7 +281,7 @@ Port::disconnect (std::string const & other) a check on whether this may affect anything that we need to know about. */ - PostDisconnect (pself, pother); // emit signal + PostDisconnect (pself, pother); // emit signal } return r; @@ -366,7 +419,7 @@ Port::public_latency_range (bool /*playback*/) const if (_port_handle) { r = port_engine.get_latency_range (_port_handle, sends_output() ? true : false); - + DEBUG_TRACE (DEBUG::Latency, string_compose ( "GET PORT %1: %4 PUBLIC latency range %2 .. %3\n", name(), r.min, r.max, @@ -456,8 +509,12 @@ Port::reestablish () return -1; } + DEBUG_TRACE (DEBUG::Ports, string_compose ("Port::reestablish %1 handle %2\n", name(), _port_handle)); + reset (); + port_manager->PortConnectedOrDisconnected.connect_same_thread (engine_connection, + boost::bind (&Port::port_connected_or_disconnected, this, _1, _3, _5)); return 0; } @@ -512,21 +569,21 @@ Port::get_state () const { XMLNode* root = new XMLNode (state_node_name); - root->add_property (X_("name"), AudioEngine::instance()->make_port_name_relative (name())); + root->set_property (X_("name"), AudioEngine::instance()->make_port_name_relative (name())); if (receives_input()) { - root->add_property (X_("direction"), X_("input")); + root->set_property (X_("direction"), X_("input")); } else { - root->add_property (X_("direction"), X_("output")); + root->set_property (X_("direction"), X_("output")); } vector c; - + get_connections (c); for (vector::const_iterator i = c.begin(); i != c.end(); ++i) { XMLNode* child = new XMLNode (X_("Connection")); - child->add_property (X_("other"), *i); + child->set_property (X_("other"), *i); root->add_child_nocopy (*child); } @@ -536,14 +593,13 @@ Port::get_state () const int Port::set_state (const XMLNode& node, int) { - const XMLProperty* prop; - if (node.name() != state_node_name) { return -1; } - if ((prop = node.property (X_("name"))) != 0) { - set_name (prop->value()); + std::string str; + if (node.get_property (X_("name"), str)) { + set_name (str); } const XMLNodeList& children (node.children()); @@ -555,12 +611,12 @@ Port::set_state (const XMLNode& node, int) if ((*c)->name() != X_("Connection")) { continue; } - - if ((prop = (*c)->property (X_("other"))) == 0) { + + if (!(*c)->get_property (X_("other"), str)) { continue; } - _connections.insert (prop->value()); + _connections.insert (str); } return 0;