From f9a66347152ad4459a564d5f92fdeabb6d8b4019 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 14 Jan 2007 04:22:16 +0000 Subject: Follow Jack port creation/destruction. git-svn-id: http://svn.drobilla.net/lad/patchage@257 a436a847-0d15-0410-975c-d299462d15a1 --- src/JackDriver.cpp | 28 ++++++++--------- src/JackDriver.h | 30 ++++++++----------- src/LashDriver.cpp | 6 ++-- src/Makefile.am | 2 ++ src/Patchage.cpp | 30 ++++++++++++++++++- src/Patchage.h | 6 ++++ src/PatchageEvent.cpp | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/PatchageEvent.h | 60 +++++++++++++++++++++++++++++++++++++ src/patchage.glade | 33 ++++++++++---------- 9 files changed, 225 insertions(+), 53 deletions(-) create mode 100644 src/PatchageEvent.cpp create mode 100644 src/PatchageEvent.h diff --git a/src/JackDriver.cpp b/src/JackDriver.cpp index 0add9da..ddb6744 100644 --- a/src/JackDriver.cpp +++ b/src/JackDriver.cpp @@ -23,6 +23,7 @@ #include #include #include "PatchageFlowCanvas.h" +#include "PatchageEvent.h" #include "JackDriver.h" #include "Patchage.h" #include "PatchageModule.h" @@ -36,6 +37,7 @@ using namespace LibFlowCanvas; JackDriver::JackDriver(Patchage* app) : m_app(app) , m_client(NULL) +, m_events(1024) // FIXME: size? , m_is_activated(false) , m_xruns(0) , m_xrun_delay(0) @@ -134,9 +136,11 @@ 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; @@ -233,7 +237,7 @@ JackDriver::refresh() // Remove any since-removed ports - for (list::iterator i = m_removed_ports.begin(); i != m_removed_ports.end(); ++i) { + /*for (list::iterator i = m_removed_ports.begin(); i != m_removed_ports.end(); ++i) { const string module_name = (*i).substr(0, i->find(":")); const string port_name = (*i).substr(i->find(":")+1); @@ -241,7 +245,7 @@ JackDriver::refresh() if (m->second->name() == module_name) m->second->remove_port(port_name); } - } + }*/ // Add all connections @@ -337,7 +341,7 @@ JackDriver::update_time() void -JackDriver::jack_port_registration_cb(jack_port_id_t port_id, int /*registered*/, void* jack_driver) +JackDriver::jack_port_registration_cb(jack_port_id_t port_id, int registered, void* jack_driver) { assert(jack_driver); JackDriver* me = reinterpret_cast(jack_driver); @@ -348,17 +352,13 @@ JackDriver::jack_port_registration_cb(jack_port_id_t port_id, int /*registered*/ jack_reset_max_delayed_usecs(me->m_client); - //(me->m_mutex).lock(); - - /*if (registered) { - me->m_added_ports.push_back(full_name); + if (registered) { + me->m_events.push(PatchageEvent(me->m_app, + PatchageEvent::PORT_CREATION, port_id)); } else { - me->m_removed_ports.push_back(full_name); - }*/ - - me->m_is_dirty = true; - - //(me->m_mutex).unlock(); + me->m_events.push(PatchageEvent(me->m_app, + PatchageEvent::PORT_DESTRUCTION, port_id)); + } } @@ -371,9 +371,7 @@ JackDriver::jack_graph_order_cb(void* jack_driver) jack_reset_max_delayed_usecs(me->m_client); - //(me->m_mutex).lock(); me->m_is_dirty = true; - //(me->m_mutex).unlock(); return 0; } diff --git a/src/JackDriver.h b/src/JackDriver.h index c581df0..c37970c 100644 --- a/src/JackDriver.h +++ b/src/JackDriver.h @@ -22,9 +22,10 @@ #include #include #include -#include +#include #include "Driver.h" class Patchage; +class PatchageEvent; class PatchageFlowCanvas; class PatchagePort; class PatchageModule; @@ -48,6 +49,9 @@ public: bool is_attached() const { return (m_client != NULL); } bool is_realtime() const { return m_client && jack_is_realtime(m_client); } + + Queue& events() { return m_events; } + void refresh(); bool connect(boost::shared_ptr src, @@ -69,7 +73,7 @@ public: jack_transport_reposition(m_client, &zero); } - //jack_client_t* client() { return m_client; } + jack_client_t* client() { return m_client; } jack_nframes_t buffer_size(); void set_buffer_size(jack_nframes_t size); @@ -82,11 +86,11 @@ public: inline float max_delay() { return jack_get_max_delayed_usecs(m_client); } -private: - boost::shared_ptr create_port(boost::shared_ptr parent, jack_port_t* port); +private: + static void error_cb(const char* msg); void destroy_all_ports(); @@ -100,23 +104,15 @@ private: static void jack_shutdown_cb(void* me); Patchage* m_app; - jack_client_t* m_client; - bool m_is_activated; - - //Mutex m_mutex; - - list m_added_ports; - list m_removed_ports; + Queue m_events; + bool m_is_activated; jack_position_t m_last_pos; - - jack_nframes_t m_buffer_size; - size_t m_xruns; - float m_xrun_delay; - - bool m_settings_changed; + jack_nframes_t m_buffer_size; + size_t m_xruns; + float m_xrun_delay; }; diff --git a/src/LashDriver.cpp b/src/LashDriver.cpp index 759c718..147cb1c 100644 --- a/src/LashDriver.cpp +++ b/src/LashDriver.cpp @@ -97,10 +97,10 @@ void LashDriver::handle_event(lash_event_t* ev) { LASH_Event_Type type = lash_event_get_type(ev); - const char* c_str = lash_event_get_string(ev); - string str = (c_str == NULL) ? "" : c_str; + const char* c_str = lash_event_get_string(ev); + string str = (c_str == NULL) ? "" : c_str; - cout << "[LashDriver] LASH Event. Type = " << (unsigned int)type << ", string = " << str << "**********" << endl; + //cout << "[LashDriver] LASH Event. Type = " << (unsigned int)type << ", string = " << str << "**********" << endl; switch (type) { case LASH_Project_Add: diff --git a/src/Makefile.am b/src/Makefile.am index 8a63179..97973d4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,6 +20,8 @@ patchage_SOURCES = \ PatchageModule.h \ PatchagePort.h \ Driver.h \ + PatchageEvent.h \ + PatchageEvent.cpp \ JackDriver.h \ JackDriver.cpp \ PatchageFlowCanvas.h \ diff --git a/src/Patchage.cpp b/src/Patchage.cpp index 357f334..4cf16d5 100644 --- a/src/Patchage.cpp +++ b/src/Patchage.cpp @@ -16,6 +16,7 @@ #include #include "Patchage.h" +#include "PatchageEvent.h" #include "config.h" #include #include @@ -135,6 +136,9 @@ Patchage::Patchage(int argc, char** argv) xml->get_widget("connect_to_jack_menuitem", m_menu_jack_connect); xml->get_widget("disconnect_from_jack_menuitem", m_menu_jack_disconnect); #ifdef HAVE_LASH + xml->get_widget("open_session_menuitem", m_menu_open_session); + xml->get_widget("save_session_menuitem", m_menu_save_session); + xml->get_widget("save_session_as_menuitem", m_menu_save_session_as); xml->get_widget("launch_lash_menuitem", m_menu_lash_launch); xml->get_widget("connect_to_lash_menuitem", m_menu_lash_connect); xml->get_widget("disconnect_from_lash_menuitem", m_menu_lash_disconnect); @@ -207,6 +211,9 @@ Patchage::Patchage(int argc, char** argv) m_menu_jack_disconnect->signal_activate().connect(sigc::mem_fun(m_jack_driver, &JackDriver::detach)); #ifdef HAVE_LASH + m_menu_open_session->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_open_session)); + m_menu_save_session->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_save_session)); + m_menu_save_session_as->signal_activate().connect(sigc::mem_fun(this, &Patchage::menu_save_session_as)); m_menu_lash_launch->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_lash_launch)); m_menu_lash_connect->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_lash_connect)); m_menu_lash_disconnect->signal_activate().connect(sigc::mem_fun(this, &Patchage::menu_lash_disconnect)); @@ -215,7 +222,7 @@ Patchage::Patchage(int argc, char** argv) m_menu_alsa_connect->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_alsa_connect)); m_menu_alsa_disconnect->signal_activate().connect(sigc::mem_fun(this, &Patchage::menu_alsa_disconnect)); #endif - m_menu_store_positions->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_store_positions)); + m_menu_store_positions->signal_activate().connect(sigc::mem_fun(this, &Patchage::menu_store_positions)); m_menu_file_quit->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_file_quit)); m_menu_view_refresh->signal_activate().connect( sigc::mem_fun(this, &Patchage::menu_view_refresh)); m_menu_view_messages->signal_toggled().connect( sigc::mem_fun(this, &Patchage::show_messages_toggled)); @@ -287,6 +294,11 @@ Patchage::attach() bool Patchage::idle_callback() { + if (m_jack_driver) + while (m_jack_driver->events().fill() > 0) + m_jack_driver->events().pop().execute(); + + bool refresh = m_refresh; refresh = refresh || (m_jack_driver && m_jack_driver->is_dirty()); @@ -295,6 +307,7 @@ Patchage::idle_callback() #endif if (refresh) { + m_canvas->flag_all_connections(); m_jack_driver->refresh(); @@ -500,6 +513,21 @@ Patchage::connect_widgets() #ifdef HAVE_LASH +void +Patchage::menu_open_session() +{ +} + +void +Patchage::menu_save_session() +{ +} + +void +Patchage::menu_save_session_as() +{ +} + void Patchage::menu_lash_launch() { diff --git a/src/Patchage.h b/src/Patchage.h index 46d134a..5c23dff 100644 --- a/src/Patchage.h +++ b/src/Patchage.h @@ -92,9 +92,15 @@ protected: #ifdef HAVE_LASH LashDriver* m_lash_driver; + Gtk::MenuItem* m_menu_open_session; + Gtk::MenuItem* m_menu_save_session; + Gtk::MenuItem* m_menu_save_session_as; Gtk::MenuItem* m_menu_lash_launch; Gtk::MenuItem* m_menu_lash_connect; Gtk::MenuItem* m_menu_lash_disconnect; + void menu_open_session(); + void menu_save_session(); + void menu_save_session_as(); void menu_lash_launch(); void menu_lash_connect(); void menu_lash_disconnect(); diff --git a/src/PatchageEvent.cpp b/src/PatchageEvent.cpp new file mode 100644 index 0000000..456756c --- /dev/null +++ b/src/PatchageEvent.cpp @@ -0,0 +1,83 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Patchage is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Patchage is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "raul/SharedPtr.h" +#include "Patchage.h" +#include "PatchageFlowCanvas.h" +#include "PatchageModule.h" +#include "PatchageEvent.h" +#include "JackDriver.h" + +void +PatchageEvent::execute() +{ + //cerr << "{ EXECUTING EVENT" << endl; + + jack_port_t* const jack_port = jack_port_by_id(_patchage->jack_driver()->client(), _port_id); + 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 = PtrCast( + _patchage->canvas()->get_module(module_name)); + + if (_type == PORT_CREATION) { + + if (!module) { + module = boost::shared_ptr( + new PatchageModule(_patchage, module_name, InputOutput)); + module->load_location(); + module->store_location(); + _patchage->canvas()->add_module(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(); + } + + } else if (_type == PORT_DESTRUCTION) { + + if (!module) { + cerr << "Unable to find module for port " << full_name << endl; + return; + } + + boost::shared_ptr port = PtrCast( + module->remove_port(full_name.substr(full_name.find(":")+1))); + + if (!port) + cerr << "Destroy port: Unable to find port " << full_name << endl; + else { + //cerr << "Destroyed port " << full_name << endl; + port->hide(); + port.reset(); // FIXME: leak? + } + + } + + if (module->num_ports() == 0) { + _patchage->canvas()->remove_module(module->name()); // FIXME: slow + module->hide(); + module.reset(); + } + + //cerr << "}" << endl << endl; +} diff --git a/src/PatchageEvent.h b/src/PatchageEvent.h new file mode 100644 index 0000000..8dec31d --- /dev/null +++ b/src/PatchageEvent.h @@ -0,0 +1,60 @@ +/* This file is part of Patchage. Copyright (C) 2005 Dave Robillard. + * + * Patchage is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation; either version 2 of the License, or (at your option) any later + * version. + * + * Patchage is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PATCHAGEEVENT_H +#define PATCHAGEEVENT_H + +#include +#include + +class Patchage; + + +/** A Driver event to be processed by the GUI thread. + */ +class PatchageEvent { +public: + enum Type { + NULL_EVENT, + PORT_CREATION, + PORT_DESTRUCTION + }; + + PatchageEvent(Patchage* patchage) + : _patchage(patchage) + , _type(NULL_EVENT) + {} + + PatchageEvent(Patchage* patchage, Type type, jack_port_id_t port_id) + : _patchage(patchage) + , _type(type) + , _port_id(port_id) + {} + + void execute(); + + Type type() { return _type; } + jack_port_id_t port_id() { return _port_id; } + +private: + Patchage* _patchage; + Type _type; + jack_port_id_t _port_id; +}; + + +#endif // PATCHAGEEVENT_H + diff --git a/src/patchage.glade b/src/patchage.glade index b84c31b..48e9220 100644 --- a/src/patchage.glade +++ b/src/patchage.glade @@ -52,7 +52,7 @@ - + True gtk-open 1 @@ -74,7 +74,7 @@ - + True gtk-save 1 @@ -90,13 +90,13 @@ True - Save Session _As + Save Session _As... True - + True gtk-save-as 1 @@ -119,13 +119,12 @@ True Store the current module positions as the defaults - _Store Positions + _Save Layout as Default True - - + True gtk-save 1 @@ -175,7 +174,7 @@ - + True gtk-preferences 1 @@ -203,7 +202,7 @@ - + True gtk-execute 1 @@ -225,7 +224,7 @@ - + True gtk-connect 1 @@ -248,7 +247,7 @@ - + True gtk-disconnect 1 @@ -276,7 +275,7 @@ - + True gtk-connect 1 @@ -299,7 +298,7 @@ - + True gtk-disconnect 1 @@ -327,7 +326,7 @@ - + True gtk-execute 1 @@ -349,7 +348,7 @@ - + True gtk-connect 1 @@ -372,7 +371,7 @@ - + True gtk-disconnect 1 @@ -419,7 +418,7 @@ - + True gtk-refresh 1 -- cgit v1.2.1