X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fport.cc;h=81290aa021187d3a4d7b62ee51e9f46223a43edb;hb=9775c5c9f1b81340f3177ede038f02faed71c887;hp=d375550d9e40570cc058c560e11923e301be99fb;hpb=22b07e0233a29d9633ffa825a79503befaf2e16e;p=ardour.git diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc index d375550d9e..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,6 +140,26 @@ 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 @@ -128,13 +175,21 @@ 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() ... */ 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; @@ -217,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); @@ -455,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; } @@ -511,12 +569,12 @@ 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; @@ -525,7 +583,7 @@ Port::get_state () const 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); } @@ -535,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,11 +612,11 @@ Port::set_state (const XMLNode& node, int) 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;