summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-01-14 04:22:16 +0000
committerDavid Robillard <d@drobilla.net>2007-01-14 04:22:16 +0000
commitf9a66347152ad4459a564d5f92fdeabb6d8b4019 (patch)
tree8ab4ed5436a83bbad634773d5b3b96428f77d85e /src
parent8e946da143030272b1bb325aba1ea52e67792254 (diff)
downloadpatchage-f9a66347152ad4459a564d5f92fdeabb6d8b4019.tar.gz
patchage-f9a66347152ad4459a564d5f92fdeabb6d8b4019.tar.bz2
patchage-f9a66347152ad4459a564d5f92fdeabb6d8b4019.zip
Follow Jack port creation/destruction.
git-svn-id: http://svn.drobilla.net/lad/patchage@257 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/JackDriver.cpp28
-rw-r--r--src/JackDriver.h30
-rw-r--r--src/LashDriver.cpp6
-rw-r--r--src/Makefile.am2
-rw-r--r--src/Patchage.cpp30
-rw-r--r--src/Patchage.h6
-rw-r--r--src/PatchageEvent.cpp83
-rw-r--r--src/PatchageEvent.h60
-rw-r--r--src/patchage.glade33
9 files changed, 225 insertions, 53 deletions
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 <jack/statistics.h>
#include <jack/thread.h>
#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<PatchageModule> 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<string>::iterator i = m_removed_ports.begin(); i != m_removed_ports.end(); ++i) {
+ /*for (list<string>::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<JackDriver*>(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 <boost/shared_ptr.hpp>
#include <jack/jack.h>
#include <jack/statistics.h>
-#include <raul/Mutex.h>
+#include <raul/Queue.h>
#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<PatchageEvent>& events() { return m_events; }
+
void refresh();
bool connect(boost::shared_ptr<PatchagePort> 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<PatchagePort> create_port(boost::shared_ptr<PatchageModule> 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<string> m_added_ports;
- list<string> m_removed_ports;
+ Queue<PatchageEvent> 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 <cmath>
#include "Patchage.h"
+#include "PatchageEvent.h"
#include "config.h"
#include <libgnomecanvasmm.h>
#include <libglademm/xml.h>
@@ -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();
@@ -501,6 +514,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()
{
m_lash_driver->attach(true);
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<PatchageModule> module = PtrCast<PatchageModule>(
+ _patchage->canvas()->get_module(module_name));
+
+ if (_type == PORT_CREATION) {
+
+ if (!module) {
+ module = boost::shared_ptr<PatchageModule>(
+ new PatchageModule(_patchage, module_name, InputOutput));
+ module->load_location();
+ module->store_location();
+ _patchage->canvas()->add_module(module);
+ module->show();
+ }
+
+ boost::shared_ptr<PatchagePort> port = PtrCast<PatchagePort>(
+ 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<PatchagePort> port = PtrCast<PatchagePort>(
+ 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 <string>
+#include <jack/jack.h>
+
+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 @@
<accelerator key="O" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image607">
+ <widget class="GtkImage" id="image662">
<property name="visible">True</property>
<property name="stock">gtk-open</property>
<property name="icon_size">1</property>
@@ -74,7 +74,7 @@
<accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image608">
+ <widget class="GtkImage" id="image663">
<property name="visible">True</property>
<property name="stock">gtk-save</property>
<property name="icon_size">1</property>
@@ -90,13 +90,13 @@
<child>
<widget class="GtkImageMenuItem" id="save_session_as_menuitem">
<property name="visible">True</property>
- <property name="label" translatable="yes">Save Session _As</property>
+ <property name="label" translatable="yes">Save Session _As...</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_save_session_as_menuitem_activate" last_modification_time="Sun, 01 Oct 2006 07:01:40 GMT"/>
<accelerator key="S" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image609">
+ <widget class="GtkImage" id="image664">
<property name="visible">True</property>
<property name="stock">gtk-save-as</property>
<property name="icon_size">1</property>
@@ -119,13 +119,12 @@
<widget class="GtkImageMenuItem" id="store_positions_menuitem">
<property name="visible">True</property>
<property name="tooltip" translatable="yes">Store the current module positions as the defaults</property>
- <property name="label" translatable="yes">_Store Positions</property>
+ <property name="label" translatable="yes">_Save Layout as Default</property>
<property name="use_underline">True</property>
<signal name="activate" handler="on_save_settings1_activate" last_modification_time="Mon, 13 Sep 2004 02:42:14 GMT"/>
- <accelerator key="S" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image610">
+ <widget class="GtkImage" id="image665">
<property name="visible">True</property>
<property name="stock">gtk-save</property>
<property name="icon_size">1</property>
@@ -175,7 +174,7 @@
<accelerator key="P" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image611">
+ <widget class="GtkImage" id="image666">
<property name="visible">True</property>
<property name="stock">gtk-preferences</property>
<property name="icon_size">1</property>
@@ -203,7 +202,7 @@
<accelerator key="J" modifiers="GDK_CONTROL_MASK | GDK_MOD1_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image612">
+ <widget class="GtkImage" id="image667">
<property name="visible">True</property>
<property name="stock">gtk-execute</property>
<property name="icon_size">1</property>
@@ -225,7 +224,7 @@
<accelerator key="J" modifiers="GDK_MOD1_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image613">
+ <widget class="GtkImage" id="image668">
<property name="visible">True</property>
<property name="stock">gtk-connect</property>
<property name="icon_size">1</property>
@@ -248,7 +247,7 @@
<accelerator key="J" modifiers="GDK_SHIFT_MASK | GDK_MOD1_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image614">
+ <widget class="GtkImage" id="image669">
<property name="visible">True</property>
<property name="stock">gtk-disconnect</property>
<property name="icon_size">1</property>
@@ -276,7 +275,7 @@
<accelerator key="A" modifiers="GDK_MOD1_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image615">
+ <widget class="GtkImage" id="image670">
<property name="visible">True</property>
<property name="stock">gtk-connect</property>
<property name="icon_size">1</property>
@@ -299,7 +298,7 @@
<accelerator key="A" modifiers="GDK_SHIFT_MASK | GDK_MOD1_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image616">
+ <widget class="GtkImage" id="image671">
<property name="visible">True</property>
<property name="stock">gtk-disconnect</property>
<property name="icon_size">1</property>
@@ -327,7 +326,7 @@
<accelerator key="L" modifiers="GDK_CONTROL_MASK | GDK_MOD1_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image617">
+ <widget class="GtkImage" id="image672">
<property name="visible">True</property>
<property name="stock">gtk-execute</property>
<property name="icon_size">1</property>
@@ -349,7 +348,7 @@
<accelerator key="L" modifiers="GDK_MOD1_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image618">
+ <widget class="GtkImage" id="image673">
<property name="visible">True</property>
<property name="stock">gtk-connect</property>
<property name="icon_size">1</property>
@@ -372,7 +371,7 @@
<accelerator key="L" modifiers="GDK_SHIFT_MASK | GDK_MOD1_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image619">
+ <widget class="GtkImage" id="image674">
<property name="visible">True</property>
<property name="stock">gtk-disconnect</property>
<property name="icon_size">1</property>
@@ -419,7 +418,7 @@
<accelerator key="R" modifiers="GDK_CONTROL_MASK" signal="activate"/>
<child internal-child="image">
- <widget class="GtkImage" id="image620">
+ <widget class="GtkImage" id="image675">
<property name="visible">True</property>
<property name="stock">gtk-refresh</property>
<property name="icon_size">1</property>