From bbb3abbe4b86a23ef884d38ca299aff13b8f9242 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 17 Feb 2008 22:00:26 +0000 Subject: Remove Jack API dependence from PatchageEvent. git-svn-id: http://svn.drobilla.net/lad/patchage@1151 a436a847-0d15-0410-975c-d299462d15a1 --- src/AlsaDriver.cpp | 30 ++++++++++-- src/AlsaDriver.hpp | 8 ++++ src/Driver.hpp | 9 ++++ src/JackDriver.cpp | 123 +++++++++++++++++++++++++++++++++++++++++--------- src/JackDriver.hpp | 21 +++++++-- src/LashDriver.hpp | 12 +++++ src/PatchageEvent.cpp | 85 ++++------------------------------ src/PatchageEvent.hpp | 24 +++++----- 8 files changed, 196 insertions(+), 116 deletions(-) diff --git a/src/AlsaDriver.cpp b/src/AlsaDriver.cpp index fc5f5d1..aeca506 100644 --- a/src/AlsaDriver.cpp +++ b/src/AlsaDriver.cpp @@ -97,6 +97,14 @@ AlsaDriver::refresh() refresh_connections(); } + +boost::shared_ptr +AlsaDriver::create_port_view(Patchage* patchage, + const PatchageEvent::PortRef& ref) +{ + return boost::shared_ptr(); +} + boost::shared_ptr AlsaDriver::create_port(boost::shared_ptr parent, @@ -319,6 +327,22 @@ AlsaDriver::add_connections(boost::shared_ptr port) } +/** Find the PatchagePort that corresponds to an Alsa Sequencer port. + * + * This function is not realtime safe, but safe to call from the GUI thread + * (e.g. in PatchageEvent::execute). + */ +boost::shared_ptr +AlsaDriver::find_port_view(Patchage* patchage, + const PatchageEvent::PortRef& ref) +{ + if (ref.type == PatchageEvent::PortRef::ALSA_ADDR) + return patchage->canvas()->find_port(ref.id.alsa_addr, ref.is_input); + else + return boost::shared_ptr(); +} + + /** Connects two Alsa Midi ports. * * \return Whether connection succeeded. @@ -497,11 +521,11 @@ AlsaDriver::_refresh_main() switch (ev->type) { case SND_SEQ_EVENT_PORT_SUBSCRIBED: - _events.push(PatchageEvent(PatchageEvent::CONNECTION, + _events.push(PatchageEvent(this, PatchageEvent::CONNECTION, ev->data.connect.sender, ev->data.connect.dest)); break; case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: - _events.push(PatchageEvent(PatchageEvent::DISCONNECTION, + _events.push(PatchageEvent(this, PatchageEvent::DISCONNECTION, ev->data.connect.sender, ev->data.connect.dest)); break; case SND_SEQ_EVENT_PORT_START: @@ -513,7 +537,7 @@ AlsaDriver::_refresh_main() case SND_SEQ_EVENT_RESET: default: // FIXME: Ultra slow kludge, use proper find-grained events - _events.push(PatchageEvent(PatchageEvent::REFRESH)); + _events.push(PatchageEvent(this, PatchageEvent::REFRESH)); } } } diff --git a/src/AlsaDriver.hpp b/src/AlsaDriver.hpp index 9e9f2ea..8caf911 100644 --- a/src/AlsaDriver.hpp +++ b/src/AlsaDriver.hpp @@ -41,6 +41,14 @@ public: bool is_attached() const { return (_seq != NULL); } void refresh(); + + boost::shared_ptr find_port_view( + Patchage* patchage, + const PatchageEvent::PortRef& ref); + + boost::shared_ptr create_port_view( + Patchage* patchage, + const PatchageEvent::PortRef& ref); bool connect(boost::shared_ptr src_port, boost::shared_ptr dst_port); diff --git a/src/Driver.hpp b/src/Driver.hpp index 5d0c59d..820e7eb 100644 --- a/src/Driver.hpp +++ b/src/Driver.hpp @@ -24,6 +24,7 @@ #include "PatchageEvent.hpp" class PatchagePort; +class PatchageCanvas; /** Trival driver base class */ class Driver { @@ -35,6 +36,14 @@ public: virtual bool is_attached() const = 0; virtual void refresh() = 0; + + virtual boost::shared_ptr create_port_view( + Patchage* patchage, + const PatchageEvent::PortRef& ref) = 0; + + virtual boost::shared_ptr find_port_view( + Patchage* patchage, + const PatchageEvent::PortRef& ref) = 0; virtual bool connect(boost::shared_ptr src_port, boost::shared_ptr dst_port) = 0; diff --git a/src/JackDriver.cpp b/src/JackDriver.cpp index adf380c..3a57047 100644 --- a/src/JackDriver.cpp +++ b/src/JackDriver.cpp @@ -137,6 +137,45 @@ JackDriver::destroy_all_ports() module->resize(); } } + + +boost::shared_ptr +JackDriver::create_port_view(Patchage* patchage, + const PatchageEvent::PortRef& ref) +{ + jack_port_t* jack_port = NULL; + + if (ref.type == PatchageEvent::PortRef::JACK_PORT) + jack_port = ref.id.jack_port; + else if (ref.type == PatchageEvent::PortRef::JACK_ID) + jack_port = jack_port_by_id(_client, ref.id.jack_id); + + string module_name, port_name; + port_names(ref, module_name, port_name); + boost::shared_ptr parent + = _app->canvas()->find_module(module_name, InputOutput); + + if (!parent) { + parent = boost::shared_ptr( + new PatchageModule(patchage, module_name, InputOutput)); + parent->load_location(); + patchage->canvas()->add_item(parent); + parent->show(); + } + + boost::shared_ptr port + = boost::dynamic_pointer_cast(parent->get_port(port_name)); + + if (port) { + return port; + } else { + port = create_port(parent, jack_port); + port->show(); + parent->add_port(port); + parent->resize(); + return port; + } +} boost::shared_ptr @@ -147,19 +186,15 @@ JackDriver::create_port(boost::shared_ptr parent, jack_port_t* p if (!strcmp(type_str, JACK_DEFAULT_AUDIO_TYPE)) { port_type = JACK_AUDIO; - //cerr << "TYPE: AUDIO\n"; #ifdef HAVE_JACK_MIDI } else if (!strcmp(type_str, JACK_DEFAULT_MIDI_TYPE)) { port_type = JACK_MIDI; - //cerr << "TYPE: MIDI\n"; #endif } else { cerr << "WARNING: " << jack_port_name(port) << " has unknown type \'" << type_str << "\'" << endl; return boost::shared_ptr(); } - //cerr << "Port " << jack_port_name(port) << " type: " << type_str << " = " << (int)port_type << endl; - boost::shared_ptr ret( new PatchagePort(parent, port_type, jack_port_short_name(port), (jack_port_flags(port) & JackPortIsInput), @@ -320,6 +355,65 @@ JackDriver::refresh() } +bool +JackDriver::port_names(const PatchageEvent::PortRef& ref, + string& module_name, + string& port_name) +{ + jack_port_t* jack_port = NULL; + + if (ref.type == PatchageEvent::PortRef::JACK_PORT) + jack_port = ref.id.jack_port; + else if (ref.type == PatchageEvent::PortRef::JACK_ID) + jack_port = jack_port_by_id(_client, ref.id.jack_id); + + if (!jack_port) { + module_name = ""; + port_name = ""; + return false; + } + + const string full_name = jack_port_name(jack_port); + + module_name = full_name.substr(0, full_name.find(":")); + port_name = full_name.substr(full_name.find(":")+1); + + return true; +} + + +/** Find the PatchagePort that corresponds to a JACK port. + * + * This function is not realtime safe, but safe to call from the GUI thread + * (e.g. in PatchageEvent::execute). + */ +boost::shared_ptr +JackDriver::find_port_view(Patchage* patchage, + const PatchageEvent::PortRef& ref) +{ + jack_port_t* jack_port = NULL; + + if (ref.type == PatchageEvent::PortRef::JACK_PORT) + jack_port = ref.id.jack_port; + else if (ref.type == PatchageEvent::PortRef::JACK_ID) + jack_port = jack_port_by_id(_client, ref.id.jack_id); + + if (!jack_port) + return boost::shared_ptr(); + + string module_name, port_name; + port_names(ref, module_name, port_name); + + SharedPtr module = patchage->canvas()->find_module(module_name, + (jack_port_flags(jack_port) & JackPortIsInput) ? Input : Output); + + if (module) + return PtrCast(module->get_port(port_name)); + else + return boost::shared_ptr(); +} + + /** Connects two Jack audio ports. * To be called from GTK thread only. * \return Whether connection succeeded. @@ -366,12 +460,6 @@ JackDriver::disconnect(boost::shared_ptr const src_port, boost::sh } -void -JackDriver::update_time() -{ -} - - void JackDriver::jack_port_registration_cb(jack_port_id_t port_id, int registered, void* jack_driver) { @@ -385,9 +473,9 @@ JackDriver::jack_port_registration_cb(jack_port_id_t port_id, int registered, vo jack_reset_max_delayed_usecs(me->_client); if (registered) { - me->_events.push(PatchageEvent(PatchageEvent::PORT_CREATION, port_id)); + me->_events.push(PatchageEvent(me, PatchageEvent::PORT_CREATION, port_id)); } else { - me->_events.push(PatchageEvent(PatchageEvent::PORT_DESTRUCTION, port_id)); + me->_events.push(PatchageEvent(me, PatchageEvent::PORT_DESTRUCTION, port_id)); } } @@ -402,9 +490,9 @@ JackDriver::jack_port_connect_cb(jack_port_id_t src, jack_port_id_t dst, int con jack_reset_max_delayed_usecs(me->_client); if (connect) { - me->_events.push(PatchageEvent(PatchageEvent::CONNECTION, src, dst)); + me->_events.push(PatchageEvent(me, PatchageEvent::CONNECTION, src, dst)); } else { - me->_events.push(PatchageEvent(PatchageEvent::DISCONNECTION, src, dst)); + me->_events.push(PatchageEvent(me, PatchageEvent::DISCONNECTION, src, dst)); } } @@ -431,11 +519,9 @@ JackDriver::jack_buffer_size_cb(jack_nframes_t buffer_size, void* jack_driver) jack_reset_max_delayed_usecs(me->_client); - //(me->_mutex).lock(); me->_buffer_size = buffer_size; me->reset_xruns(); me->reset_delay(); - //(me->_mutex).unlock(); return 0; } @@ -448,14 +534,9 @@ JackDriver::jack_xrun_cb(void* jack_driver) JackDriver* me = reinterpret_cast(jack_driver); assert(me->_client); - //(me->_mutex).lock(); me->_xruns++; me->_xrun_delay = jack_get_xrun_delayed_usecs(me->_client); jack_reset_max_delayed_usecs(me->_client); - - //cerr << "** XRUN Delay = " << me->_xrun_delay << endl; - - //(me->_mutex).unlock(); return 0; } diff --git a/src/JackDriver.hpp b/src/JackDriver.hpp index b66e4ee..3569255 100644 --- a/src/JackDriver.hpp +++ b/src/JackDriver.hpp @@ -51,6 +51,18 @@ public: void refresh(); + bool port_names(const PatchageEvent::PortRef& ref, + std::string& module_name, + std::string& port_name); + + boost::shared_ptr find_port_view( + Patchage* patchage, + const PatchageEvent::PortRef& ref); + + boost::shared_ptr create_port_view( + Patchage* patchage, + const PatchageEvent::PortRef& ref); + bool connect(boost::shared_ptr src, boost::shared_ptr dst); @@ -81,18 +93,17 @@ public: inline float max_delay() { return jack_get_max_delayed_usecs(_client); } - boost::shared_ptr create_port(boost::shared_ptr parent, - jack_port_t* port); - private: + + boost::shared_ptr create_port( + boost::shared_ptr parent, + jack_port_t* port); static void error_cb(const char* msg); void destroy_all_ports(); void shutdown(); - void update_time(); - static void jack_port_registration_cb(jack_port_id_t port_id, int registered, void* me); static void jack_port_connect_cb(jack_port_id_t src, jack_port_id_t dst, int connect, void* me); static int jack_graph_order_cb(void* me); diff --git a/src/LashDriver.hpp b/src/LashDriver.hpp index 4cca58d..c1d648d 100644 --- a/src/LashDriver.hpp +++ b/src/LashDriver.hpp @@ -35,6 +35,18 @@ public: bool is_attached() const { return _server_interface && _server_interface->enabled(); } + boost::shared_ptr find_port_view( + Patchage* patchage, + const PatchageEvent::PortRef& ref) { + return boost::shared_ptr(); + } + + boost::shared_ptr create_port_view( + Patchage* patchage, + const PatchageEvent::PortRef& ref) { + return boost::shared_ptr(); + } + bool connect(boost::shared_ptr, boost::shared_ptr) { return false; } diff --git a/src/PatchageEvent.cpp b/src/PatchageEvent.cpp index 7877200..da64899 100644 --- a/src/PatchageEvent.cpp +++ b/src/PatchageEvent.cpp @@ -21,92 +21,25 @@ #include "PatchageCanvas.hpp" #include "PatchageModule.hpp" #include "PatchageEvent.hpp" -#include "JackDriver.hpp" +#include "Driver.hpp" using namespace std; - -SharedPtr -PatchageEvent::find_port(const Patchage* patchage, const PortRef& ref) -{ - if (ref.type == PortRef::NULL_PORT_REF) - return boost::shared_ptr(); - -#ifdef HAVE_ALSA - if (ref.type == PortRef::ALSA_ADDR) { - return patchage->canvas()->find_port(ref.id.alsa_addr, ref.is_input); - } else -#endif - { - if (!patchage->jack_driver()->client()) - return boost::shared_ptr(); - - jack_port_t* jack_port = NULL; - - if (ref.type == PortRef::JACK_PORT) - jack_port = ref.id.jack_port; - else if (ref.type == PortRef::JACK_ID) - jack_port = jack_port_by_id(patchage->jack_driver()->client(), ref.id.jack_id); - - if (!jack_port) - return boost::shared_ptr(); - - const string full_name = jack_port_name(jack_port); - const string module_name = full_name.substr(0, full_name.find(":")); - const string port_name = full_name.substr(full_name.find(":")+1); - - SharedPtr module = patchage->canvas()->find_module(module_name, - (jack_port_flags(jack_port) & JackPortIsInput) ? Input : Output); - - if (module) - return PtrCast(module->get_port(port_name)); - else - return boost::shared_ptr(); - } - - return boost::shared_ptr(); -} - void PatchageEvent::execute(Patchage* patchage) { - if (_type == REFRESH) { + if (_type == REFRESH) { patchage->refresh(); } else if (_type == PORT_CREATION) { - jack_port_t* jack_port = NULL; - if (patchage->jack_driver()->client()) - jack_port = jack_port_by_id(patchage->jack_driver()->client(), _port_1.id.jack_id); - - if (!jack_port) - return; - - const string full_name = jack_port_name(jack_port); - const string module_name = full_name.substr(0, full_name.find(":")); - const string port_name = full_name.substr(full_name.find(":")+1); - - SharedPtr module = patchage->canvas()->find_module(module_name, - (jack_port_flags(jack_port) & JackPortIsInput) ? Input : Output); - if (!module) { - module = SharedPtr( - new PatchageModule(patchage, module_name, InputOutput)); - module->load_location(); - patchage->canvas()->add_item(module); - module->show(); - } - - boost::shared_ptr port = PtrCast( - module->get_port(port_name)); - if (!port) { - port = patchage->jack_driver()->create_port(module, jack_port); - module->add_port(port); - module->resize(); + if ( ! _driver->create_port_view(patchage, _port_1)) { + cerr << "Unable to create port view (already exists?" << endl; } } else if (_type == PORT_DESTRUCTION) { - SharedPtr port = find_port(patchage, _port_1); + SharedPtr port = _driver->find_port_view(patchage, _port_1); if (port) { SharedPtr module = PtrCast(port->module().lock()); @@ -128,8 +61,8 @@ PatchageEvent::execute(Patchage* patchage) } else if (_type == CONNECTION) { - SharedPtr port_1 = find_port(patchage, _port_1); - SharedPtr port_2 = find_port(patchage, _port_2); + SharedPtr port_1 = _driver->find_port_view(patchage, _port_1); + SharedPtr port_2 = _driver->find_port_view(patchage, _port_2); if (port_1 && port_2) patchage->canvas()->add_connection(port_1, port_2, port_1->color() + 0x22222200); @@ -138,8 +71,8 @@ PatchageEvent::execute(Patchage* patchage) } else if (_type == DISCONNECTION) { - SharedPtr port_1 = find_port(patchage, _port_1); - SharedPtr port_2 = find_port(patchage, _port_2); + SharedPtr port_1 = _driver->find_port_view(patchage, _port_1); + SharedPtr port_2 = _driver->find_port_view(patchage, _port_2); if (port_1 && port_2) patchage->canvas()->remove_connection(port_1, port_2); diff --git a/src/PatchageEvent.hpp b/src/PatchageEvent.hpp index 0d982bf..bffc3c8 100644 --- a/src/PatchageEvent.hpp +++ b/src/PatchageEvent.hpp @@ -26,6 +26,7 @@ #include "PatchagePort.hpp" class Patchage; +class Driver; /** A Driver event to be processed by the GUI thread. @@ -41,29 +42,29 @@ public: DISCONNECTION }; - PatchageEvent(Type type=NULL_EVENT) - : _type(type) + PatchageEvent(Driver* d = NULL, Type type=NULL_EVENT) + : _driver(d) + , _type(type) {} template - PatchageEvent(Type type, P port) - : _type(type) + PatchageEvent(Driver* driver, Type type, P port) + : _driver(driver) , _port_1(port) + , _type(type) {} template - PatchageEvent(Type type, P port_1, P port_2) - : _type(type) + PatchageEvent(Driver* driver, Type type, P port_1, P port_2) + : _driver(driver) , _port_1(port_1, false) , _port_2(port_2, true) + , _type(type) {} void execute(Patchage* patchage); inline Type type() const { return (Type)_type; } - -private: - uint8_t _type; struct PortRef { PortRef() : type(NULL_PORT_REF) { memset(&id, 0, sizeof(id)); } @@ -92,10 +93,11 @@ private: } id; }; +private: + Driver* _driver; PortRef _port_1; PortRef _port_2; - - boost::shared_ptr find_port(const Patchage* patchage, const PortRef& ref); + uint8_t _type; }; -- cgit v1.2.1