#include <glibmm.h>
#include "dummy_audiobackend.h"
+
#include "pbd/error.h"
+#include "ardour/port_manager.h"
#include "i18n.h"
using namespace ARDOUR;
, _processed_samples (0)
{
_instance_name = s_instance_name;
+ pthread_mutex_init (&_port_callback_mutex, 0);
}
DummyAudioBackend::~DummyAudioBackend ()
{
+ pthread_mutex_destroy (&_port_callback_mutex);
}
/* AUDIOBACKEND API */
DummyPort* port = NULL;
switch (type) {
case DataType::AUDIO:
- port = new DummyAudioPort (name, flags);
+ port = new DummyAudioPort (*this, name, flags);
break;
case DataType::MIDI:
- port = new DummyMidiPort (name, flags);
+ port = new DummyMidiPort (*this, name, flags);
break;
default:
PBD::error << _("DummyBackend::register_port: Invalid Data Type.") << endmsg;
Glib::usleep (100); // don't hog cpu
}
clock1 = g_get_monotonic_time();
+
+ if (!pthread_mutex_trylock (&_port_callback_mutex)) {
+ while (!_port_connection_queue.empty ()) {
+ PortConnectData *c = _port_connection_queue.back ();
+ manager.connect_callback (c->a, c->b, c->c);
+ _port_connection_queue.pop_back ();
+ delete c;
+ }
+ pthread_mutex_unlock (&_port_callback_mutex);
+ }
+
}
_running = false;
return 0;
/******************************************************************************/
-DummyPort::DummyPort (const std::string& name, PortFlags flags)
- : _name (name)
+DummyPort::DummyPort (DummyAudioBackend &b, const std::string& name, PortFlags flags)
+ : _dummy_backend (b)
+ , _name (name)
, _flags (flags)
{
_capture_latency_range.min = 0;
_connections.push_back (port);
if (callback) {
port->_connect (this, false);
+ _dummy_backend.port_connect_callback (name(), port->name(), true);
}
}
if (callback) {
port->_disconnect (this, false);
+ _dummy_backend.port_connect_callback (name(), port->name(), false);
}
}
{
while (!_connections.empty ()) {
_connections.back ()->_disconnect (this, false);
+ _dummy_backend.port_connect_callback (name(), _connections.back ()->name(), false);
_connections.pop_back ();
}
}
/******************************************************************************/
-DummyAudioPort::DummyAudioPort (const std::string& name, PortFlags flags)
- : DummyPort (name, flags)
+DummyAudioPort::DummyAudioPort (DummyAudioBackend &b, const std::string& name, PortFlags flags)
+ : DummyPort (b, name, flags)
{
memset (_buffer, 0, sizeof (_buffer));
}
}
-DummyMidiPort::DummyMidiPort (const std::string& name, PortFlags flags)
- : DummyPort (name, flags)
+DummyMidiPort::DummyMidiPort (DummyAudioBackend &b, const std::string& name, PortFlags flags)
+ : DummyPort (b, name, flags)
{
_buffer.clear ();
}
namespace ARDOUR {
+class DummyAudioBackend;
+
class DummyMidiEvent {
public:
DummyMidiEvent (const pframes_t timestamp, const uint8_t* data, size_t size);
class DummyPort {
protected:
- DummyPort (const std::string&, PortFlags);
+ DummyPort (DummyAudioBackend &b, const std::string&, PortFlags);
public:
virtual ~DummyPort ();
}
private:
+ DummyAudioBackend &_dummy_backend;
std::string _name;
const PortFlags _flags;
LatencyRange _capture_latency_range;
class DummyAudioPort : public DummyPort {
public:
- DummyAudioPort (const std::string&, PortFlags);
+ DummyAudioPort (DummyAudioBackend &b, const std::string&, PortFlags);
~DummyAudioPort ();
DataType type () const { return DataType::AUDIO; };
class DummyMidiPort : public DummyPort {
public:
- DummyMidiPort (const std::string&, PortFlags);
+ DummyMidiPort (DummyAudioBackend &b, const std::string&, PortFlags);
~DummyMidiPort ();
DataType type () const { return DataType::MIDI; };
}; // class DummyMidiPort
class DummyAudioBackend : public AudioBackend {
+ friend class DummyPort;
public:
DummyAudioBackend (AudioEngine& e, AudioBackendInfo& info);
~DummyAudioBackend ();
std::vector<DummyPort *> _ports;
+
+ struct PortConnectData {
+ std::string a;
+ std::string b;
+ bool c;
+
+ PortConnectData (const std::string& a, const std::string& b, bool c)
+ : a (a) , b (b) , c (c) {}
+ };
+
+ std::vector<PortConnectData *> _port_connection_queue;
+ pthread_mutex_t _port_callback_mutex;
+
+ void port_connect_callback (const std::string& a, const std::string& b, bool conn) {
+ pthread_mutex_lock (&_port_callback_mutex);
+ _port_connection_queue.push_back(new PortConnectData(a, b, conn));
+ pthread_mutex_unlock (&_port_callback_mutex);
+ }
+
bool valid_port (PortHandle port) const {
return std::find (_ports.begin (), _ports.end (), (DummyPort*)port) != _ports.end ();
}
+
DummyPort * find_port (const std::string& port_name) const {
for (std::vector<DummyPort*>::const_iterator it = _ports.begin (); it != _ports.end (); ++it) {
if ((*it)->name () == port_name) {