diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2020-04-07 10:18:16 -0600 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2020-04-07 13:23:49 -0600 |
commit | b9cb306e8b9a330ec5211ccdfde6b90f17701099 (patch) | |
tree | 4e3e2d90fe9d0747a06e08c8bfd099fc275c07b4 /libs/ardour | |
parent | 1eb98316a3467c94842f6b6ba21eaf4470760880 (diff) |
use shared_ptr to manage backend port lifetimes (Pulse,ALSA,Dummy,JACK)
JACK is not yet finished.
Changes also include minor reformatting and a spelling correction (latecies to latencies)
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/audioengine.h | 4 | ||||
-rw-r--r-- | libs/ardour/ardour/port.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/port_engine.h | 26 | ||||
-rw-r--r-- | libs/ardour/ardour/port_engine_shared.h | 69 | ||||
-rw-r--r-- | libs/ardour/audioengine.cc | 2 | ||||
-rw-r--r-- | libs/ardour/disk_writer.cc | 5 | ||||
-rw-r--r-- | libs/ardour/port.cc | 2 | ||||
-rw-r--r-- | libs/ardour/port_engine_shared.cc | 235 |
8 files changed, 200 insertions, 145 deletions
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h index 3d08759787..70006fcf87 100644 --- a/libs/ardour/ardour/audioengine.h +++ b/libs/ardour/ardour/audioengine.h @@ -284,8 +284,8 @@ class LIBARDOUR_API AudioEngine : public PortManager, public SessionHandlePtr MTDM* _mtdm; MIDIDM* _mididm; LatencyMeasurement _measuring_latency; - PortEngine::PortHandle _latency_input_port; - PortEngine::PortHandle _latency_output_port; + PortEngine::PortPtr _latency_input_port; + PortEngine::PortPtr _latency_output_port; samplecnt_t _latency_flush_samples; std::string _latency_input_name; std::string _latency_output_name; diff --git a/libs/ardour/ardour/port.h b/libs/ardour/ardour/port.h index aa19ca85ed..781c970e2a 100644 --- a/libs/ardour/ardour/port.h +++ b/libs/ardour/ardour/port.h @@ -159,7 +159,7 @@ protected: Port (std::string const &, DataType, PortFlags); - PortEngine::PortHandle _port_handle; + PortEngine::PortPtr _port_handle; static bool _connecting_blocked; static pframes_t _cycle_nframes; /* access only from process() tree */ diff --git a/libs/ardour/ardour/port_engine.h b/libs/ardour/ardour/port_engine.h index 483206578a..056b70f31b 100644 --- a/libs/ardour/ardour/port_engine.h +++ b/libs/ardour/ardour/port_engine.h @@ -75,6 +75,12 @@ class PortManager; * documentation, on which this entire object is based. */ +class LIBARDOUR_API ProtoPort { + public: + ProtoPort() {} + virtual ~ProtoPort () {} +}; + class LIBARDOUR_API PortEngine { public: @@ -88,14 +94,24 @@ public: /** Opaque handle to use as reference for Ports * - * We use void* here so that the API can be defined for any implementation. + * The handle needs to be lifetime managed (i.e. a shared_ptr type) + * in order to allow RCU to provide lock-free cross-thread operations + * on ports and ports containers. * * We could theoretically use a template (PortEngine\<T\>) and define * PortHandle as T, but this complicates the desired inheritance * pattern in which FooPortEngine handles things for the Foo API, * rather than being a derivative of PortEngine\<Foo\>. + * + * We use this to declare return values and members of structures. + */ + typedef boost::shared_ptr<ProtoPort> PortPtr; + + /* We use this to declare arguments to methods/functions, in order to + * avoid copying shared_ptr<ProtoPort> every time (a practice we use in + * other contexts where we pass shared_ptr<T>). */ - typedef void* PortHandle; + typedef PortPtr const & PortHandle; /** Return the name of this process as used by the port manager * when naming ports. @@ -164,7 +180,7 @@ public: * @param name Full port-name to lookup * @return PortHandle if lookup was successful, or an "empty" PortHandle (analogous to a null pointer) if no such port exists. */ - virtual PortHandle get_port_by_name (const std::string& name) const = 0; + virtual PortPtr get_port_by_name (const std::string& name) const = 0; /** Find the set of ports whose names, types and flags match * specified values, place the names of each port into \p ports . @@ -194,7 +210,7 @@ public: * @param flags flags of the port to create * @return a reference to the port, otherwise return a null pointer. */ - virtual PortHandle register_port (const std::string& shortname, ARDOUR::DataType type, ARDOUR::PortFlags flags) = 0; + virtual PortPtr register_port (const std::string& shortname, ARDOUR::DataType type, ARDOUR::PortFlags flags) = 0; /* Destroy the port referred to by \p port, including all resources * associated with it. This will also disconnect \p port from any ports it @@ -202,7 +218,7 @@ public: * * @param port \ref PortHandle of the port to destroy */ - virtual void unregister_port (PortHandle port) = 0; + virtual void unregister_port (PortHandle port) = 0; /* Connection management */ diff --git a/libs/ardour/ardour/port_engine_shared.h b/libs/ardour/ardour/port_engine_shared.h index 7997cb9e9d..bb95277346 100644 --- a/libs/ardour/ardour/port_engine_shared.h +++ b/libs/ardour/ardour/port_engine_shared.h @@ -39,25 +39,28 @@ namespace ARDOUR { class PortEngineSharedImpl; class PortManager; -class LIBARDOUR_API BackendPort +class BackendPort; + +typedef boost::shared_ptr<BackendPort> BackendPortPtr; +typedef boost::shared_ptr<BackendPort> const & BackendPortHandle; + +class LIBARDOUR_API BackendPort : public ProtoPort { -protected: + protected: BackendPort (PortEngineSharedImpl& b, const std::string&, PortFlags); -public: + public: virtual ~BackendPort (); const std::string& name () const { return _name; } const std::string& pretty_name () const { return _pretty_name; } - int set_name (const std::string& name) - { + int set_name (const std::string& name) { _name = name; return 0; } - int set_pretty_name (const std::string& name) - { + int set_pretty_name (const std::string& name) { _pretty_name = name; return 0; } @@ -71,17 +74,16 @@ public: bool is_terminal () const { return flags () & IsTerminal; } bool is_connected () const { return _connections.size () != 0; } - bool is_connected (const BackendPort* port) const; + bool is_connected (BackendPortHandle port) const; bool is_physically_connected () const; - const std::set<BackendPort*>& get_connections () const - { + const std::set<BackendPortPtr>& get_connections () const { return _connections; } - int connect (BackendPort* port); - int disconnect (BackendPort* port); - void disconnect_all (); + int connect (BackendPortHandle port, BackendPortHandle self); + int disconnect (BackendPortHandle port, BackendPortHandle self); + void disconnect_all (BackendPortHandle self); virtual void* get_buffer (pframes_t nframes) = 0; @@ -103,10 +105,10 @@ private: const PortFlags _flags; LatencyRange _capture_latency_range; LatencyRange _playback_latency_range; - std::set<BackendPort*> _connections; + std::set<BackendPortPtr> _connections; - void _connect (BackendPort*, bool); - void _disconnect (BackendPort*, bool); + void store_connection (BackendPortHandle); + void remove_connection (BackendPortHandle); }; // class BackendPort @@ -129,7 +131,7 @@ public: int set_port_name (PortEngine::PortHandle, const std::string&); std::string get_port_name (PortEngine::PortHandle) const; PortFlags get_port_flags (PortEngine::PortHandle) const; - PortEngine::PortHandle get_port_by_name (const std::string&) const; + PortEngine::PortPtr get_port_by_name (const std::string&) const; int get_port_property (PortEngine::PortHandle, const std::string& key, std::string& value, std::string& type) const; int set_port_property (PortEngine::PortHandle, const std::string& key, const std::string& value, const std::string& type); @@ -138,8 +140,8 @@ public: DataType port_data_type (PortEngine::PortHandle) const; - PortEngine::PortHandle register_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags); - virtual void unregister_port (PortEngine::PortHandle); + PortEngine::PortPtr register_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags); + virtual void unregister_port (PortEngine::PortHandle); int connect (const std::string& src, const std::string& dst); int disconnect (const std::string& src, const std::string& dst); @@ -158,36 +160,35 @@ public: protected: std::string _instance_name; - std::vector<BackendPort*> _system_inputs; - std::vector<BackendPort*> _system_outputs; - std::vector<BackendPort*> _system_midi_in; - std::vector<BackendPort*> _system_midi_out; + std::vector<BackendPortPtr> _system_inputs; + std::vector<BackendPortPtr> _system_outputs; + std::vector<BackendPortPtr> _system_midi_in; + std::vector<BackendPortPtr> _system_midi_out; + + virtual void update_system_port_latencies (); void clear_ports (); - PortEngine::PortHandle add_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags); - void unregister_ports (bool system_only = false); + BackendPortPtr add_port (const std::string& shortname, ARDOUR::DataType, ARDOUR::PortFlags); + void unregister_ports (bool system_only = false); struct SortByPortName { - bool operator() (const BackendPort* lhs, const BackendPort* rhs) const - { + bool operator() (BackendPortHandle lhs, BackendPortHandle rhs) const { return PBD::naturally_less (lhs->name ().c_str (), rhs->name ().c_str ()); } }; - typedef std::map<std::string, BackendPort*> PortMap; // fast lookup in _ports - typedef std::set<BackendPort*, SortByPortName> PortIndex; // fast lookup in _ports + typedef std::map<std::string, BackendPortPtr> PortMap; // fast lookup in _ports + typedef std::set<BackendPortPtr, SortByPortName> PortIndex; // fast lookup in _ports SerializedRCUManager<PortMap> _portmap; SerializedRCUManager<PortIndex> _ports; - bool valid_port (PortEngine::PortHandle port) const - { + bool valid_port (BackendPortHandle port) const { boost::shared_ptr<PortIndex> p = _ports.reader (); - return std::find (p->begin (), p->end (), static_cast<BackendPort*> (port)) != p->end (); + return std::find (p->begin (), p->end (), port) != p->end (); } - BackendPort* find_port (const std::string& port_name) const - { + BackendPortPtr find_port (const std::string& port_name) const { boost::shared_ptr<PortMap> p = _portmap.reader (); PortMap::const_iterator it = p->find (port_name); if (it == p->end ()) { diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index a4ee9dc587..51c5fbb9bb 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -92,8 +92,6 @@ AudioEngine::AudioEngine () , _mtdm (0) , _mididm (0) , _measuring_latency (MeasureNone) - , _latency_input_port (0) - , _latency_output_port (0) , _latency_flush_samples (0) , _latency_signal_latency (0) , _stopped_for_latency (false) diff --git a/libs/ardour/disk_writer.cc b/libs/ardour/disk_writer.cc index bb19bc3c57..d61d0f23f7 100644 --- a/libs/ardour/disk_writer.cc +++ b/libs/ardour/disk_writer.cc @@ -826,11 +826,8 @@ DiskWriter::do_flush (RunContext ctxt, bool force_flush) uint32_t to_write; int32_t ret = 0; RingBufferNPT<Sample>::rw_vector vector; - RingBufferNPT<CaptureTransition>::rw_vector transvec; samplecnt_t total; - transvec.buf[0] = 0; - transvec.buf[1] = 0; vector.buf[0] = 0; vector.buf[1] = 0; @@ -1205,8 +1202,6 @@ DiskWriter::transport_stopped_wallclock (struct tm& when, time_t twhen, bool abo out: reset_write_sources (mark_write_completed); - outout: - for (ci = capture_info.begin(); ci != capture_info.end(); ++ci) { delete *ci; } diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc index 5c1766f931..7b3ad40ad5 100644 --- a/libs/ardour/port.cc +++ b/libs/ardour/port.cc @@ -76,7 +76,7 @@ Port::Port (std::string const & n, DataType t, PortFlags f) if (!port_manager->running ()) { DEBUG_TRACE (DEBUG::Ports, string_compose ("port-engine n/a postpone registering %1\n", name())); - _port_handle = 0; // created during ::reestablish() later + _port_handle.reset (); // 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 (); diff --git a/libs/ardour/port_engine_shared.cc b/libs/ardour/port_engine_shared.cc index 1db72065b9..bd95ba7bd6 100644 --- a/libs/ardour/port_engine_shared.cc +++ b/libs/ardour/port_engine_shared.cc @@ -40,10 +40,11 @@ BackendPort::BackendPort (PortEngineSharedImpl &b, const std::string& name, Port BackendPort::~BackendPort () { - disconnect_all (); + assert (_connections.empty()); } -int BackendPort::connect (BackendPort *port) +int +BackendPort::connect (BackendPortHandle port, BackendPortHandle self) { if (!port) { PBD::error << _("BackendPort::connect (): invalid (null) port") << endmsg; @@ -65,7 +66,7 @@ int BackendPort::connect (BackendPort *port) return -1; } - if (this == port) { + if (this == port.get()) { PBD::error << _("BackendPort::connect (): cannot self-connect ports.") << endmsg; return -1; } @@ -79,20 +80,22 @@ int BackendPort::connect (BackendPort *port) return -1; } - _connect (port, true); + store_connection (port); + port->store_connection (self); + + _backend.port_connect_callback (name(), port->name(), true); + return 0; } -void BackendPort::_connect (BackendPort *port, bool callback) +void +BackendPort::store_connection (BackendPortHandle port) { _connections.insert (port); - if (callback) { - port->_connect (this, false); - _backend.port_connect_callback (name(), port->name(), true); - } } -int BackendPort::disconnect (BackendPort *port) +int +BackendPort::disconnect (BackendPortHandle port, BackendPortHandle self) { if (!port) { PBD::error << _("BackendPort::disconnect (): invalid (null) port") << endmsg; @@ -105,41 +108,41 @@ int BackendPort::disconnect (BackendPort *port) << endmsg; return -1; } - _disconnect (port, true); + + remove_connection (port); + port->remove_connection (self); + _backend.port_connect_callback (name(), port->name(), false); + return 0; } -void BackendPort::_disconnect (BackendPort *port, bool callback) +void BackendPort::remove_connection (BackendPortHandle port) { - std::set<BackendPort*>::iterator it = _connections.find (port); + std::set<BackendPortPtr>::iterator it = _connections.find (port); assert (it != _connections.end ()); _connections.erase (it); - if (callback) { - port->_disconnect (this, false); - _backend.port_connect_callback (name(), port->name(), false); - } } -void BackendPort::disconnect_all () +void BackendPort::disconnect_all (BackendPortHandle self) { while (!_connections.empty ()) { - std::set<BackendPort*>::iterator it = _connections.begin (); - (*it)->_disconnect (this, false); + std::set<BackendPortPtr>::iterator it = _connections.begin (); + (*it)->remove_connection (self); _backend.port_connect_callback (name(), (*it)->name(), false); _connections.erase (it); } } bool -BackendPort::is_connected (const BackendPort *port) const +BackendPort::is_connected (BackendPortHandle port) const { - return _connections.find (const_cast<BackendPort *>(port)) != _connections.end (); + return _connections.find (port) != _connections.end (); } bool BackendPort::is_physically_connected () const { - for (std::set<BackendPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) { + for (std::set<BackendPortPtr>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) { if ((*it)->is_physical ()) { return true; } @@ -156,7 +159,7 @@ BackendPort::set_latency_range (const LatencyRange &latency_range, bool for_play _capture_latency_range = latency_range; } - for (std::set<BackendPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) { + for (std::set<BackendPortPtr>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) { if ((*it)->is_physical ()) { (*it)->update_connected_latency (is_input ()); } @@ -168,7 +171,7 @@ BackendPort::update_connected_latency (bool for_playback) { LatencyRange lr; lr.min = lr.max = 0; - for (std::set<BackendPort*>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) { + for (std::set<BackendPortPtr>::const_iterator it = _connections.begin (); it != _connections.end (); ++it) { LatencyRange l; l = (*it)->latency_range (for_playback); lr.min = std::max (lr.min, l.min); @@ -208,7 +211,7 @@ PortEngineSharedImpl::get_ports ( boost::shared_ptr<PortIndex> p = _ports.reader (); for (PortIndex::const_iterator i = p->begin (); i != p->end (); ++i) { - BackendPort* port = *i; + BackendPortPtr port = *i; if ((port->type () == type) && flags == (port->flags () & flags)) { if (!use_regexp || !regexec (&port_regex, port->name ().c_str (), 0, NULL, 0)) { port_names.push_back (port->name ()); @@ -227,11 +230,11 @@ PortEngineSharedImpl::get_ports ( bool PortEngineSharedImpl::port_is_physical (PortEngine::PortHandle port) const { - if (!valid_port (port)) { + if (!valid_port (boost::dynamic_pointer_cast<BackendPort>(port))) { PBD::error << _("BackendPort::port_is_physical (): invalid port.") << endmsg; return false; } - return static_cast<BackendPort*>(port)->is_physical (); + return boost::dynamic_pointer_cast<BackendPort>(port)->is_physical (); } void @@ -240,7 +243,7 @@ PortEngineSharedImpl::get_physical_outputs (DataType type, std::vector<std::stri boost::shared_ptr<PortIndex> p = _ports.reader(); for (PortIndex::iterator i = p->begin (); i != p->end (); ++i) { - BackendPort* port = *i; + BackendPortPtr port = *i; if ((port->type () == type) && port->is_input () && port->is_physical ()) { port_names.push_back (port->name ()); } @@ -253,7 +256,7 @@ PortEngineSharedImpl::get_physical_inputs (DataType type, std::vector<std::strin boost::shared_ptr<PortIndex> p = _ports.reader(); for (PortIndex::iterator i = p->begin (); i != p->end (); ++i) { - BackendPort* port = *i; + BackendPortPtr port = *i; if ((port->type () == type) && port->is_output () && port->is_physical ()) { port_names.push_back (port->name ()); } @@ -269,7 +272,7 @@ PortEngineSharedImpl::n_physical_outputs () const boost::shared_ptr<PortIndex> p = _ports.reader(); for (PortIndex::const_iterator i = p->begin (); i != p->end (); ++i) { - BackendPort* port = *i; + BackendPortPtr port = *i; if (port->is_output () && port->is_physical ()) { switch (port->type ()) { case DataType::AUDIO: ++n_audio; break; @@ -293,7 +296,7 @@ PortEngineSharedImpl::n_physical_inputs () const boost::shared_ptr<PortIndex> p = _ports.reader(); for (PortIndex::const_iterator i = p->begin (); i != p->end (); ++i) { - BackendPort* port = *i; + BackendPortPtr port = *i; if (port->is_input () && port->is_physical ()) { switch (port->type ()) { case DataType::AUDIO: ++n_audio; break; @@ -308,22 +311,20 @@ PortEngineSharedImpl::n_physical_inputs () const return cc; } -PortEngine::PortHandle -PortEngineSharedImpl::add_port ( - const std::string& name, - ARDOUR::DataType type, - ARDOUR::PortFlags flags) +BackendPortPtr +PortEngineSharedImpl::add_port (const std::string& name, ARDOUR::DataType type, ARDOUR::PortFlags flags) { assert(name.size ()); + if (find_port (name)) { PBD::error << string_compose (_("%1::register_port: Port already exists: (%2)"), _instance_name, name) << endmsg; - return 0; + return BackendPortPtr(); } - BackendPort* port = port_factory (name, type, flags); + BackendPortPtr port (port_factory (name, type, flags)); if (!port) { - return 0; + return BackendPortPtr (); } { @@ -343,7 +344,7 @@ PortEngineSharedImpl::add_port ( void PortEngineSharedImpl::unregister_port (PortEngine::PortHandle port_handle) { - BackendPort* port = static_cast<BackendPort*>(port_handle); + BackendPortPtr port = boost::dynamic_pointer_cast<BackendPort>(port_handle); { RCUWriter<PortIndex> index_writer (_ports); @@ -352,20 +353,18 @@ PortEngineSharedImpl::unregister_port (PortEngine::PortHandle port_handle) boost::shared_ptr<PortIndex> ps = index_writer.get_copy (); boost::shared_ptr<PortMap> pm = map_writer.get_copy (); - PortIndex::iterator i = std::find (ps->begin(), ps->end(), static_cast<BackendPort*>(port_handle)); + PortIndex::iterator i = std::find (ps->begin(), ps->end(), boost::dynamic_pointer_cast<BackendPort> (port_handle)); if (i == ps->end ()) { PBD::error << string_compose (_("%1::unregister_port: Failed to find port"), _instance_name) << endmsg; return; } - disconnect_all(port_handle); + disconnect_all (port_handle); pm->erase (port->name()); ps->erase (i); } - - delete port; } @@ -386,11 +385,10 @@ PortEngineSharedImpl::unregister_ports (bool system_only) for (PortIndex::iterator i = ps->begin (); i != ps->end ();) { PortIndex::iterator cur = i++; - BackendPort* port = *cur; + BackendPortPtr port = *cur; if (! system_only || (port->is_physical () && port->is_terminal ())) { - port->disconnect_all (); + port->disconnect_all (port); pm->erase (port->name()); - delete port; ps->erase (cur); } } @@ -423,9 +421,10 @@ PortEngineSharedImpl::port_name_size () const } int -PortEngineSharedImpl::set_port_name (PortEngine::PortHandle port, const std::string& name) +PortEngineSharedImpl::set_port_name (PortEngine::PortHandle port_handle, const std::string& name) { std::string newname (_instance_name + ":" + name); + BackendPortPtr port = boost::dynamic_pointer_cast<BackendPort>(port_handle); if (!valid_port (port)) { PBD::error << string_compose (_("%1::set_port_name: Invalid Port"), _instance_name) << endmsg; @@ -437,49 +436,53 @@ PortEngineSharedImpl::set_port_name (PortEngine::PortHandle port, const std::str return -1; } - BackendPort* p = static_cast<BackendPort*>(port); + int ret = port->set_name (newname); + + if (ret == 0) { - { RCUWriter<PortMap> map_writer (_portmap); boost::shared_ptr<PortMap> pm = map_writer.get_copy (); - pm->erase (p->name()); - pm->insert (make_pair (newname, p)); + pm->erase (port->name()); + pm->insert (make_pair (newname, port)); } - return p->set_name (newname); + return ret; } std::string -PortEngineSharedImpl::get_port_name (PortEngine::PortHandle port) const +PortEngineSharedImpl::get_port_name (PortEngine::PortHandle port_handle) const { + BackendPortPtr port = boost::dynamic_pointer_cast<BackendPort>(port_handle); + if (!valid_port (port)) { PBD::warning << string_compose (_("AlsaBackend::get_port_name: Invalid Port(s)"), _instance_name) << endmsg; return std::string (); } - return static_cast<BackendPort*>(port)->name (); + + return port->name (); } PortFlags PortEngineSharedImpl::get_port_flags (PortEngine::PortHandle port) const { - if (!valid_port (port)) { + if (!valid_port (boost::dynamic_pointer_cast<BackendPort>(port))) { PBD::warning << string_compose (_("%1::get_port_flags: Invalid Port(s)"), _instance_name) << endmsg; return PortFlags (0); } - return static_cast<BackendPort*>(port)->flags (); + return boost::static_pointer_cast<BackendPort>(port)->flags (); } int PortEngineSharedImpl::get_port_property (PortEngine::PortHandle port, const std::string& key, std::string& value, std::string& type) const { - if (!valid_port (port)) { + if (!valid_port (boost::dynamic_pointer_cast<BackendPort>(port))) { PBD::warning << string_compose (_("%1::get_port_property: Invalid Port(s)"), _instance_name) << endmsg; return -1; } if (key == "http://jackaudio.org/metadata/pretty-name") { type = ""; - value = static_cast<BackendPort*>(port)->pretty_name (); + value = boost::static_pointer_cast<BackendPort>(port)->pretty_name (); if (!value.empty()) { return 0; } @@ -490,50 +493,51 @@ PortEngineSharedImpl::get_port_property (PortEngine::PortHandle port, const std: int PortEngineSharedImpl::set_port_property (PortEngine::PortHandle port, const std::string& key, const std::string& value, const std::string& type) { - if (!valid_port (port)) { + if (!valid_port (boost::dynamic_pointer_cast<BackendPort>(port))) { PBD::warning << string_compose (_("%1::set_port_property: Invalid Port(s)"), _instance_name) << endmsg; return -1; } if (key == "http://jackaudio.org/metadata/pretty-name" && type.empty ()) { - static_cast<BackendPort*>(port)->set_pretty_name (value); + boost::static_pointer_cast<BackendPort>(port)->set_pretty_name (value); return 0; } return -1; } -PortEngine::PortHandle +PortEngine::PortPtr PortEngineSharedImpl::get_port_by_name (const std::string& name) const { - PortEngine::PortHandle port = (PortEngine::PortHandle) find_port (name); - return port; + return find_port (name); } DataType PortEngineSharedImpl::port_data_type (PortEngine::PortHandle port) const { - if (!valid_port (port)) { + BackendPortPtr p = boost::dynamic_pointer_cast<BackendPort> (port); + + if (!valid_port (p)) { return DataType::NIL; } - return static_cast<BackendPort*>(port)->type (); + + return p->type (); } -PortEngine::PortHandle +PortEngine::PortPtr PortEngineSharedImpl::register_port ( const std::string& name, ARDOUR::DataType type, ARDOUR::PortFlags flags) { - if (name.size () == 0) { return 0; } - if (flags & IsPhysical) { return 0; } + if (name.size () == 0) { return PortEngine::PortPtr(); } + if (flags & IsPhysical) { return PortEngine::PortPtr(); } return add_port (_instance_name + ":" + name, type, flags); } - int PortEngineSharedImpl::connect (const std::string& src, const std::string& dst) { - BackendPort* src_port = find_port (src); - BackendPort* dst_port = find_port (dst); + BackendPortPtr src_port = find_port (src); + BackendPortPtr dst_port = find_port (dst); if (!src_port) { PBD::error << string_compose (_("%1::connect: Invalid Source port: (%2)"), _instance_name, src) << endmsg; @@ -543,95 +547,118 @@ PortEngineSharedImpl::connect (const std::string& src, const std::string& dst) PBD::error << string_compose (_("%1::connect: Invalid Destination port: (%2)"), _instance_name, dst) << endmsg; return -1; } - return src_port->connect (dst_port); + + src_port->connect (dst_port, src_port); + + return 0; } int PortEngineSharedImpl::disconnect (const std::string& src, const std::string& dst) { - BackendPort* src_port = find_port (src); - BackendPort* dst_port = find_port (dst); + BackendPortPtr src_port = find_port (src); + BackendPortPtr dst_port = find_port (dst); if (!src_port || !dst_port) { PBD::error << string_compose (_("%1::disconnect: Invalid Port(s)"), _instance_name) << endmsg; return -1; } - return src_port->disconnect (dst_port); + return src_port->disconnect (dst_port, src_port); } int PortEngineSharedImpl::connect (PortEngine::PortHandle src, const std::string& dst) { - BackendPort* dst_port = find_port (dst); - if (!valid_port (src)) { + BackendPortPtr src_port = boost::dynamic_pointer_cast<BackendPort> (src); + + if (!valid_port (src_port)) { PBD::error << string_compose (_("%1::connect: Invalid Source Port Handle"), _instance_name) << endmsg; return -1; } + + BackendPortPtr dst_port = find_port (dst); + if (!dst_port) { PBD::error << string_compose (_("%1::connect: Invalid Destination Port: (%2)"), _instance_name, dst) << endmsg; return -1; } - return static_cast<BackendPort*>(src)->connect (dst_port); + + src_port->connect (dst_port, src_port); + + return 0; } int PortEngineSharedImpl::disconnect (PortEngine::PortHandle src, const std::string& dst) { - BackendPort* dst_port = find_port (dst); - if (!valid_port (src) || !dst_port) { + BackendPortPtr src_port = boost::dynamic_pointer_cast<BackendPort>(src); + BackendPortPtr dst_port = find_port (dst); + + if (!valid_port (src_port) || !dst_port) { PBD::error << string_compose (_("%1::disconnect: Invalid Port(s)"), _instance_name) << endmsg; return -1; } - return static_cast<BackendPort*>(src)->disconnect (dst_port); + return src_port->disconnect (dst_port, src_port); } int -PortEngineSharedImpl::disconnect_all (PortEngine::PortHandle port) +PortEngineSharedImpl::disconnect_all (PortEngine::PortHandle port_handle) { + BackendPortPtr port = boost::dynamic_pointer_cast<BackendPort> (port_handle); + if (!valid_port (port)) { PBD::error << string_compose (_("%1::disconnect_all: Invalid Port"), _instance_name) << endmsg; return -1; } - static_cast<BackendPort*>(port)->disconnect_all (); + + port->disconnect_all (port); + return 0; } bool -PortEngineSharedImpl::connected (PortEngine::PortHandle port, bool /* process_callback_safe*/) +PortEngineSharedImpl::connected (PortEngine::PortHandle port_handle, bool /* process_callback_safe*/) { + BackendPortPtr port = boost::dynamic_pointer_cast<BackendPort> (port_handle); + if (!valid_port (port)) { PBD::error << string_compose (_("%1::disconnect_all: Invalid Port"), _instance_name) << endmsg; return false; } - return static_cast<BackendPort*>(port)->is_connected (); + return port->is_connected (); } bool PortEngineSharedImpl::connected_to (PortEngine::PortHandle src, const std::string& dst, bool /*process_callback_safe*/) { - BackendPort* dst_port = find_port (dst); + BackendPortPtr src_port = boost::dynamic_pointer_cast<BackendPort> (src); + BackendPortPtr dst_port = find_port (dst); #ifndef NDEBUG - if (!valid_port (src) || !dst_port) { + if (!valid_port (src_port) || !dst_port) { PBD::error << string_compose (_("%1::connected_to: Invalid Port"), _instance_name) << endmsg; return false; } #endif - return static_cast<BackendPort*>(src)->is_connected (dst_port); + return boost::static_pointer_cast<BackendPort>(src)->is_connected (dst_port); } bool -PortEngineSharedImpl::physically_connected (PortEngine::PortHandle port, bool /*process_callback_safe*/) +PortEngineSharedImpl::physically_connected (PortEngine::PortHandle port_handle, bool /*process_callback_safe*/) { + BackendPortPtr port = boost::dynamic_pointer_cast<BackendPort> (port_handle); + if (!valid_port (port)) { PBD::error << string_compose (_("%1::physically_connected: Invalid Port"), _instance_name) << endmsg; return false; } - return static_cast<BackendPort*>(port)->is_physically_connected (); + return port->is_physically_connected (); } int -PortEngineSharedImpl::get_connections (PortEngine::PortHandle port, std::vector<std::string>& names, bool /*process_callback_safe*/) +PortEngineSharedImpl::get_connections (PortEngine::PortHandle port_handle, std::vector<std::string>& names, bool /*process_callback_safe*/) { + BackendPortPtr port = boost::dynamic_pointer_cast<BackendPort> (port_handle); + if (!valid_port (port)) { PBD::error << string_compose (_("%1::get_connections: Invalid Port"), _instance_name) << endmsg; return -1; @@ -639,11 +666,29 @@ PortEngineSharedImpl::get_connections (PortEngine::PortHandle port, std::vector< assert (0 == names.size ()); - const std::set<BackendPort*>& connected_ports = static_cast<BackendPort*>(port)->get_connections (); + const std::set<BackendPortPtr>& connected_ports = port->get_connections (); - for (std::set<BackendPort*>::const_iterator i = connected_ports.begin (); i != connected_ports.end (); ++i) { + for (std::set<BackendPortPtr>::const_iterator i = connected_ports.begin (); i != connected_ports.end (); ++i) { names.push_back ((*i)->name ()); } return (int)names.size (); } + +void +PortEngineSharedImpl::update_system_port_latencies () +{ + for (std::vector<BackendPortPtr>::const_iterator it = _system_inputs.begin (); it != _system_inputs.end (); ++it) { + (*it)->update_connected_latency (true); + } + for (std::vector<BackendPortPtr>::const_iterator it = _system_outputs.begin (); it != _system_outputs.end (); ++it) { + (*it)->update_connected_latency (false); + } + + for (std::vector<BackendPortPtr>::const_iterator it = _system_midi_in.begin (); it != _system_midi_in.end (); ++it) { + (*it)->update_connected_latency (true); + } + for (std::vector<BackendPortPtr>::const_iterator it = _system_midi_out.begin (); it != _system_midi_out.end (); ++it) { + (*it)->update_connected_latency (false); + } +} |