From 2b9fa31241de5ff6e3c3258915798b24c5539ad5 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 25 May 2014 00:21:44 +0200 Subject: [PATCH] DummyBackend: implement port connect_callback() --- libs/backends/dummy/dummy_audiobackend.cc | 35 +++++++++++++++++------ libs/backends/dummy/dummy_audiobackend.h | 30 +++++++++++++++++-- 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/libs/backends/dummy/dummy_audiobackend.cc b/libs/backends/dummy/dummy_audiobackend.cc index 01e8085e04..bcf930665e 100644 --- a/libs/backends/dummy/dummy_audiobackend.cc +++ b/libs/backends/dummy/dummy_audiobackend.cc @@ -23,7 +23,9 @@ #include #include "dummy_audiobackend.h" + #include "pbd/error.h" +#include "ardour/port_manager.h" #include "i18n.h" using namespace ARDOUR; @@ -47,10 +49,12 @@ DummyAudioBackend::DummyAudioBackend (AudioEngine& e, AudioBackendInfo& info) , _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 */ @@ -583,10 +587,10 @@ DummyAudioBackend::add_port ( 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; @@ -1019,6 +1023,17 @@ DummyAudioBackend::main_process_thread () 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; @@ -1078,8 +1093,9 @@ extern "C" ARDOURBACKEND_API ARDOUR::AudioBackendInfo* descriptor () /******************************************************************************/ -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; @@ -1139,6 +1155,7 @@ void DummyPort::_connect (DummyPort *port, bool callback) _connections.push_back (port); if (callback) { port->_connect (this, false); + _dummy_backend.port_connect_callback (name(), port->name(), true); } } @@ -1169,6 +1186,7 @@ void DummyPort::_disconnect (DummyPort *port, bool callback) if (callback) { port->_disconnect (this, false); + _dummy_backend.port_connect_callback (name(), port->name(), false); } } @@ -1177,6 +1195,7 @@ void DummyPort::disconnect_all () { while (!_connections.empty ()) { _connections.back ()->_disconnect (this, false); + _dummy_backend.port_connect_callback (name(), _connections.back ()->name(), false); _connections.pop_back (); } } @@ -1199,8 +1218,8 @@ bool DummyPort::is_physically_connected () const /******************************************************************************/ -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)); } @@ -1234,8 +1253,8 @@ void* DummyAudioPort::get_buffer (pframes_t n_samples) } -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 (); } diff --git a/libs/backends/dummy/dummy_audiobackend.h b/libs/backends/dummy/dummy_audiobackend.h index 28143ff7ba..733bb5f78a 100644 --- a/libs/backends/dummy/dummy_audiobackend.h +++ b/libs/backends/dummy/dummy_audiobackend.h @@ -35,6 +35,8 @@ namespace ARDOUR { +class DummyAudioBackend; + class DummyMidiEvent { public: DummyMidiEvent (const pframes_t timestamp, const uint8_t* data, size_t size); @@ -55,7 +57,7 @@ typedef std::vector > DummyMidiBuffer; class DummyPort { protected: - DummyPort (const std::string&, PortFlags); + DummyPort (DummyAudioBackend &b, const std::string&, PortFlags); public: virtual ~DummyPort (); @@ -100,6 +102,7 @@ class DummyPort { } private: + DummyAudioBackend &_dummy_backend; std::string _name; const PortFlags _flags; LatencyRange _capture_latency_range; @@ -113,7 +116,7 @@ class DummyPort { class DummyAudioPort : public DummyPort { public: - DummyAudioPort (const std::string&, PortFlags); + DummyAudioPort (DummyAudioBackend &b, const std::string&, PortFlags); ~DummyAudioPort (); DataType type () const { return DataType::AUDIO; }; @@ -128,7 +131,7 @@ class DummyAudioPort : public DummyPort { class DummyMidiPort : public DummyPort { public: - DummyMidiPort (const std::string&, PortFlags); + DummyMidiPort (DummyAudioBackend &b, const std::string&, PortFlags); ~DummyMidiPort (); DataType type () const { return DataType::MIDI; }; @@ -141,6 +144,7 @@ class DummyMidiPort : public DummyPort { }; // class DummyMidiPort class DummyAudioBackend : public AudioBackend { + friend class DummyPort; public: DummyAudioBackend (AudioEngine& e, AudioBackendInfo& info); ~DummyAudioBackend (); @@ -312,9 +316,29 @@ class DummyAudioBackend : public AudioBackend { std::vector _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 _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::const_iterator it = _ports.begin (); it != _ports.end (); ++it) { if ((*it)->name () == port_name) {