#include <fstream>
#include <algorithm>
#include <cmath>
+#include <vector>
#include <unistd.h>
#include <locale.h>
#include <errno.h>
#include <glibmm.h>
-#include <glibmm/thread.h>
+#include <glibmm/threads.h>
#include "pbd/xml++.h"
#include "pbd/replace_all.h"
#include "i18n.h"
-#define BLOCK_PROCESS_CALLBACK() Glib::Mutex::Lock em (AudioEngine::instance()->process_lock())
+#define BLOCK_PROCESS_CALLBACK() Glib::Threads::Mutex::Lock em (AudioEngine::instance()->process_lock())
using namespace std;
using namespace ARDOUR;
/** @param default_type The type of port that will be created by ensure_io
* and friends if no type is explicitly requested (to avoid breakage).
*/
-IO::IO (Session& s, const string& name, Direction dir, DataType default_type)
+IO::IO (Session& s, const string& name, Direction dir, DataType default_type, bool sendish)
: SessionObject (s, name)
, _direction (dir)
, _default_type (default_type)
+ , _sendish (sendish)
{
_active = true;
Port::PostDisconnect.connect_same_thread (*this, boost::bind (&IO::disconnect_check, this, _1, _2));
setup_bundle ();
}
-IO::IO (Session& s, const XMLNode& node, DataType dt)
+IO::IO (Session& s, const XMLNode& node, DataType dt, bool sendish)
: SessionObject(s, "unnamed io")
, _direction (Input)
, _default_type (dt)
+ , _sendish (sendish)
{
_active = true;
pending_state_node = 0;
IO::~IO ()
{
- Glib::Mutex::Lock lm (io_lock);
+ Glib::Threads::Mutex::Lock lm (io_lock);
BLOCK_PROCESS_CALLBACK ();
we assume that its safely locked by our own ::disconnect().
*/
- Glib::Mutex::Lock tm (io_lock, Glib::TRY_LOCK);
+ Glib::Threads::Mutex::Lock tm (io_lock, Glib::Threads::TRY_LOCK);
if (tm.locked()) {
/* we took the lock, so we cannot be here from inside
}
{
- Glib::Mutex::Lock lm (io_lock);
+ Glib::Threads::Mutex::Lock lm (io_lock);
/* check that our_port is really one of ours */
}
{
- Glib::Mutex::Lock lm (io_lock);
+ Glib::Threads::Mutex::Lock lm (io_lock);
/* check that our_port is really one of ours */
BLOCK_PROCESS_CALLBACK ();
{
- Glib::Mutex::Lock lm (io_lock);
+ Glib::Threads::Mutex::Lock lm (io_lock);
if (_ports.remove(port)) {
change.type = IOChange::Type (change.type | IOChange::ConfigurationChanged);
{
- Glib::Mutex::Lock lm (io_lock);
+ Glib::Threads::Mutex::Lock lm (io_lock);
/* Create a new port */
IO::disconnect (void* src)
{
{
- Glib::Mutex::Lock lm (io_lock);
+ Glib::Threads::Mutex::Lock lm (io_lock);
for (PortSet::iterator i = _ports.begin(); i != _ports.end(); ++i) {
i->disconnect_all ();
int
IO::ensure_ports_locked (ChanCount count, bool clear, bool& changed)
{
+#ifndef PLATFORM_WINDOWS
assert (!AudioEngine::instance()->process_lock().trylock());
+#endif
boost::shared_ptr<Port> port;
int
IO::ensure_ports (ChanCount count, bool clear, void* src)
{
+#ifndef PLATFORM_WINDOWS
assert (!AudioEngine::instance()->process_lock().trylock());
+#endif
bool changed = false;
change.before = _ports.count ();
{
- Glib::Mutex::Lock im (io_lock);
+ Glib::Threads::Mutex::Lock im (io_lock);
if (ensure_ports_locked (count, clear, changed)) {
return -1;
}
int
IO::ensure_io (ChanCount count, bool clear, void* src)
{
+#ifndef PLATFORM_WINDOWS
assert (!AudioEngine::instance()->process_lock().trylock());
+#endif
return ensure_ports (count, clear, src);
}
string str;
vector<string>::iterator ci;
int n;
- LocaleGuard lg (X_("POSIX"));
- Glib::Mutex::Lock lm (io_lock);
+ LocaleGuard lg (X_("C"));
+ Glib::Threads::Mutex::Lock lm (io_lock);
node->add_property("name", _name);
id().print (buf, sizeof (buf));
const XMLProperty* prop;
XMLNodeConstIterator iter;
- LocaleGuard lg (X_("POSIX"));
+ LocaleGuard lg (X_("C"));
/* force use of non-localized representation of decimal point,
since we use it a lot in XML files and so forth.
{
const XMLProperty* prop;
XMLNodeConstIterator iter;
- LocaleGuard lg (X_("POSIX"));
+ LocaleGuard lg (X_("C"));
/* force use of non-localized representation of decimal point,
since we use it a lot in XML files and so forth.
for (iter = node.children().begin(); iter != node.children().end(); ++iter) {
if ((*iter)->name() == X_("Bundle")) {
+ prop = (*iter)->property ("name");
if ((c = find_possible_bundle (prop->value())) != 0) {
n = ChanCount::max (n, c->nchannels());
return 0;
get_port_counts (node, version, n, c);
{
- Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+ Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
if (ensure_ports (n, true, this)) {
error << string_compose(_("%1: cannot create I/O ports"), _name) << endmsg;
if (prop) {
boost::shared_ptr<Bundle> b = find_possible_bundle (prop->value());
if (b) {
- connect_ports_to_bundle (b, this);
+ connect_ports_to_bundle (b, true, this);
}
}
if (p != string::npos) {
ports[x].replace (p, 4, "/audio_out");
}
- nth(i)->connect (ports[x]);
+ if (NULL != nth(i).get())
+ nth(i)->connect (ports[x]);
}
}
if (p != string::npos) {
ports[x].replace (p, 3, "/audio_in");
}
- nth(i)->connect (ports[x]);
+ if (NULL != nth(i).get())
+ nth(i)->connect (ports[x]);
}
}
IO::set_ports (const string& str)
{
vector<string> ports;
- int i;
int n;
uint32_t nports;
}
{
- Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
+ Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock ());
// FIXME: audio-only
if (ensure_ports (ChanCount(DataType::AUDIO, nports), true, this)) {
}
}
- string::size_type start, end, ostart;
-
- ostart = 0;
- start = 0;
- end = 0;
- i = 0;
-
- while ((start = str.find_first_of ('{', ostart)) != string::npos) {
+ string::size_type start = 0;
+ string::size_type end = 0;
+ string::size_type ostart = 0;
+ for (int i = 0; (start = str.find_first_of ('{', ostart)) != string::npos; ++i) {
start += 1;
if ((end = str.find_first_of ('}', start)) == string::npos) {
}
ostart = end+1;
- i++;
}
return 0;
{
string::size_type pos, opos;
- pos = 0;
opos = 0;
ports.clear ();
}
int
-IO::connect_ports_to_bundle (boost::shared_ptr<Bundle> c, void* src)
+IO::connect_ports_to_bundle (boost::shared_ptr<Bundle> c, bool exclusive, void* src)
{
BLOCK_PROCESS_CALLBACK ();
{
- Glib::Mutex::Lock lm2 (io_lock);
+ Glib::Threads::Mutex::Lock lm2 (io_lock);
+
+ if (exclusive) {
+ for (PortSet::iterator i = _ports.begin(); i != _ports.end(); ++i) {
+ i->disconnect_all ();
+ }
+ }
c->connect (_bundle, _session.engine());
BLOCK_PROCESS_CALLBACK ();
{
- Glib::Mutex::Lock lm2 (io_lock);
+ Glib::Threads::Mutex::Lock lm2 (io_lock);
c->disconnect (_bundle, _session.engine());
int
IO::enable_connecting ()
{
- Glib::Mutex::Lock lm (AudioEngine::instance()->process_lock());
+ Glib::Threads::Mutex::Lock lm (AudioEngine::instance()->process_lock());
connecting_legal = true;
boost::optional<int> r = ConnectingLegal ();
return r.get_value_or (0);
string
IO::build_legal_port_name (DataType type)
{
- const int name_size = jack_port_name_size();
+ const int name_size = AudioEngine::instance()->port_name_size();
int limit;
string suffix;
if (type == DataType::AUDIO) {
- suffix = _("audio");
+ suffix = X_("audio");
} else if (type == DataType::MIDI) {
- suffix = _("midi");
+ suffix = X_("midi");
} else {
throw unknown_type();
}
use the (new) translated name.
*/
- if (_direction == Input) {
- suffix += X_("_in");
+ if (_sendish) {
+ if (_direction == Input) {
+ suffix += X_("_return");
+ } else {
+ suffix += X_("_send");
+ }
} else {
- suffix += X_("_out");
+ if (_direction == Input) {
+ suffix += X_("_in");
+ } else {
+ suffix += X_("_out");
+ }
}
// allow up to 4 digits for the output port number, plus the slash, suffix and extra space
- limit = name_size - _session.engine().client_name().length() - (suffix.length() + 5);
+ limit = name_size - AudioEngine::instance()->my_name().length() - (suffix.length() + 5);
- char buf1[name_size+1];
- char buf2[name_size+1];
+ std::vector<char> buf1(name_size+1);
+ std::vector<char> buf2(name_size+1);
/* colons are illegal in port names, so fix that */
string nom = _name.val();
replace_all (nom, ":", ";");
- snprintf (buf1, name_size+1, ("%.*s/%s"), limit, nom.c_str(), suffix.c_str());
+ snprintf (&buf1[0], name_size+1, ("%.*s/%s"), limit, nom.c_str(), suffix.c_str());
- int port_number = find_port_hole (buf1);
- snprintf (buf2, name_size+1, "%s %d", buf1, port_number);
+ int port_number = find_port_hole (&buf1[0]);
+ snprintf (&buf2[0], name_size+1, "%s %d", &buf1[0], port_number);
- return string (buf2);
+ return string (&buf2[0]);
}
int32_t
*/
for (n = 1; n < 9999; ++n) {
- char buf[jack_port_name_size()];
+ std::vector<char> buf (AudioEngine::instance()->port_name_size());
PortSet::iterator i = _ports.begin();
- snprintf (buf, jack_port_name_size(), _("%s %u"), base, n);
+ snprintf (&buf[0], buf.size()+1, _("%s %u"), base, n);
for ( ; i != _ports.end(); ++i) {
- if (i->name() == buf) {
+ if (string(i->name()) == string(&buf[0])) {
break;
}
}
for (i = 0; i < no; ++i) {
for (j = 0; j < ni; ++j) {
- if (nth(i)->connected_to (other->nth(j)->name())) {
- return true;
+ if ((NULL != nth(i).get()) && (NULL != other->nth(j).get())) {
+ if (nth(i)->connected_to (other->nth(j)->name())) {
+ return true;
+ }
}
}
}
return;
}
- _buffers.get_jack_port_addresses (_ports, nframes);
- proc->run (_buffers, start_frame, end_frame, nframes, true);
+ _buffers.get_backend_port_addresses (_ports, nframes);
+ if (proc) {
+ proc->run (_buffers, start_frame, end_frame, nframes, true);
+ }
}
void
bool
IO::has_port (boost::shared_ptr<Port> p) const
{
- Glib::Mutex::Lock lm (io_lock);
+ Glib::Threads::Mutex::Lock lm (io_lock);
return _ports.contains (p);
}