diff options
author | David Robillard <d@drobilla.net> | 2009-05-12 04:34:08 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-05-12 04:34:08 +0000 |
commit | 0fd55176b99cd6bd3230afdf350687a04702bd92 (patch) | |
tree | 07f8fd4244c415bac532981c6800e0ea9beb0982 /src/engine | |
parent | effacccee852f5070c29f214cd2d15ce9aa2e91b (diff) | |
download | ingen-0fd55176b99cd6bd3230afdf350687a04702bd92.tar.gz ingen-0fd55176b99cd6bd3230afdf350687a04702bd92.tar.bz2 ingen-0fd55176b99cd6bd3230afdf350687a04702bd92.zip |
Detach/Reattach from/to Jack from UI (ticket #180).
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@1985 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine')
-rw-r--r-- | src/engine/Driver.hpp | 3 | ||||
-rw-r--r-- | src/engine/Engine.cpp | 68 | ||||
-rw-r--r-- | src/engine/EventSource.hpp | 4 | ||||
-rw-r--r-- | src/engine/HTTPEngineReceiver.cpp | 8 | ||||
-rw-r--r-- | src/engine/HTTPEngineReceiver.hpp | 4 | ||||
-rw-r--r-- | src/engine/JackAudioDriver.cpp | 119 | ||||
-rw-r--r-- | src/engine/JackAudioDriver.hpp | 21 | ||||
-rw-r--r-- | src/engine/JackMidiDriver.cpp | 45 | ||||
-rw-r--r-- | src/engine/JackMidiDriver.hpp | 7 | ||||
-rw-r--r-- | src/engine/MidiDriver.hpp | 3 | ||||
-rw-r--r-- | src/engine/OSCEngineReceiver.cpp | 8 | ||||
-rw-r--r-- | src/engine/OSCEngineReceiver.hpp | 4 | ||||
-rw-r--r-- | src/engine/PostProcessor.cpp | 16 | ||||
-rw-r--r-- | src/engine/QueuedEngineInterface.cpp | 14 | ||||
-rw-r--r-- | src/engine/QueuedEventSource.hpp | 4 | ||||
-rw-r--r-- | src/engine/events/ClearPatchEvent.cpp | 2 | ||||
-rw-r--r-- | src/engine/events/DeactivateEvent.cpp | 54 | ||||
-rw-r--r-- | src/engine/events/DeactivateEvent.hpp | 12 | ||||
-rw-r--r-- | src/engine/events/DestroyEvent.cpp | 2 | ||||
-rw-r--r-- | src/engine/wscript | 1 |
20 files changed, 214 insertions, 185 deletions
diff --git a/src/engine/Driver.hpp b/src/engine/Driver.hpp index a2ca6b15..e03c316d 100644 --- a/src/engine/Driver.hpp +++ b/src/engine/Driver.hpp @@ -46,7 +46,8 @@ public: /** Set the name of the system port */ virtual void set_name(const std::string& name) = 0; - virtual void unregister() = 0; + virtual void create() = 0; + virtual void destroy() = 0; bool is_input() const { return _patch_port->is_input(); } DuplexPort* patch_port() const { return _patch_port; } diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 41004b97..4d984916 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -22,26 +22,26 @@ #include "raul/Deletable.hpp" #include "raul/Maid.hpp" #include "raul/SharedPtr.hpp" -#include "Engine.hpp" -#include "tuning.hpp" -#include "Event.hpp" -#include "common/interface/EventType.hpp" -#include "shared/Store.hpp" -#include "NodeFactory.hpp" +#include "AudioDriver.hpp" #include "ClientBroadcaster.hpp" -#include "PatchImpl.hpp" +#include "Engine.hpp" #include "EngineStore.hpp" +#include "Event.hpp" +#include "MessageContext.hpp" #include "MidiDriver.hpp" +#include "NodeFactory.hpp" #include "OSCDriver.hpp" -#include "QueuedEventSource.hpp" +#include "PatchImpl.hpp" #include "PostProcessor.hpp" -#include "events/CreatePatchEvent.hpp" #include "PostProcessor.hpp" -#include "AudioDriver.hpp" -#include "ProcessSlave.hpp" #include "ProcessContext.hpp" -#include "MessageContext.hpp" +#include "ProcessSlave.hpp" +#include "QueuedEventSource.hpp" #include "ThreadManager.hpp" +#include "common/interface/EventType.hpp" +#include "events/CreatePatchEvent.hpp" +#include "shared/Store.hpp" +#include "tuning.hpp" using namespace std; namespace Ingen { @@ -182,20 +182,21 @@ Engine::activate(size_t parallelism) _midi_driver = new DummyMidiDriver(); for (EventSources::iterator i = _event_sources.begin(); i != _event_sources.end(); ++i) - (*i)->activate(); + (*i)->activate_source(); // Create root patch - - PatchImpl* root_patch = new PatchImpl(*this, "", 1, NULL, - _audio_driver->sample_rate(), _audio_driver->buffer_size(), 1); - root_patch->activate(); - _world->store->add(root_patch); - root_patch->compiled_patch(root_patch->compile()); - - assert(_audio_driver->root_patch() == NULL); - _audio_driver->set_root_patch(root_patch); + PatchImpl* root_patch = _audio_driver->root_patch(); + if (!root_patch) { + root_patch = new PatchImpl(*this, "", 1, NULL, + _audio_driver->sample_rate(), _audio_driver->buffer_size(), 1); + root_patch->activate(); + _world->store->add(root_patch); + root_patch->compiled_patch(root_patch->compile()); + _audio_driver->set_root_patch(root_patch); + } _audio_driver->activate(); + _midi_driver->attach(*_audio_driver.get()); _process_slaves.clear(); _process_slaves.reserve(parallelism); @@ -219,34 +220,31 @@ Engine::deactivate() return; for (EventSources::iterator i = _event_sources.begin(); i != _event_sources.end(); ++i) - (*i)->deactivate(); + (*i)->deactivate_source(); /*for (Tree<GraphObject*>::iterator i = _engine_store->objects().begin(); i != _engine_store->objects().end(); ++i) if ((*i)->as_node() != NULL && (*i)->as_node()->parent() == NULL) (*i)->as_node()->deactivate();*/ - _audio_driver->deactivate(); - - if (_midi_driver != NULL) { + if (_midi_driver) _midi_driver->deactivate(); - delete _midi_driver; - _midi_driver = NULL; - } + + _audio_driver->deactivate(); _audio_driver->root_patch()->deactivate(); - for (size_t i=0; i < _process_slaves.size(); ++i) { + /*for (size_t i=0; i < _process_slaves.size(); ++i) { delete _process_slaves[i]; - } + }*/ - _process_slaves.clear(); + //_process_slaves.clear(); // Finalize any lingering events (unlikely) - _post_processor->process(); + //_post_processor->process(); - _audio_driver.reset(); - _event_sources.clear(); + //_audio_driver.reset(); + //_event_sources.clear(); _activated = false; } diff --git a/src/engine/EventSource.hpp b/src/engine/EventSource.hpp index f3377393..1e36c2da 100644 --- a/src/engine/EventSource.hpp +++ b/src/engine/EventSource.hpp @@ -43,8 +43,8 @@ class EventSource public: virtual ~EventSource() {} - virtual void activate() = 0; - virtual void deactivate() = 0; + virtual void activate_source() = 0; + virtual void deactivate_source() = 0; virtual void process(PostProcessor& dest, ProcessContext& context) = 0; }; diff --git a/src/engine/HTTPEngineReceiver.cpp b/src/engine/HTTPEngineReceiver.cpp index 98008a16..4e279455 100644 --- a/src/engine/HTTPEngineReceiver.cpp +++ b/src/engine/HTTPEngineReceiver.cpp @@ -86,20 +86,20 @@ HTTPEngineReceiver::~HTTPEngineReceiver() void -HTTPEngineReceiver::activate() +HTTPEngineReceiver::activate_source() { - QueuedEventSource::activate(); + QueuedEventSource::activate_source(); _receive_thread->set_name("HTTP Receiver"); _receive_thread->start(); } void -HTTPEngineReceiver::deactivate() +HTTPEngineReceiver::deactivate_source() { cout << "[HTTPEngineReceiver] Stopped HTTP listening thread" << endl; _receive_thread->stop(); - QueuedEventSource::deactivate(); + QueuedEventSource::deactivate_source(); } diff --git a/src/engine/HTTPEngineReceiver.hpp b/src/engine/HTTPEngineReceiver.hpp index d47e9747..88f71aaf 100644 --- a/src/engine/HTTPEngineReceiver.hpp +++ b/src/engine/HTTPEngineReceiver.hpp @@ -31,8 +31,8 @@ public: HTTPEngineReceiver(Engine& engine, uint16_t port); ~HTTPEngineReceiver(); - void activate(); - void deactivate(); + void activate_source(); + void deactivate_source(); private: struct ReceiveThread : public Raul::Thread { diff --git a/src/engine/JackAudioDriver.cpp b/src/engine/JackAudioDriver.cpp index d7cfece2..f1f814c9 100644 --- a/src/engine/JackAudioDriver.cpp +++ b/src/engine/JackAudioDriver.cpp @@ -53,15 +53,7 @@ JackAudioPort::JackAudioPort(JackAudioDriver* driver, DuplexPort* patch_port) { assert(patch_port->poly() == 1); - _jack_port = jack_port_register(_driver->jack_client(), - patch_port->path().c_str(), JACK_DEFAULT_AUDIO_TYPE, - (patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput, - 0); - - if (_jack_port == NULL) { - cerr << "[JackAudioPort] ERROR: Failed to register port " << patch_port->path() << endl; - throw JackAudioDriver::PortRegistrationFailedException(); - } + create(); patch_port->buffer(0)->clear(); patch_port->fixed_buffers(true); @@ -75,7 +67,22 @@ JackAudioPort::~JackAudioPort() void -JackAudioPort::unregister() +JackAudioPort::create() +{ + _jack_port = jack_port_register(_driver->jack_client(), + _patch_port->path().c_str(), JACK_DEFAULT_AUDIO_TYPE, + (_patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput, + 0); + + if (_jack_port == NULL) { + cerr << "[JackAudioPort] ERROR: Failed to register port " << _patch_port->path() << endl; + throw JackAudioDriver::PortRegistrationFailedException(); + } +} + + +void +JackAudioPort::destroy() { assert(_jack_port); if (jack_port_unregister(_driver->jack_client(), _jack_port)) @@ -103,24 +110,42 @@ JackAudioPort::prepare_buffer(jack_nframes_t nframes) //// JackAudioDriver //// -JackAudioDriver::JackAudioDriver(Engine& engine, - std::string server_name, - std::string client_name, - jack_client_t* jack_client) +JackAudioDriver::JackAudioDriver(Engine& engine) : _engine(engine) , _jack_thread(NULL) - , _client(jack_client) - , _buffer_size(jack_client ? jack_get_buffer_size(jack_client) : 0) - , _sample_rate(jack_client ? jack_get_sample_rate(jack_client) : 0) + , _sem(0) + , _flag(0) + , _client(NULL) + , _buffer_size(0) + , _sample_rate(0) , _is_activated(false) - , _local_client(true) // FIXME + , _local_client(true) , _process_context(engine) , _root_patch(NULL) { - if (!_client) { +} + + +JackAudioDriver::~JackAudioDriver() +{ + deactivate(); + + if (_local_client) + jack_client_close(_client); +} + + +bool +JackAudioDriver::attach(const std::string& server_name, + const std::string& client_name, + void* jack_client) +{ + assert(!_client); + if (!jack_client) { // Try supplied server name if (server_name != "") { - _client = jack_client_open(client_name.c_str(), JackServerName, NULL, server_name.c_str()); + _client = jack_client_open(client_name.c_str(), + JackServerName, NULL, server_name.c_str()); if (_client) cerr << "[JackAudioDriver] Connected to JACK server '" << server_name << "'" << endl; @@ -138,27 +163,27 @@ JackAudioDriver::JackAudioDriver(Engine& engine, // Still failed if (!_client) { cerr << "[JackAudioDriver] Unable to connect to Jack. Exiting." << endl; - exit(EXIT_FAILURE); + return false; } - - _buffer_size = jack_get_buffer_size(_client); - _sample_rate = jack_get_sample_rate(_client); + } else { + _client = (jack_client_t*)jack_client; } + _local_client = (jack_client == NULL); + + _buffer_size = jack_get_buffer_size(_client); + _sample_rate = jack_get_sample_rate(_client); + jack_on_shutdown(_client, shutdown_cb, this); jack_set_thread_init_callback(_client, thread_init_cb, this); jack_set_sample_rate_callback(_client, sample_rate_cb, this); jack_set_buffer_size_callback(_client, buffer_size_cb, this); -} - - -JackAudioDriver::~JackAudioDriver() -{ - deactivate(); - if (_local_client) - jack_client_close(_client); + for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) + (*i)->create(); + + return true; } @@ -170,6 +195,9 @@ JackAudioDriver::activate() return; } + if (!_client) + attach("", "ingen", NULL); + jack_set_process_callback(_client, process_cb, this); _is_activated = true; @@ -181,8 +209,11 @@ JackAudioDriver::activate() cout << "[JackAudioDriver] Activated Jack client." << endl; } - if (!_engine.midi_driver() || dynamic_cast<DummyMidiDriver*>(_engine.midi_driver())) - _engine.set_midi_driver(new JackMidiDriver(_engine, _client)); + if (!_engine.midi_driver() || dynamic_cast<DummyMidiDriver*>(_engine.midi_driver())) { + JackMidiDriver* midi_driver = new JackMidiDriver(_engine); + midi_driver->attach(*this); + _engine.set_midi_driver(midi_driver); + } } @@ -190,12 +221,17 @@ void JackAudioDriver::deactivate() { if (_is_activated) { - for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) - (*i)->unregister(); + _flag = 1; _is_activated = false; + _sem.wait(); + for (Raul::List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) + (*i)->destroy(); jack_deactivate(_client); + if (_local_client) { + jack_client_close(_client); + _client = NULL; + } _jack_thread->stop(); - _ports.clear(); cout << "[JackAudioDriver] Deactivated Jack client." << endl; } } @@ -288,8 +324,11 @@ JackAudioDriver::driver_port(const Path& path) int JackAudioDriver::_process_cb(jack_nframes_t nframes) { - if (nframes == 0 || ! _is_activated) + if (nframes == 0 || ! _is_activated) { + if (_flag == 1) + _sem.post(); return 0; + } // FIXME: all of this time stuff is screwy @@ -396,7 +435,9 @@ new_jack_audio_driver( const std::string client_name, void* jack_client) { - return new Ingen::JackAudioDriver(engine, server_name, client_name, (jack_client_t*)jack_client); + Ingen::JackAudioDriver* driver = new Ingen::JackAudioDriver(engine); + driver->attach(server_name, client_name, jack_client); + return driver; } } diff --git a/src/engine/JackAudioDriver.hpp b/src/engine/JackAudioDriver.hpp index a7f4c2ff..aa952197 100644 --- a/src/engine/JackAudioDriver.hpp +++ b/src/engine/JackAudioDriver.hpp @@ -20,8 +20,10 @@ #include <jack/jack.h> #include <jack/transport.h> -#include "raul/Thread.hpp" +#include "raul/AtomicInt.hpp" #include "raul/List.hpp" +#include "raul/Semaphore.hpp" +#include "raul/Thread.hpp" #include "AudioDriver.hpp" #include "Buffer.hpp" #include "ProcessContext.hpp" @@ -48,7 +50,8 @@ public: JackAudioPort(JackAudioDriver* driver, DuplexPort* patch_port); ~JackAudioPort(); - void unregister(); + void create(); + void destroy(); void set_name(const std::string& name) { jack_port_set_name(_jack_port, name.c_str()); }; @@ -75,13 +78,13 @@ private: class JackAudioDriver : public AudioDriver { public: - JackAudioDriver(Engine& engine, - std::string server_name = "default", - std::string client_name = "ingen", - jack_client_t* jack_client = 0); - + JackAudioDriver(Engine& engine); ~JackAudioDriver(); + bool attach(const std::string& server_name, + const std::string& client_name, + void* jack_client); + void activate(); void deactivate(); void enable(); @@ -112,7 +115,7 @@ public: SampleCount sample_rate() const { return _sample_rate; } bool is_activated() const { return _is_activated; } - inline SampleCount frame_time() const { return jack_frame_time(_client); } + inline SampleCount frame_time() const { return _client ? jack_frame_time(_client) : 0; } class PortRegistrationFailedException : public std::exception {}; @@ -136,6 +139,8 @@ private: Engine& _engine; Raul::Thread* _jack_thread; + Raul::Semaphore _sem; + Raul::AtomicInt _flag; jack_client_t* _client; jack_nframes_t _buffer_size; jack_nframes_t _sample_rate; diff --git a/src/engine/JackMidiDriver.cpp b/src/engine/JackMidiDriver.cpp index 9551b6be..ec94f962 100644 --- a/src/engine/JackMidiDriver.cpp +++ b/src/engine/JackMidiDriver.cpp @@ -47,15 +47,7 @@ JackMidiPort::JackMidiPort(JackMidiDriver* driver, DuplexPort* patch_port) { assert(patch_port->poly() == 1); - _jack_port = jack_port_register(_driver->jack_client(), - patch_port->path().c_str(), JACK_DEFAULT_MIDI_TYPE, - (patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput, - 0); - - if (_jack_port == NULL) { - cerr << "[JackMidiPort] ERROR: Failed to register port " << patch_port->path() << endl; - throw JackAudioDriver::PortRegistrationFailedException(); - } + create(); patch_port->buffer(0)->clear(); } @@ -68,7 +60,22 @@ JackMidiPort::~JackMidiPort() void -JackMidiPort::unregister() +JackMidiPort::create() +{ + _jack_port = jack_port_register(_driver->jack_client(), + _patch_port->path().c_str(), JACK_DEFAULT_MIDI_TYPE, + (_patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput, + 0); + + if (_jack_port == NULL) { + cerr << "[JackMidiPort] ERROR: Failed to register port " << _patch_port->path() << endl; + throw JackAudioDriver::PortRegistrationFailedException(); + } +} + + +void +JackMidiPort::destroy() { assert(_jack_port); if (jack_port_unregister(_driver->jack_client(), _jack_port)) @@ -157,9 +164,9 @@ JackMidiPort::post_process(ProcessContext& context) bool JackMidiDriver::_midi_thread_exit_flag = true; -JackMidiDriver::JackMidiDriver(Engine& engine, jack_client_t* client) +JackMidiDriver::JackMidiDriver(Engine& engine) : _engine(engine) - , _client(client) + , _client(NULL) , _is_activated(false) , _is_enabled(false) { @@ -175,6 +182,17 @@ JackMidiDriver::~JackMidiDriver() } +void +JackMidiDriver::attach(AudioDriver& driver) +{ + JackAudioDriver* jad = dynamic_cast<JackAudioDriver*>(&driver); + assert(jad); + _client = jad->jack_client(); + for (Raul::List<JackMidiPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) + (*i)->create(); +} + + /** Launch and start the MIDI thread. */ void @@ -190,9 +208,8 @@ void JackMidiDriver::deactivate() { for (Raul::List<JackMidiPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) - (*i)->unregister(); + (*i)->destroy(); _is_activated = false; - _ports.clear(); } diff --git a/src/engine/JackMidiDriver.hpp b/src/engine/JackMidiDriver.hpp index af885766..d0e81396 100644 --- a/src/engine/JackMidiDriver.hpp +++ b/src/engine/JackMidiDriver.hpp @@ -41,7 +41,8 @@ public: JackMidiPort(JackMidiDriver* driver, DuplexPort* port); virtual ~JackMidiPort(); - void unregister(); + void create(); + void destroy(); void pre_process(ProcessContext& context); void post_process(ProcessContext& context); @@ -64,9 +65,11 @@ private: class JackMidiDriver : public MidiDriver { public: - JackMidiDriver(Engine& engine, jack_client_t* client); + JackMidiDriver(Engine& engine); ~JackMidiDriver(); + void attach(AudioDriver& driver); + void activate(); void deactivate(); void enable() { _is_enabled = true; } diff --git a/src/engine/MidiDriver.hpp b/src/engine/MidiDriver.hpp index 75da9db5..da465293 100644 --- a/src/engine/MidiDriver.hpp +++ b/src/engine/MidiDriver.hpp @@ -26,6 +26,7 @@ namespace Ingen { class ProcessContext; +class AudioDriver; /** Midi driver abstract base class. @@ -37,6 +38,8 @@ class MidiDriver : public Driver public: MidiDriver() : Driver(DataType::EVENT) {} + virtual void attach(AudioDriver& master) {} + /** Prepare input for the specified (upcoming) cycle. * * Realtime safe, run in audio thread before executing the graph for a cycle. diff --git a/src/engine/OSCEngineReceiver.cpp b/src/engine/OSCEngineReceiver.cpp index b5505f86..26b8aeeb 100644 --- a/src/engine/OSCEngineReceiver.cpp +++ b/src/engine/OSCEngineReceiver.cpp @@ -143,9 +143,9 @@ OSCEngineReceiver::~OSCEngineReceiver() void -OSCEngineReceiver::activate() +OSCEngineReceiver::activate_source() { - QueuedEventSource::activate(); + QueuedEventSource::activate_source(); _receive_thread->set_name("OSC Receiver"); _receive_thread->start(); _receive_thread->set_scheduling(SCHED_FIFO, 5); // Jack default appears to be 10 @@ -153,11 +153,11 @@ OSCEngineReceiver::activate() void -OSCEngineReceiver::deactivate() +OSCEngineReceiver::deactivate_source() { cout << "[OSCEngineReceiver] Stopped OSC listening thread" << endl; _receive_thread->stop(); - QueuedEventSource::deactivate(); + QueuedEventSource::deactivate_source(); } diff --git a/src/engine/OSCEngineReceiver.hpp b/src/engine/OSCEngineReceiver.hpp index 75094f55..6ab017d0 100644 --- a/src/engine/OSCEngineReceiver.hpp +++ b/src/engine/OSCEngineReceiver.hpp @@ -63,8 +63,8 @@ public: OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t port); ~OSCEngineReceiver(); - void activate(); - void deactivate(); + void activate_source(); + void deactivate_source(); private: struct ReceiveThread : public Raul::Thread { diff --git a/src/engine/PostProcessor.cpp b/src/engine/PostProcessor.cpp index b90f7ddc..1595ac38 100644 --- a/src/engine/PostProcessor.cpp +++ b/src/engine/PostProcessor.cpp @@ -55,14 +55,18 @@ PostProcessor::process() /* FIXME: process events from all threads if parallel */ /* Process audio thread generated events */ - while (_engine.audio_driver()->context().event_sink().read( - _event_buffer_size, _event_buffer)) { - if (((Event*)_event_buffer)->time() > end_time) { - cerr << "WARNING: Lost event with time " - << ((Event*)_event_buffer)->time() << " > " << end_time << endl; + while (true) { + AudioDriver* driver = _engine.audio_driver(); + if (driver && driver->context().event_sink().read(_event_buffer_size, _event_buffer)) { + if (((Event*)_event_buffer)->time() > end_time) { + cerr << "WARNING: Lost event with time " + << ((Event*)_event_buffer)->time() << " > " << end_time << endl; + break; + } + ((Event*)_event_buffer)->post_process(); + } else { break; } - ((Event*)_event_buffer)->post_process(); } /* Process normal events */ diff --git a/src/engine/QueuedEngineInterface.cpp b/src/engine/QueuedEngineInterface.cpp index 6a322e16..9a2cea1b 100644 --- a/src/engine/QueuedEngineInterface.cpp +++ b/src/engine/QueuedEngineInterface.cpp @@ -39,8 +39,10 @@ QueuedEngineInterface::now() const { // Exactly one cycle latency (some could run ASAP if we get lucky, but not always, and a slight // constant latency is far better than jittery lower (average) latency - assert(_engine.audio_driver()); - return _engine.audio_driver()->frame_time() + _engine.audio_driver()->buffer_size(); + if (_engine.audio_driver()) + return _engine.audio_driver()->frame_time() + _engine.audio_driver()->buffer_size(); + else + return 0; } @@ -99,8 +101,14 @@ QueuedEngineInterface::load_plugins() void QueuedEngineInterface::activate() { - QueuedEventSource::activate(); + static bool in_activate = false; + if (!in_activate) { + in_activate = true; + _engine.activate(1); + } + QueuedEventSource::activate_source(); push_queued(new PingQueuedEvent(_engine, _responder, now())); + in_activate = false; } diff --git a/src/engine/QueuedEventSource.hpp b/src/engine/QueuedEventSource.hpp index f8ff2783..3054d910 100644 --- a/src/engine/QueuedEventSource.hpp +++ b/src/engine/QueuedEventSource.hpp @@ -48,8 +48,8 @@ public: QueuedEventSource(size_t queue_size); ~QueuedEventSource(); - void activate() { Slave::start(); } - void deactivate() { Slave::stop(); } + void activate_source() { Slave::start(); } + void deactivate_source() { Slave::stop(); } void process(PostProcessor& dest, ProcessContext& context); diff --git a/src/engine/events/ClearPatchEvent.cpp b/src/engine/events/ClearPatchEvent.cpp index c37d1910..9122281b 100644 --- a/src/engine/events/ClearPatchEvent.cpp +++ b/src/engine/events/ClearPatchEvent.cpp @@ -143,7 +143,7 @@ ClearPatchEvent::post_process() for (size_t i = 0; i < _driver_ports->size(); ++i) { Raul::List<DriverPort*>::Node* ln = _driver_ports->at(i); if (ln) { - ln->elem()->unregister(); + ln->elem()->destroy(); _engine.maid()->push(ln); } } diff --git a/src/engine/events/DeactivateEvent.cpp b/src/engine/events/DeactivateEvent.cpp deleted file mode 100644 index a68419f0..00000000 --- a/src/engine/events/DeactivateEvent.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* This file is part of Ingen. - * Copyright (C) 2007 Dave Robillard <http://drobilla.net> - * - * Ingen 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. - * - * Ingen 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., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "DeactivateEvent.hpp" -#include "Responder.hpp" -#include "Engine.hpp" - -namespace Ingen { - - -DeactivateEvent::DeactivateEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(engine, responder, timestamp) -{ -} - - -void -DeactivateEvent::pre_process() -{ - QueuedEvent::pre_process(); -} - - -void -DeactivateEvent::execute(ProcessContext& context) -{ - QueuedEvent::execute(context); -} - - -void -DeactivateEvent::post_process() -{ - _responder->respond_ok(); - _engine.deactivate(); -} - - -} // namespace Ingen - diff --git a/src/engine/events/DeactivateEvent.hpp b/src/engine/events/DeactivateEvent.hpp index 5a6750ba..eaa7e9cb 100644 --- a/src/engine/events/DeactivateEvent.hpp +++ b/src/engine/events/DeactivateEvent.hpp @@ -19,6 +19,7 @@ #define DEACTIVATEEVENT_H #include "QueuedEvent.hpp" +#include "Engine.hpp" namespace Ingen { @@ -30,11 +31,14 @@ namespace Ingen { class DeactivateEvent : public QueuedEvent { public: - DeactivateEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp); + DeactivateEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp) + : QueuedEvent(engine, responder, timestamp) + {} - void pre_process(); - void execute(ProcessContext& context); - void post_process(); + void post_process() { + _responder->respond_ok(); + _engine.deactivate(); + } }; diff --git a/src/engine/events/DestroyEvent.cpp b/src/engine/events/DestroyEvent.cpp index 52c19945..a9597638 100644 --- a/src/engine/events/DestroyEvent.cpp +++ b/src/engine/events/DestroyEvent.cpp @@ -200,7 +200,7 @@ DestroyEvent::post_process() } if (_driver_port) { - _driver_port->elem()->unregister(); + _driver_port->elem()->destroy(); _engine.maid()->push(_driver_port); } } diff --git a/src/engine/wscript b/src/engine/wscript index e6f38c0c..66d6f29e 100644 --- a/src/engine/wscript +++ b/src/engine/wscript @@ -63,7 +63,6 @@ def build(bld): events/CreateNodeEvent.cpp events/CreatePatchEvent.cpp events/CreatePortEvent.cpp - events/DeactivateEvent.cpp events/DestroyEvent.cpp events/DisconnectAllEvent.cpp events/DisconnectionEvent.cpp |