summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2020-04-07 10:18:16 -0600
committerPaul Davis <paul@linuxaudiosystems.com>2020-04-07 13:23:49 -0600
commitb9cb306e8b9a330ec5211ccdfde6b90f17701099 (patch)
tree4e3e2d90fe9d0747a06e08c8bfd099fc275c07b4 /libs/ardour
parent1eb98316a3467c94842f6b6ba21eaf4470760880 (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.h4
-rw-r--r--libs/ardour/ardour/port.h2
-rw-r--r--libs/ardour/ardour/port_engine.h26
-rw-r--r--libs/ardour/ardour/port_engine_shared.h69
-rw-r--r--libs/ardour/audioengine.cc2
-rw-r--r--libs/ardour/disk_writer.cc5
-rw-r--r--libs/ardour/port.cc2
-rw-r--r--libs/ardour/port_engine_shared.cc235
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);
+ }
+}