diff options
author | David Robillard <d@drobilla.net> | 2007-01-07 17:51:18 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2007-01-07 17:51:18 +0000 |
commit | 813e0cbb39809d7cf837e6b91a75815079502f47 (patch) | |
tree | 7a01ea7c6f3959ba6c6f1ffeffa27919ddc04ba1 | |
parent | 99ab1c257b7456c16f82119e1faea62c61eea660 (diff) | |
download | ingen-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.h | 11 | ||||
-rw-r--r-- | src/libs/engine/JackAudioDriver.cpp | 2 | ||||
-rw-r--r-- | src/libs/engine/JackMidiDriver.cpp | 76 | ||||
-rw-r--r-- | src/libs/engine/JackMidiDriver.h | 41 | ||||
-rw-r--r-- | src/libs/engine/MidiDriver.h | 3 | ||||
-rw-r--r-- | src/libs/engine/events/AddPortEvent.cpp | 5 | ||||
-rw-r--r-- | src/libs/engine/events/DestroyEvent.cpp | 7 |
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()); + } } } |