summaryrefslogtreecommitdiff
path: root/libs/ardour/port.cc
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2009-01-30 07:40:13 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2009-01-30 07:40:13 +0000
commit70b939da4f9d4097160e32f2373a7a5ff8f4957f (patch)
tree5917e5847c75e441c9df550d5101352d18e8286f /libs/ardour/port.cc
parentee62ee07d39f51ba1b70f390dc2158c57f54a572 (diff)
first pass at internal sends. this is a very tentative work in progress, and it is possible that major changes may follow in the near future. it is certainly not complete, but the fundamental changes to Port/Buffer operation merit a commit at this point
git-svn-id: svn://localhost/ardour2/branches/3.0@4464 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour/port.cc')
-rw-r--r--libs/ardour/port.cc123
1 files changed, 95 insertions, 28 deletions
diff --git a/libs/ardour/port.cc b/libs/ardour/port.cc
index b200888508..74de1922fe 100644
--- a/libs/ardour/port.cc
+++ b/libs/ardour/port.cc
@@ -25,19 +25,30 @@
#include "pbd/compose.h"
#include <stdexcept>
-ARDOUR::AudioEngine* ARDOUR::Port::_engine = 0;
+using namespace std;
+using namespace ARDOUR;
+
+AudioEngine* Port::_engine = 0;
/** @param n Port short name */
-ARDOUR::Port::Port (std::string const & n, DataType t, Flags f, bool e) : _jack_port (0), _last_monitor (false), _latency (0), _name (n), _flags (f)
+Port::Port (std::string const & n, DataType t, Flags f, bool e)
+ : _jack_port (0)
+ , _last_monitor (false)
+ , _latency (0)
+ , _name (n)
+ , _flags (f)
{
+
/* Unfortunately we have to pass the DataType into this constructor so that we can
create the right kind of JACK port; aside from this we'll use the virtual function type ()
- to establish type. */
+ to establish type.
+ */
assert (_name.find_first_of (':') == std::string::npos);
if (e) {
try {
+ cerr << "NEW PORT " << _name << " ext = " << e << endl;
do_make_external (t);
}
catch (...) {
@@ -47,7 +58,7 @@ ARDOUR::Port::Port (std::string const & n, DataType t, Flags f, bool e) : _jack_
}
/** Port destructor */
-ARDOUR::Port::~Port ()
+Port::~Port ()
{
if (_jack_port) {
jack_port_unregister (_engine->jack (), _jack_port);
@@ -58,28 +69,27 @@ ARDOUR::Port::~Port ()
* @param t Data type, so that we can call this method from the constructor.
*/
void
-ARDOUR::Port::do_make_external (DataType t)
+Port::do_make_external (DataType t)
{
if (_jack_port) {
/* already external */
return;
}
- _jack_port = jack_port_register (_engine->jack (), _name.c_str (), t.to_jack_type (), _flags, 0);
- if (_jack_port == 0) {
+ if ((_jack_port = jack_port_register (_engine->jack (), _name.c_str (), t.to_jack_type (), _flags, 0)) == 0) {
throw std::runtime_error ("Could not register JACK port");
}
}
void
-ARDOUR::Port::make_external ()
+Port::make_external ()
{
do_make_external (type ());
}
/** @return true if this port is connected to anything */
bool
-ARDOUR::Port::connected () const
+Port::connected () const
{
if (!_connections.empty ()) {
/* connected to a Port* */
@@ -94,8 +104,20 @@ ARDOUR::Port::connected () const
return (jack_port_connected (_jack_port) != 0);
}
+/** @return true if this port is connected to anything via an external port */
+bool
+Port::externally_connected () const
+{
+ if (_jack_port == 0) {
+ /* not using a JACK port, so can't be connected to anything else */
+ return false;
+ }
+
+ return (jack_port_connected (_jack_port) != 0);
+}
+
int
-ARDOUR::Port::disconnect_all ()
+Port::disconnect_all ()
{
/* Disconnect from Port* connections */
for (std::set<Port*>::iterator i = _connections.begin (); i != _connections.end (); ++i) {
@@ -108,6 +130,8 @@ ARDOUR::Port::disconnect_all ()
jack_port_disconnect (_engine->jack(), _jack_port);
_named_connections.clear ();
+ check_buffer_status ();
+
return 0;
}
@@ -115,7 +139,7 @@ ARDOUR::Port::disconnect_all ()
* @return true if this port is connected to o, otherwise false.
*/
bool
-ARDOUR::Port::connected_to (std::string const & o) const
+Port::connected_to (std::string const & o) const
{
std::string const full = _engine->make_port_name_non_relative (o);
std::string const shrt = _engine->make_port_name_non_relative (o);
@@ -137,7 +161,7 @@ ARDOUR::Port::connected_to (std::string const & o) const
/** @param o Filled in with port full names of ports that we are connected to */
int
-ARDOUR::Port::get_connections (std::vector<std::string> & c) const
+Port::get_connections (std::vector<std::string> & c) const
{
int n = 0;
@@ -163,7 +187,7 @@ ARDOUR::Port::get_connections (std::vector<std::string> & c) const
}
int
-ARDOUR::Port::connect (std::string const & other)
+Port::connect (std::string const & other)
{
/* caller must hold process lock */
@@ -197,11 +221,13 @@ ARDOUR::Port::connect (std::string const & other)
}
}
+ check_buffer_status ();
+
return r;
}
int
-ARDOUR::Port::disconnect (std::string const & other)
+Port::disconnect (std::string const & other)
{
/* caller must hold process lock */
@@ -227,6 +253,8 @@ ARDOUR::Port::disconnect (std::string const & other)
if (r == 0) {
_named_connections.erase (other);
}
+
+ check_buffer_status ();
}
return r;
@@ -234,13 +262,13 @@ ARDOUR::Port::disconnect (std::string const & other)
bool
-ARDOUR::Port::connected_to (Port* o) const
+Port::connected_to (Port* o) const
{
return connected_to (o->name ());
}
int
-ARDOUR::Port::connect (Port* o)
+Port::connect (Port* o)
{
/* caller must hold process lock */
@@ -253,11 +281,14 @@ ARDOUR::Port::connect (Port* o)
_connections.insert (o);
o->_connections.insert (this);
+ check_buffer_status ();
+ o->check_buffer_status ();
+
return 0;
}
int
-ARDOUR::Port::disconnect (Port* o)
+Port::disconnect (Port* o)
{
if (external () && o->external ()) {
/* we're both external; try disconnecting using name */
@@ -270,17 +301,20 @@ ARDOUR::Port::disconnect (Port* o)
_connections.erase (o);
o->_connections.erase (this);
+ check_buffer_status ();
+ o->check_buffer_status ();
+
return 0;
}
void
-ARDOUR::Port::set_engine (AudioEngine* e)
+Port::set_engine (AudioEngine* e)
{
_engine = e;
}
void
-ARDOUR::Port::ensure_monitor_input (bool yn)
+Port::ensure_monitor_input (bool yn)
{
if (_jack_port) {
jack_port_ensure_monitor (_jack_port, yn);
@@ -288,7 +322,7 @@ ARDOUR::Port::ensure_monitor_input (bool yn)
}
bool
-ARDOUR::Port::monitoring_input () const
+Port::monitoring_input () const
{
if (_jack_port) {
return jack_port_monitoring_input (_jack_port);
@@ -298,7 +332,7 @@ ARDOUR::Port::monitoring_input () const
}
void
-ARDOUR::Port::reset ()
+Port::reset ()
{
_last_monitor = false;
@@ -308,7 +342,7 @@ ARDOUR::Port::reset ()
}
void
-ARDOUR::Port::recompute_total_latency () const
+Port::recompute_total_latency () const
{
#ifdef HAVE_JACK_RECOMPUTE_LATENCY
if (_jack_port) {
@@ -318,7 +352,7 @@ ARDOUR::Port::recompute_total_latency () const
}
nframes_t
-ARDOUR::Port::total_latency () const
+Port::total_latency () const
{
if (_jack_port) {
return jack_port_get_total_latency (_engine->jack (), _jack_port);
@@ -328,7 +362,7 @@ ARDOUR::Port::total_latency () const
}
int
-ARDOUR::Port::reestablish ()
+Port::reestablish ()
{
if (!_jack_port) {
return 0;
@@ -348,7 +382,7 @@ ARDOUR::Port::reestablish ()
int
-ARDOUR::Port::reconnect ()
+Port::reconnect ()
{
/* caller must hold process lock; intended to be used only after reestablish() */
@@ -367,7 +401,7 @@ ARDOUR::Port::reconnect ()
/** @param n Short name */
int
-ARDOUR::Port::set_name (std::string const & n)
+Port::set_name (std::string const & n)
{
assert (_name.find_first_of (':') == std::string::npos);
@@ -386,15 +420,48 @@ ARDOUR::Port::set_name (std::string const & n)
}
void
-ARDOUR::Port::set_latency (nframes_t n)
+Port::set_latency (nframes_t n)
{
_latency = n;
}
void
-ARDOUR::Port::request_monitor_input (bool yn)
+Port::request_monitor_input (bool yn)
{
if (_jack_port) {
jack_port_request_monitor (_jack_port, yn);
}
}
+
+void
+Port::check_buffer_status ()
+{
+ if (external() && receives_input()) {
+ if (!externally_connected()) {
+ if (!_connections.empty()) {
+
+ /* There are no external connections, so the
+ external port buffer will be the silent buffer. We cannot write into it.
+ But we have to write somewhere because there is at least one internal
+ connection that is supplying us with data.
+ */
+
+ if (!using_internal_data()) {
+ use_internal_data ();
+ }
+
+ } else {
+
+ /* There are no external connections and no internal ones
+ either, so we can revert to use the externally supplied
+ buffer which will be silent (whatever the semantics of
+ that are for a particular data type.
+ */
+
+ if (using_internal_data()) {
+ use_external_data ();
+ }
+ }
+ }
+ }
+}