summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-01-07 17:51:18 +0000
committerDavid Robillard <d@drobilla.net>2007-01-07 17:51:18 +0000
commit813e0cbb39809d7cf837e6b91a75815079502f47 (patch)
tree7a01ea7c6f3959ba6c6f1ffeffa27919ddc04ba1
parent99ab1c257b7456c16f82119e1faea62c61eea660 (diff)
downloadingen-813e0cbb39809d7cf837e6b91a75815079502f47.tar.gz
ingen-813e0cbb39809d7cf837e6b91a75815079502f47.tar.bz2
ingen-813e0cbb39809d7cf837e6b91a75815079502f47.zip
Jack MIDI port destruction.
git-svn-id: http://svn.drobilla.net/lad/ingen@240 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/libs/engine/Driver.h11
-rw-r--r--src/libs/engine/JackAudioDriver.cpp2
-rw-r--r--src/libs/engine/JackMidiDriver.cpp76
-rw-r--r--src/libs/engine/JackMidiDriver.h41
-rw-r--r--src/libs/engine/MidiDriver.h3
-rw-r--r--src/libs/engine/events/AddPortEvent.cpp5
-rw-r--r--src/libs/engine/events/DestroyEvent.cpp7
7 files changed, 84 insertions, 61 deletions
diff --git a/src/libs/engine/Driver.h b/src/libs/engine/Driver.h
index 103c4fe6..e611eff8 100644
--- a/src/libs/engine/Driver.h
+++ b/src/libs/engine/Driver.h
@@ -19,6 +19,7 @@
#include <string>
#include <boost/utility.hpp>
+#include "raul/Path.h"
namespace Ingen {
@@ -40,8 +41,13 @@ public:
/** Set the name of the system port */
virtual void set_name(const std::string& name) = 0;
+ bool is_input() { return _is_input; }
+
protected:
- DriverPort() {}
+ /** is_input from the perspective outside of ingen */
+ DriverPort(bool is_input) : _is_input(is_input) {}
+
+ bool _is_input;
};
@@ -72,6 +78,9 @@ public:
* May return NULL if the Driver can not drive the port for some reason.
*/
virtual DriverPort* create_port(DuplexPort<T>* patch_port) = 0;
+
+ virtual void add_port(DriverPort* port) = 0;
+ virtual DriverPort* remove_port(const Path& path) = 0;
};
diff --git a/src/libs/engine/JackAudioDriver.cpp b/src/libs/engine/JackAudioDriver.cpp
index 87728e93..00c7afe6 100644
--- a/src/libs/engine/JackAudioDriver.cpp
+++ b/src/libs/engine/JackAudioDriver.cpp
@@ -47,7 +47,7 @@ namespace Ingen {
//// JackAudioPort ////
JackAudioPort::JackAudioPort(JackAudioDriver* driver, DuplexPort<Sample>* patch_port)
-: DriverPort(),
+: DriverPort(patch_port->is_input()),
ListNode<JackAudioPort*>(this),
_driver(driver),
_jack_port(NULL),
diff --git a/src/libs/engine/JackMidiDriver.cpp b/src/libs/engine/JackMidiDriver.cpp
index 55ba3522..c21484e3 100644
--- a/src/libs/engine/JackMidiDriver.cpp
+++ b/src/libs/engine/JackMidiDriver.cpp
@@ -20,6 +20,7 @@
#include <pthread.h>
#include "types.h"
#include "midi.h"
+#include "ThreadManager.h"
#include "Maid.h"
#include "AudioDriver.h"
#include "MidiMessage.h"
@@ -35,15 +36,15 @@ namespace Ingen {
//// JackMidiPort ////
JackMidiPort::JackMidiPort(JackMidiDriver* driver, DuplexPort<MidiMessage>* patch_port)
-: DriverPort(),
+: DriverPort(patch_port->is_input()),
ListNode<JackMidiPort*>(this),
- m_driver(driver),
- m_jack_port(NULL),
- m_patch_port(patch_port)
+ _driver(driver),
+ _jack_port(NULL),
+ _patch_port(patch_port)
{
assert(patch_port->poly() == 1);
- m_jack_port = jack_port_register(m_driver->jack_client(),
+ _jack_port = jack_port_register(_driver->jack_client(),
patch_port->path().c_str(), JACK_DEFAULT_MIDI_TYPE,
(patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput,
0);
@@ -55,7 +56,7 @@ JackMidiPort::JackMidiPort(JackMidiDriver* driver, DuplexPort<MidiMessage>* patc
JackMidiPort::~JackMidiPort()
{
- jack_port_unregister(m_driver->jack_client(), m_jack_port);
+ jack_port_unregister(_driver->jack_client(), _jack_port);
}
@@ -74,14 +75,14 @@ JackMidiPort::prepare_block(const SampleCount block_start, const SampleCount blo
assert(block_end >= block_start);
const SampleCount nframes = block_end - block_start;
- void* jack_buffer = jack_port_get_buffer(m_jack_port, nframes);
+ void* jack_buffer = jack_port_get_buffer(_jack_port, nframes);
const jack_nframes_t event_count = jack_midi_get_event_count(jack_buffer, nframes);
- assert(event_count < m_patch_port->buffer_size());
+ assert(event_count < _patch_port->buffer_size());
// Copy events from Jack port buffer into patch port buffer
for (jack_nframes_t i=0; i < event_count; ++i) {
- jack_midi_event_t* ev = (jack_midi_event_t*)&m_patch_port->buffer(0)->value_at(i);
+ jack_midi_event_t* ev = (jack_midi_event_t*)&_patch_port->buffer(0)->value_at(i);
jack_midi_event_get(ev, jack_buffer, i, nframes);
// Convert note ons with velocity 0 to proper note offs
@@ -89,7 +90,7 @@ JackMidiPort::prepare_block(const SampleCount block_start, const SampleCount blo
ev->buffer[0] = MIDI_CMD_NOTE_OFF;
// MidiMessage and jack_midi_event_t* are the same thing :/
- MidiMessage* const message = &m_patch_port->buffer(0)->data()[i];
+ MidiMessage* const message = &_patch_port->buffer(0)->data()[i];
message->time = ev->time;
message->size = ev->size;
message->buffer = ev->buffer;
@@ -97,8 +98,8 @@ JackMidiPort::prepare_block(const SampleCount block_start, const SampleCount blo
//cerr << "Jack MIDI got " << event_count << " events." << endl;
- m_patch_port->buffer(0)->filled_size(event_count);
- //m_patch_port->tied_port()->buffer(0)->filled_size(event_count);
+ _patch_port->buffer(0)->filled_size(event_count);
+ //_patch_port->tied_port()->buffer(0)->filled_size(event_count);
}
@@ -106,13 +107,13 @@ JackMidiPort::prepare_block(const SampleCount block_start, const SampleCount blo
//// JackMidiDriver ////
-bool JackMidiDriver::m_midi_thread_exit_flag = true;
+bool JackMidiDriver::_midi_thread_exit_flag = true;
JackMidiDriver::JackMidiDriver(jack_client_t* client)
-: m_client(client),
- m_is_activated(false),
- m_is_enabled(false)
+: _client(client),
+ _is_activated(false),
+ _is_enabled(false)
{
}
@@ -128,7 +129,7 @@ JackMidiDriver::~JackMidiDriver()
void
JackMidiDriver::activate()
{
- m_is_activated = true;
+ _is_activated = true;
}
@@ -137,7 +138,7 @@ JackMidiDriver::activate()
void
JackMidiDriver::deactivate()
{
- m_is_activated = false;
+ _is_activated = false;
}
@@ -146,7 +147,7 @@ JackMidiDriver::deactivate()
void
JackMidiDriver::prepare_block(const SampleCount block_start, const SampleCount block_end)
{
- for (List<JackMidiPort*>::iterator i = m_in_ports.begin(); i != m_in_ports.end(); ++i)
+ for (List<JackMidiPort*>::iterator i = _in_ports.begin(); i != _in_ports.end(); ++i)
(*i)->prepare_block(block_start, block_end);
}
@@ -159,12 +160,15 @@ JackMidiDriver::prepare_block(const SampleCount block_start, const SampleCount b
* See create_port() and remove_port().
*/
void
-JackMidiDriver::add_port(JackMidiPort* port)
+JackMidiDriver::add_port(DriverPort* port)
{
- if (port->patch_port()->is_input())
- m_in_ports.push_back(port);
+ assert(ThreadManager::current_thread_id() == THREAD_PROCESS);
+ assert(dynamic_cast<JackMidiPort*>(port));
+
+ if (port->is_input())
+ _in_ports.push_back((JackMidiPort*)port);
else
- m_out_ports.push_back(port);
+ _out_ports.push_back((JackMidiPort*)port);
}
@@ -176,19 +180,21 @@ JackMidiDriver::add_port(JackMidiPort* port)
*
* It is the callers responsibility to delete the returned port.
*/
-JackMidiPort*
-JackMidiDriver::remove_port(JackMidiPort* port)
+DriverPort*
+JackMidiDriver::remove_port(const Path& path)
{
- if (port->patch_port()->is_input()) {
- for (List<JackMidiPort*>::iterator i = m_in_ports.begin(); i != m_in_ports.end(); ++i)
- if ((*i) == (JackMidiPort*)port)
- return m_in_ports.remove(i)->elem();
- } else {
- for (List<JackMidiPort*>::iterator i = m_out_ports.begin(); i != m_out_ports.end(); ++i)
- if ((*i) == port)
- return m_out_ports.remove(i)->elem();
- }
-
+ assert(ThreadManager::current_thread_id() == THREAD_PROCESS);
+
+ // FIXME: duplex?
+
+ for (List<JackMidiPort*>::iterator i = _in_ports.begin(); i != _in_ports.end(); ++i)
+ if ((*i)->patch_port()->path() == path)
+ return _in_ports.remove(i)->elem();
+
+ for (List<JackMidiPort*>::iterator i = _out_ports.begin(); i != _out_ports.end(); ++i)
+ if ((*i)->patch_port()->path() == path)
+ return _out_ports.remove(i)->elem();
+
cerr << "[JackMidiDriver::remove_input] WARNING: Failed to find Jack port to remove!" << endl;
return NULL;
}
diff --git a/src/libs/engine/JackMidiDriver.h b/src/libs/engine/JackMidiDriver.h
index e870b3c2..116eaebd 100644
--- a/src/libs/engine/JackMidiDriver.h
+++ b/src/libs/engine/JackMidiDriver.h
@@ -44,14 +44,14 @@ public:
void prepare_block(const SampleCount block_start, const SampleCount block_end);
- void set_name(const std::string& name) { jack_port_set_name(m_jack_port, name.c_str()); };
+ void set_name(const std::string& name) { jack_port_set_name(_jack_port, name.c_str()); };
- DuplexPort<MidiMessage>* patch_port() const { return m_patch_port; }
+ DuplexPort<MidiMessage>* patch_port() const { return _patch_port; }
private:
- JackMidiDriver* m_driver;
- jack_port_t* m_jack_port;
- DuplexPort<MidiMessage>* m_patch_port;
+ JackMidiDriver* _driver;
+ jack_port_t* _jack_port;
+ DuplexPort<MidiMessage>* _patch_port;
};
@@ -70,40 +70,39 @@ public:
void activate();
void deactivate();
- void enable() { m_is_enabled = true; }
- void disable() { m_is_enabled = false; }
+ void enable() { _is_enabled = true; }
+ void disable() { _is_enabled = false; }
- bool is_activated() const { return m_is_activated; }
- bool is_enabled() const { return m_is_enabled; }
+ bool is_activated() const { return _is_activated; }
+ bool is_enabled() const { return _is_enabled; }
void prepare_block(const SampleCount block_start, const SampleCount block_end);
JackMidiPort* create_port(DuplexPort<MidiMessage>* patch_port)
{ return new JackMidiPort(this, patch_port); }
+
+ void add_port(DriverPort* port);
+ DriverPort* remove_port(const Path& path);
- jack_client_t* jack_client() { return m_client; }
+ jack_client_t* jack_client() { return _client; }
private:
- List<JackMidiPort*> m_in_ports;
- List<JackMidiPort*> m_out_ports;
+ List<JackMidiPort*> _in_ports;
+ List<JackMidiPort*> _out_ports;
friend class JackMidiPort;
- // Functions for JackMidiPort
- void add_port(JackMidiPort* port);
- JackMidiPort* remove_port(JackMidiPort* port);
-
void add_output(ListNode<JackMidiPort*>* port);
ListNode<JackMidiPort*>* remove_output(JackMidiPort* port);
// MIDI thread
static void* process_midi_in(void* me);
- jack_client_t* m_client;
- pthread_t m_process_thread;
- bool m_is_activated;
- bool m_is_enabled;
- static bool m_midi_thread_exit_flag;
+ jack_client_t* _client;
+ pthread_t _process_thread;
+ bool _is_activated;
+ bool _is_enabled;
+ static bool _midi_thread_exit_flag;
};
diff --git a/src/libs/engine/MidiDriver.h b/src/libs/engine/MidiDriver.h
index 79236a56..dba3056d 100644
--- a/src/libs/engine/MidiDriver.h
+++ b/src/libs/engine/MidiDriver.h
@@ -68,6 +68,9 @@ public:
DriverPort* create_port(DuplexPort<MidiMessage>* patch_port) { return NULL; }
+ void add_port(DriverPort* port) {}
+ DriverPort* remove_port(const Path& path) { return NULL; }
+
void prepare_block(const SampleCount block_start, const SampleCount block_end) {}
};
diff --git a/src/libs/engine/events/AddPortEvent.cpp b/src/libs/engine/events/AddPortEvent.cpp
index 4173ced2..317e68b7 100644
--- a/src/libs/engine/events/AddPortEvent.cpp
+++ b/src/libs/engine/events/AddPortEvent.cpp
@@ -140,7 +140,10 @@ AddPortEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
}
if (_driver_port)
- _engine.audio_driver()->add_port(_driver_port);
+ if (_type == "ingen:audio")
+ _engine.audio_driver()->add_port(_driver_port);
+ else if (_type == "ingen:midi")
+ _engine.midi_driver()->add_port(_driver_port);
}
diff --git a/src/libs/engine/events/DestroyEvent.cpp b/src/libs/engine/events/DestroyEvent.cpp
index 9866fe95..97a4f215 100644
--- a/src/libs/engine/events/DestroyEvent.cpp
+++ b/src/libs/engine/events/DestroyEvent.cpp
@@ -22,6 +22,7 @@
#include "Node.h"
#include "Plugin.h"
#include "AudioDriver.h"
+#include "MidiDriver.h"
#include "InternalNode.h"
#include "DisconnectNodeEvent.h"
#include "DisconnectPortEvent.h"
@@ -178,9 +179,11 @@ DestroyEvent::execute(SampleCount nframes, FrameTime start, FrameTime end)
_port->parent_patch()->external_ports(_ports_array);
- if (!_port->parent_patch()->parent())
+ if (!_port->parent_patch()->parent()) {
_driver_port = _engine.audio_driver()->remove_port(_port->path());
-
+ if (!_driver_port)
+ _driver_port = _engine.midi_driver()->remove_port(_port->path());
+ }
}
}