diff options
123 files changed, 898 insertions, 840 deletions
diff --git a/src/libs/engine/AlsaMidiDriver.cpp b/src/libs/engine/AlsaMidiDriver.cpp index f609ac52..e516f1ac 100644 --- a/src/libs/engine/AlsaMidiDriver.cpp +++ b/src/libs/engine/AlsaMidiDriver.cpp @@ -18,9 +18,8 @@ #include <iostream> #include <cstdlib> #include <pthread.h> -#include "Engine.h" #include "types.h" -#include "Engine.h" +//#include "Engine.h" #include "Maid.h" #include "AudioDriver.h" #include "MidiMessage.h" @@ -38,17 +37,17 @@ namespace Ingen { AlsaMidiPort::AlsaMidiPort(AlsaMidiDriver* driver, DuplexPort<MidiMessage>* port) : DriverPort(), ListNode<AlsaMidiPort*>(this), - m_driver(driver), - m_patch_port(port), - m_port_id(0), - m_midi_pool(new unsigned char*[port->buffer_size()]), - m_events(1024) + _driver(driver), + _patch_port(port), + _port_id(0), + _midi_pool(new unsigned char*[port->buffer_size()]), + _events(1024) { assert(port->parent() != NULL); assert(port->poly() == 1); if (port->is_input()) { - if ((m_port_id = snd_seq_create_simple_port(driver->seq_handle(), port->path().c_str(), + if ((_port_id = snd_seq_create_simple_port(driver->seq_handle(), port->path().c_str(), SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, SND_SEQ_PORT_TYPE_APPLICATION)) < 0) { @@ -56,7 +55,7 @@ AlsaMidiPort::AlsaMidiPort(AlsaMidiDriver* driver, DuplexPort<MidiMessage>* port exit(EXIT_FAILURE); } } else { - if ((m_port_id = snd_seq_create_simple_port(driver->seq_handle(), port->path().c_str(), + if ((_port_id = snd_seq_create_simple_port(driver->seq_handle(), port->path().c_str(), SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, SND_SEQ_PORT_TYPE_APPLICATION)) < 0) { @@ -70,7 +69,7 @@ AlsaMidiPort::AlsaMidiPort(AlsaMidiDriver* driver, DuplexPort<MidiMessage>* port * buffer will be set directly to an element in this pool, then next cycle they * will be overwritten (eliminating the need for any allocation/freeing). */ for (size_t i=0; i < port->buffer_size(); ++i) - m_midi_pool[i] = new unsigned char[MAX_MIDI_EVENT_SIZE]; + _midi_pool[i] = new unsigned char[MAX_MIDI_EVENT_SIZE]; port->buffer(0)->clear(); port->fixed_buffers(true); @@ -79,27 +78,27 @@ AlsaMidiPort::AlsaMidiPort(AlsaMidiDriver* driver, DuplexPort<MidiMessage>* port AlsaMidiPort::~AlsaMidiPort() { - snd_seq_delete_simple_port(m_driver->seq_handle(), m_port_id); + snd_seq_delete_simple_port(_driver->seq_handle(), _port_id); // Free event pool - for (size_t i=0; i < m_patch_port->buffer_size(); ++i) - delete[] m_midi_pool[i]; + for (size_t i=0; i < _patch_port->buffer_size(); ++i) + delete[] _midi_pool[i]; - delete[] m_midi_pool; + delete[] _midi_pool; } void AlsaMidiPort::add_to_driver() { - m_driver->add_port(this); + _driver->add_port(this); } void AlsaMidiPort::remove_from_driver() { - m_driver->remove_port(this); + _driver->remove_port(this); } @@ -108,9 +107,9 @@ AlsaMidiPort::set_name(const string& name) { snd_seq_port_info_t* info = NULL; snd_seq_port_info_malloc(&info); - snd_seq_get_port_info(m_driver->seq_handle(), m_port_id, info); + snd_seq_get_port_info(_driver->seq_handle(), _port_id, info); snd_seq_port_info_set_name(info, name.c_str()); - snd_seq_set_port_info(m_driver->seq_handle(), m_port_id, info); + snd_seq_set_port_info(_driver->seq_handle(), _port_id, info); snd_seq_port_info_free(info); } @@ -119,13 +118,13 @@ void AlsaMidiPort::event(snd_seq_event_t* const ev) { // Abuse the tick field to hold the timestamp - ev->time.tick = Engine::instance().audio_driver()->time_stamp(); + ev->time.tick = _driver->clock()->time_stamp(); // Fix noteons with velocity 0 (required for DSSI spec) if (ev->type == SND_SEQ_EVENT_NOTEON && ev->data.note.velocity == 0) ev->type = SND_SEQ_EVENT_NOTEOFF; - m_events.push(*ev); + _events.push(*ev); } @@ -142,14 +141,14 @@ AlsaMidiPort::prepare_block(const SampleCount block_start, const SampleCount blo snd_seq_event_t* ev = NULL; MidiMessage* message = NULL; - size_t num_events = 0; + size_t nu_events = 0; size_t event_size = 0; // decoded length of Alsa event in bytes int timestamp = 0; - while (!m_events.is_empty() && m_events.front().time.tick < block_end) { - assert(num_events < m_patch_port->buffer_size()); - ev = &m_events.front(); - message = &m_patch_port->buffer(0)->data()[num_events]; + while (!_events.is_empty() && _events.front().time.tick < block_end) { + assert(nu_events < _patch_port->buffer_size()); + ev = &_events.front(); + message = &_patch_port->buffer(0)->data()[nu_events]; timestamp = ev->time.tick - block_start; if (timestamp < 0) { @@ -160,24 +159,24 @@ AlsaMidiPort::prepare_block(const SampleCount block_start, const SampleCount blo assert(timestamp < (int)(block_end - block_start)); // Reset decoder so we don't get running status - snd_midi_event_reset_decode(m_driver->event_coder()); + snd_midi_event_reset_decode(_driver->event_coder()); // FIXME: is this realtime safe? - if ((event_size = snd_midi_event_decode(m_driver->event_coder(), - m_midi_pool[num_events], MAX_MIDI_EVENT_SIZE, ev)) > 0) { + if ((event_size = snd_midi_event_decode(_driver->event_coder(), + _midi_pool[nu_events], MAX_MIDI_EVENT_SIZE, ev)) > 0) { message->size = event_size; message->time = timestamp; - message->buffer = m_midi_pool[num_events]; - ++num_events; + message->buffer = _midi_pool[nu_events]; + ++nu_events; } else { cerr << "[AlsaMidiPort] Unable to decode MIDI event" << endl; } - m_events.pop(); + _events.pop(); } - m_patch_port->buffer(0)->filled_size(num_events); - //m_patch_port->tied_port()->buffer(0)->filled_size(num_events); + _patch_port->buffer(0)->filled_size(nu_events); + //_patch_port->tied_port()->buffer(0)->filled_size(nu_events); } @@ -185,38 +184,38 @@ AlsaMidiPort::prepare_block(const SampleCount block_start, const SampleCount blo //// AlsaMidiDriver //// -bool AlsaMidiDriver::m_midi_thread_exit_flag = true; +bool AlsaMidiDriver::_midi_thread_exit_flag = true; AlsaMidiDriver::AlsaMidiDriver() -: m_seq_handle(NULL), - m_event_coder(NULL), - m_is_activated(false) +: _seq_handle(NULL), + _event_coder(NULL), + _is_activated(false) { - if (snd_seq_open(&m_seq_handle, "hw", SND_SEQ_OPEN_INPUT, 0) < 0) { + if (snd_seq_open(&_seq_handle, "hw", SND_SEQ_OPEN_INPUT, 0) < 0) { cerr << "[AlsaMidiDriver] Error opening ALSA sequencer." << endl; exit(EXIT_FAILURE); } else { cout << "[AlsaMidiDriver] Successfully opened ALSA sequencer." << endl; } - if (snd_midi_event_new(3, &m_event_coder)) { + if (snd_midi_event_new(3, &_event_coder)) { cerr << "[AlsaMidiDriver] Failed to initialize ALSA MIDI event coder!"; exit(EXIT_FAILURE); } else { - snd_midi_event_reset_encode(m_event_coder); - snd_midi_event_reset_decode(m_event_coder); + snd_midi_event_reset_encode(_event_coder); + snd_midi_event_reset_decode(_event_coder); } - snd_seq_set_client_name(m_seq_handle, "Ingen"); + snd_seq_set_client_name(_seq_handle, "Ingen"); } AlsaMidiDriver::~AlsaMidiDriver() { deactivate(); - snd_midi_event_free(m_event_coder); - snd_seq_close(m_seq_handle); + snd_midi_event_free(_event_coder); + snd_seq_close(_seq_handle); } @@ -226,11 +225,11 @@ void AlsaMidiDriver::activate() { // Just exit if already running - if (m_midi_thread_exit_flag == false) + if (_midi_thread_exit_flag == false) return; bool success = false; - m_midi_thread_exit_flag = false; + _midi_thread_exit_flag = false; //if (Engine::instance().audio_driver()->is_realtime()) { pthread_attr_t attr; @@ -250,7 +249,7 @@ AlsaMidiDriver::activate() cout << "[AlsaMidiDriver] Unable to set SCHED_FIFO priority " << param.sched_priority << endl; - if (!pthread_create(&m_process_thread, &attr, process_midi_in, this)) { + if (!pthread_create(&_process_thread, &attr, process_midi_in, this)) { cout << "[AlsaMidiDriver] Started realtime MIDI thread (SCHED_FIFO, priority " << param.sched_priority << ")" << endl; success = true; @@ -262,15 +261,16 @@ AlsaMidiDriver::activate() if (!success) { // FIXME: check for success - pthread_create(&m_process_thread, NULL, process_midi_in, this); + pthread_create(&_process_thread, NULL, process_midi_in, this); cout << "[AlsaMidiDriver] Started non-realtime MIDI thread." << endl; } #ifdef HAVE_LASH - Engine::instance().lash_driver()->set_alsa_client_id(snd_seq_client_id(m_seq_handle)); + cerr << "FIXME: LASH + ALSA" << endl; + //Engine::instance().lash_driver()->set_alsa_client_id(snd_seq_client_id(_seq_handle)); #endif - m_is_activated = true; + _is_activated = true; } @@ -279,11 +279,11 @@ AlsaMidiDriver::activate() void AlsaMidiDriver::deactivate() { - if (m_is_activated) { - m_midi_thread_exit_flag = true; - pthread_cancel(m_process_thread); - pthread_join(m_process_thread, NULL); - m_is_activated = false; + if (_is_activated) { + _midi_thread_exit_flag = true; + pthread_cancel(_process_thread); + pthread_join(_process_thread, NULL); + _is_activated = false; } } @@ -293,7 +293,7 @@ AlsaMidiDriver::deactivate() void AlsaMidiDriver::prepare_block(const SampleCount block_start, const SampleCount block_end) { - for (List<AlsaMidiPort*>::iterator i = m_in_ports.begin(); i != m_in_ports.end(); ++i) + for (List<AlsaMidiPort*>::iterator i = _in_ports.begin(); i != _in_ports.end(); ++i) (*i)->prepare_block(block_start, block_end); } @@ -309,9 +309,9 @@ void AlsaMidiDriver::add_port(AlsaMidiPort* port) { if (port->patch_port()->is_input()) - m_in_ports.push_back(port); + _in_ports.push_back(port); else - m_out_ports.push_back(port); + _out_ports.push_back(port); } @@ -327,13 +327,13 @@ AlsaMidiPort* AlsaMidiDriver::remove_port(AlsaMidiPort* port) { if (port->patch_port()->is_input()) { - for (List<AlsaMidiPort*>::iterator i = m_in_ports.begin(); i != m_in_ports.end(); ++i) + for (List<AlsaMidiPort*>::iterator i = _in_ports.begin(); i != _in_ports.end(); ++i) if ((*i) == (AlsaMidiPort*)port) - return m_in_ports.remove(i)->elem(); + return _in_ports.remove(i)->elem(); } else { - for (List<AlsaMidiPort*>::iterator i = m_out_ports.begin(); i != m_out_ports.end(); ++i) + for (List<AlsaMidiPort*>::iterator i = _out_ports.begin(); i != _out_ports.end(); ++i) if ((*i) == port) - return m_out_ports.remove(i)->elem(); + return _out_ports.remove(i)->elem(); } cerr << "[AlsaMidiDriver::remove_input] WARNING: Failed to find Jack port to remove!" << endl; @@ -350,14 +350,14 @@ AlsaMidiDriver::process_midi_in(void* alsa_driver) snd_seq_event_t* ev; - int npfd = snd_seq_poll_descriptors_count(ad->m_seq_handle, POLLIN); + int npfd = snd_seq_poll_descriptors_count(ad->_seq_handle, POLLIN); struct pollfd pfd; - snd_seq_poll_descriptors(ad->m_seq_handle, &pfd, npfd, POLLIN); + snd_seq_poll_descriptors(ad->_seq_handle, &pfd, npfd, POLLIN); - while ( ! m_midi_thread_exit_flag) + while ( ! _midi_thread_exit_flag) if (poll(&pfd, npfd, 100000) > 0) - while (snd_seq_event_input(ad->m_seq_handle, &ev) > 0) - for (List<AlsaMidiPort*>::iterator i = ad->m_in_ports.begin(); i != ad->m_in_ports.end(); ++i) + while (snd_seq_event_input(ad->_seq_handle, &ev) > 0) + for (List<AlsaMidiPort*>::iterator i = ad->_in_ports.begin(); i != ad->_in_ports.end(); ++i) if ((*i)->port_id() == ev->dest.port) (*i)->event(ev); diff --git a/src/libs/engine/AlsaMidiDriver.h b/src/libs/engine/AlsaMidiDriver.h index c1941c42..ad40ed17 100644 --- a/src/libs/engine/AlsaMidiDriver.h +++ b/src/libs/engine/AlsaMidiDriver.h @@ -50,19 +50,19 @@ public: void remove_from_driver(); void set_name(const string& name); - int port_id() const { return m_port_id; } - DuplexPort<MidiMessage>* patch_port() const { return m_patch_port; } + int port_id() const { return _port_id; } + DuplexPort<MidiMessage>* patch_port() const { return _patch_port; } private: // Prevent copies (undefined) AlsaMidiPort(const AlsaMidiPort&); AlsaMidiPort& operator=(const AlsaMidiPort&); - AlsaMidiDriver* m_driver; - DuplexPort<MidiMessage>* m_patch_port; - int m_port_id; - unsigned char** m_midi_pool; ///< Pool of raw MIDI events for MidiMessage::buffer - Queue<snd_seq_event_t> m_events; + AlsaMidiDriver* _driver; + DuplexPort<MidiMessage>* _patch_port; + int _port_id; + unsigned char** _midi_pool; ///< Pool of raw MIDI events for MidiMessage::buffer + Queue<snd_seq_event_t> _events; }; @@ -82,15 +82,15 @@ public: void activate(); void deactivate(); - bool is_activated() const { return m_is_activated; } + bool is_activated() const { return _is_activated; } void prepare_block(const SampleCount block_start, const SampleCount block_end); DriverPort* create_port(DuplexPort<MidiMessage>* patch_port) { return new AlsaMidiPort(this, patch_port); } - snd_seq_t* seq_handle() const { return m_seq_handle; } - snd_midi_event_t* event_coder() const { return m_event_coder; } + snd_seq_t* seq_handle() const { return _seq_handle; } + snd_midi_event_t* event_coder() const { return _event_coder; } private: @@ -98,8 +98,8 @@ private: AlsaMidiDriver(const AlsaMidiDriver&); AlsaMidiDriver& operator=(const AlsaMidiDriver&); - List<AlsaMidiPort*> m_in_ports; - List<AlsaMidiPort*> m_out_ports; + List<AlsaMidiPort*> _in_ports; + List<AlsaMidiPort*> _out_ports; friend class AlsaMidiPort; @@ -113,11 +113,11 @@ private: // MIDI thread static void* process_midi_in(void* me); - snd_seq_t* m_seq_handle; - snd_midi_event_t* m_event_coder; - pthread_t m_process_thread; - bool m_is_activated; - static bool m_midi_thread_exit_flag; + snd_seq_t* _seq_handle; + snd_midi_event_t* _event_coder; + pthread_t _process_thread; + bool _is_activated; + static bool _midi_thread_exit_flag; }; diff --git a/src/libs/engine/AudioDriver.h b/src/libs/engine/AudioDriver.h index f46d4689..f72c43ea 100644 --- a/src/libs/engine/AudioDriver.h +++ b/src/libs/engine/AudioDriver.h @@ -41,7 +41,7 @@ public: virtual SampleCount buffer_size() const = 0; virtual SampleCount sample_rate() const = 0; - virtual SampleCount time_stamp() const = 0; + virtual SampleCount frame_time() const = 0; }; diff --git a/src/libs/engine/ClientBroadcaster.cpp b/src/libs/engine/ClientBroadcaster.cpp index 4dc992db..1fa64d9a 100644 --- a/src/libs/engine/ClientBroadcaster.cpp +++ b/src/libs/engine/ClientBroadcaster.cpp @@ -18,7 +18,6 @@ #include <cassert> #include <iostream> #include <unistd.h> -#include "Engine.h" #include "ObjectStore.h" #include "NodeFactory.h" #include "util.h" @@ -131,11 +130,11 @@ ClientBroadcaster::send_error(const string& msg) /* FIXME: Make a copy method for list and just make a copy and pass it here * instead of this global+locking mess */ void -ClientBroadcaster::send_plugins_to(ClientInterface* client) +ClientBroadcaster::send_plugins_to(ClientInterface* client, const list<Plugin*>& plugin_list) { - Engine::instance().node_factory()->lock_plugin_list(); - - const list<Plugin*>& plugs = Engine::instance().node_factory()->plugins(); + // FIXME: This probably isn't actually thread safe + const list<Plugin*> plugs = plugin_list; // make a copy + const Plugin* plugin; lo_timetag tt; @@ -174,8 +173,6 @@ ClientBroadcaster::send_plugins_to(ClientInterface* client) } for (list<lo_bundle>::const_iterator i = msgs.begin(); i != msgs.end(); ++i) lo_message_free(*i); - - Engine::instance().node_factory()->unlock_plugin_list(); } diff --git a/src/libs/engine/ClientBroadcaster.h b/src/libs/engine/ClientBroadcaster.h index 2c9890a6..adc0e7e9 100644 --- a/src/libs/engine/ClientBroadcaster.h +++ b/src/libs/engine/ClientBroadcaster.h @@ -66,7 +66,7 @@ public: // Error that isn't the direct result of a request void send_error(const string& msg); - void send_plugins_to(ClientInterface* client); + void send_plugins_to(ClientInterface* client, const list<Plugin*>& plugin_list); //void send_node_creation_messages(const Node* const node); diff --git a/src/libs/engine/DSSINode.cpp b/src/libs/engine/DSSINode.cpp index 122c13b4..11fda753 100644 --- a/src/libs/engine/DSSINode.cpp +++ b/src/libs/engine/DSSINode.cpp @@ -17,7 +17,6 @@ #include "DSSINode.h" #include <map> #include <set> -#include "Engine.h" #include "ClientBroadcaster.h" #include "interface/ClientInterface.h" #include "InputPort.h" @@ -160,9 +159,9 @@ DSSINode::has_midi_input() const void -DSSINode::process(SampleCount nframes) +DSSINode::process(SampleCount nframes, FrameTime start, FrameTime end) { - NodeBase::process(nframes); + NodeBase::process(nframes, start, end); if (_dssi_descriptor->run_synth) { convert_events(); @@ -176,7 +175,7 @@ DSSINode::process(SampleCount nframes) _dssi_descriptor->run_multiple_synths(1, _instances, nframes, events, events_sizes); } else { - LADSPANode::process(nframes); + LADSPANode::process(nframes, start, end); } } @@ -252,6 +251,7 @@ DSSINode::send_update() bool DSSINode::update_programs(bool send_events) { +#if 0 // remember all old banks and programs set<pair<int, int> > to_be_deleted; map<int, Bank>::const_iterator iter; @@ -276,7 +276,7 @@ DSSINode::update_programs(bool send_events) iter->second.find(descriptor->Program)->second != descriptor->Name) { _banks[descriptor->Bank][descriptor->Program] = descriptor->Name; if (send_events) { - Engine::instance().client_broadcaster()->send_program_add(path(), descriptor->Bank, + _engine.client_broadcaster()->send_program_add(path(), descriptor->Bank, descriptor->Program, descriptor->Name); } @@ -291,11 +291,13 @@ DSSINode::update_programs(bool send_events) set_iter != to_be_deleted.end(); ++set_iter) { _banks[set_iter->first].erase(set_iter->second); if (send_events) - Engine::instance().client_broadcaster()->send_program_remove(path(), set_iter->first, set_iter->second); + _engine.client_broadcaster()->send_program_remove(path(), set_iter->first, set_iter->second); if (_banks[set_iter->first].size() == 0) _banks.erase(set_iter->first); } - +#endif + cerr << "FIXME: DSSI programs broken!" << endl; + return true; } diff --git a/src/libs/engine/DSSINode.h b/src/libs/engine/DSSINode.h index 625d325c..3c8dc841 100644 --- a/src/libs/engine/DSSINode.h +++ b/src/libs/engine/DSSINode.h @@ -53,7 +53,7 @@ public: void configure(const string& key, const string& val); void program(int bank, int program); - void process(SampleCount nframes); + void process(SampleCount nframes, FrameTime start, FrameTime end); bool update_programs(bool send_events); void set_default_program(); diff --git a/src/libs/engine/Engine.cpp b/src/libs/engine/Engine.cpp index 75c544ac..a98f4fbf 100644 --- a/src/libs/engine/Engine.cpp +++ b/src/libs/engine/Engine.cpp @@ -49,20 +49,9 @@ using std::cout; using std::cerr; using std::endl; namespace Ingen { -Engine* Engine::m_instance = NULL; - - -void -Engine::instantiate(const char* port, AudioDriver* audio_driver) -{ - assert(!m_instance); - m_instance = new Engine(port, audio_driver); -} - - -Engine::Engine(const char* port, AudioDriver* audio_driver) -: m_audio_driver( (audio_driver) ? audio_driver : new JackAudioDriver() ), - m_osc_receiver(new OSCReceiver(pre_processor_queue_size, port)), +Engine::Engine(const char* listen_port, AudioDriver* audio_driver) +: m_audio_driver( (audio_driver) ? audio_driver : new JackAudioDriver(*this) ), + m_osc_receiver(new OSCReceiver(*this, pre_processor_queue_size, listen_port)), #ifdef HAVE_JACK_MIDI m_midi_driver(new JackMidiDriver(((JackAudioDriver*)m_audio_driver)->jack_client())), #elif HAVE_ALSA_MIDI @@ -70,8 +59,8 @@ Engine::Engine(const char* port, AudioDriver* audio_driver) #else m_midi_driver(new DummyMidiDriver()), #endif - m_post_processor(new PostProcessor(post_processor_queue_size)), m_maid(new Maid(maid_queue_size)), + m_post_processor(new PostProcessor(*m_maid, post_processor_queue_size)), m_client_broadcaster(new ClientBroadcaster()), m_object_store(new ObjectStore()), m_node_factory(new NodeFactory()), @@ -155,13 +144,13 @@ Engine::activate() return; // Create root patch - CreatePatchEvent create_ev(CountedPtr<Responder>(new Responder()), 0, "/", 1); + CreatePatchEvent create_ev(*this, CountedPtr<Responder>(new Responder()), 0, "/", 1); create_ev.pre_process(); - create_ev.execute(0); + create_ev.execute(1, 0, 1); create_ev.post_process(); - EnablePatchEvent enable_ev(CountedPtr<Responder>(new Responder()), 0, "/"); + EnablePatchEvent enable_ev(*this, CountedPtr<Responder>(new Responder()), 0, "/"); enable_ev.pre_process(); - enable_ev.execute(0); + enable_ev.execute(1, 0, 1); enable_ev.post_process(); assert(m_audio_driver->root_patch() != NULL); @@ -183,7 +172,7 @@ Engine::deactivate() if (!m_activated) return; - m_audio_driver->root_patch()->process(false); + m_audio_driver->root_patch()->disable(); m_audio_driver->root_patch()->deactivate(); /*for (Tree<GraphObject*>::iterator i = m_object_store->objects().begin(); diff --git a/src/libs/engine/Engine.h b/src/libs/engine/Engine.h index f6cfe9e9..fbad649f 100644 --- a/src/libs/engine/Engine.h +++ b/src/libs/engine/Engine.h @@ -39,21 +39,21 @@ class LashDriver; template <typename T> class Driver; -/** The main class for Ingen, the whole engine basically lives in here +/** The main class for the Engine. * - * A singleton, but shouldn't be (FIXME). Explicitly instantiated singleton - * to be exact - call instantiate before instance or suffer horrible death. + * With access to this you can find any object that's a part of the engine. + * Access to this should be limited as possible, it basically exists so + * there's something to pass Event constructors so they can access what + * they need to perform their function. * * \ingroup engine */ class Engine { public: + Engine(const char* listen_port, AudioDriver* audio_driver = 0); ~Engine(); - static void instantiate(const char* port, AudioDriver* audio_driver = 0); - static Engine& instance() { assert(m_instance); return *m_instance; } - int main(); /** Set the quit flag that should kill all threads and exit cleanly. @@ -66,8 +66,8 @@ public: AudioDriver* audio_driver() const { return m_audio_driver; } OSCReceiver* osc_receiver() const { return m_osc_receiver; } MidiDriver* midi_driver() const { return m_midi_driver; } - PostProcessor* post_processor() const { return m_post_processor; } Maid* maid() const { return m_maid; } + PostProcessor* post_processor() const { return m_post_processor; } ClientBroadcaster* client_broadcaster() const { return m_client_broadcaster; } ObjectStore* object_store() const { return m_object_store; } NodeFactory* node_factory() const { return m_node_factory; } @@ -77,19 +77,15 @@ public: template<typename T> Driver<T>* driver(); private: - Engine(const char* port, AudioDriver* audio_driver = 0); - // Prevent copies (undefined) Engine(const Engine&); Engine& operator=(const Engine&); - static Engine* m_instance; - AudioDriver* m_audio_driver; OSCReceiver* m_osc_receiver; MidiDriver* m_midi_driver; - PostProcessor* m_post_processor; Maid* m_maid; + PostProcessor* m_post_processor; ClientBroadcaster* m_client_broadcaster; ObjectStore* m_object_store; NodeFactory* m_node_factory; diff --git a/src/libs/engine/Event.h b/src/libs/engine/Event.h index 6532655c..3ea72555 100644 --- a/src/libs/engine/Event.h +++ b/src/libs/engine/Event.h @@ -25,6 +25,7 @@ namespace Ingen { +class Engine; /** Base class for all events (both realtime and QueuedEvent). @@ -44,27 +45,34 @@ public: virtual ~Event() {} /** Execute this event in the audio thread (MUST be realtime safe). */ - virtual void execute(SampleCount offset) { assert(!_executed); _executed = true; } + virtual void execute(SampleCount nframes, FrameTime start, FrameTime end) + { + assert(!_executed); + assert(_time >= start && _time <= end); + _executed = true; + } /** Perform any actions after execution (ie send replies to commands) * (no realtime requirements). */ virtual void post_process() {} - inline SampleCount time_stamp() { return _time_stamp; } + inline SampleCount time() { return _time; } protected: // Prevent copies Event(const Event&); Event& operator=(const Event&); - Event(CountedPtr<Responder> responder, SampleCount timestamp) - : _responder(responder) - , _time_stamp(timestamp) + Event(Engine& engine, CountedPtr<Responder> responder, FrameTime time) + : _engine(engine) + , _responder(responder) + , _time(time) , _executed(false) {} + Engine& _engine; CountedPtr<Responder> _responder; - SampleCount _time_stamp; + FrameTime _time; bool _executed; }; diff --git a/src/libs/engine/GraphObject.h b/src/libs/engine/GraphObject.h index 1c4fae49..3b0c27b1 100644 --- a/src/libs/engine/GraphObject.h +++ b/src/libs/engine/GraphObject.h @@ -31,6 +31,7 @@ namespace Ingen { class Patch; class Node; class Port; +class ObjectStore; /** An object on the audio graph - Patch, Node, Port, etc. @@ -57,7 +58,7 @@ public: inline GraphObject* parent() const { return _parent; } inline const string& name() const { return _name; } - virtual void process(SampleCount nframes) = 0; + virtual void process(SampleCount nframes, FrameTime start, FrameTime end) = 0; /** Rename */ virtual void set_path(const Path& new_path) { @@ -79,7 +80,7 @@ public: /** Patch and Node override this to recursively add their children. */ - virtual void add_to_store() = 0; + virtual void add_to_store(ObjectStore* store) = 0; /** Patch and Node override this to recursively remove their children. */ virtual void remove_from_store() = 0; diff --git a/src/libs/engine/InputPort.cpp b/src/libs/engine/InputPort.cpp index 29270bd1..830b370c 100644 --- a/src/libs/engine/InputPort.cpp +++ b/src/libs/engine/InputPort.cpp @@ -209,7 +209,7 @@ template void InputPort<MidiMessage>::tie(OutputPort<MidiMessage>* const port); */ template<> void -InputPort<Sample>::process(SampleCount nframes) +InputPort<Sample>::process(SampleCount nframes, FrameTime start, FrameTime end) { //assert(!m_is_tied || m_tied_port != NULL); @@ -219,7 +219,7 @@ InputPort<Sample>::process(SampleCount nframes) if (m_connections.size() == 0) return; for (TypedConnectionListIterator c = m_connections.begin(); c != m_connections.end(); ++c) - (*c)->process(nframes); + (*c)->process(nframes, start, end); // If only one connection, buffer is (maybe) used directly (no copying) if (m_connections.size() == 1) { @@ -272,7 +272,7 @@ InputPort<Sample>::process(SampleCount nframes) */ template <> void -InputPort<MidiMessage>::process(SampleCount nframes) +InputPort<MidiMessage>::process(SampleCount nframes, FrameTime start, FrameTime end) { //assert(!m_is_tied || m_tied_port != NULL); @@ -285,7 +285,7 @@ InputPort<MidiMessage>::process(SampleCount nframes) assert(_poly == 1); for (TypedConnectionListIterator c = m_connections.begin(); c != m_connections.end(); ++c) - (*c)->process(nframes); + (*c)->process(nframes, start, end); // If only one connection, buffer is used directly (no copying) diff --git a/src/libs/engine/InputPort.h b/src/libs/engine/InputPort.h index 39632cee..8360fd3e 100644 --- a/src/libs/engine/InputPort.h +++ b/src/libs/engine/InputPort.h @@ -55,7 +55,7 @@ public: const List<TypedConnection<T>*>& connections() { return m_connections; } - void process(SampleCount nframes); + void process(SampleCount nframes, FrameTime start, FrameTime end); bool is_connected() const { return (m_connections.size() > 0); } bool is_connected_to(const OutputPort<T>* const port) const; diff --git a/src/libs/engine/InternalNode.h b/src/libs/engine/InternalNode.h index 2cbbcff8..9c95aacb 100644 --- a/src/libs/engine/InternalNode.h +++ b/src/libs/engine/InternalNode.h @@ -44,7 +44,8 @@ public: virtual void deactivate() { if (_is_added) remove_from_patch(); NodeBase::deactivate(); } - virtual void process(SampleCount nframes) { NodeBase::process(nframes); } + virtual void process(SampleCount nframes, FrameTime start, FrameTime end) + { NodeBase::process(nframes, start, end); } virtual void add_to_patch() { assert(!_is_added); _is_added = true; } virtual void remove_from_patch() { assert(_is_added); _is_added = false; } diff --git a/src/libs/engine/JackAudioDriver.cpp b/src/libs/engine/JackAudioDriver.cpp index 8f5c788a..2c0d4a70 100644 --- a/src/libs/engine/JackAudioDriver.cpp +++ b/src/libs/engine/JackAudioDriver.cpp @@ -48,15 +48,15 @@ namespace Ingen { JackAudioPort::JackAudioPort(JackAudioDriver* driver, DuplexPort<Sample>* patch_port) : DriverPort(), ListNode<JackAudioPort*>(this), - m_driver(driver), - m_jack_port(NULL), - m_jack_buffer(NULL), - m_patch_port(patch_port) + _driver(driver), + _jack_port(NULL), + _jack_buffer(NULL), + _patch_port(patch_port) { //assert(patch_port->tied_port() != NULL); 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_AUDIO_TYPE, (patch_port->is_input()) ? JackPortIsInput : JackPortIsOutput, 0); @@ -67,21 +67,21 @@ JackAudioPort::JackAudioPort(JackAudioDriver* driver, DuplexPort<Sample>* patch_ JackAudioPort::~JackAudioPort() { - jack_port_unregister(m_driver->jack_client(), m_jack_port); + jack_port_unregister(_driver->jack_client(), _jack_port); } void JackAudioPort::add_to_driver() { - m_driver->add_port(this); + _driver->add_port(this); } void JackAudioPort::remove_from_driver() { - m_driver->remove_port(this); + _driver->remove_port(this); } void @@ -93,12 +93,12 @@ JackAudioPort::prepare_buffer(jack_nframes_t nframes) m_patch_port->buffer(0)->join(m_jack_buffer); */ - jack_sample_t* jack_buf = (jack_sample_t*)jack_port_get_buffer(m_jack_port, nframes); + jack_sample_t* jack_buf = (jack_sample_t*)jack_port_get_buffer(_jack_port, nframes); - if (jack_buf != m_jack_buffer) { + if (jack_buf != _jack_buffer) { //cerr << "Jack buffer: " << jack_buf << endl; - m_patch_port->buffer(0)->set_data(jack_buf); - m_jack_buffer = jack_buf; + _patch_port->buffer(0)->set_data(jack_buf); + _jack_buffer = jack_buf; } //assert(m_patch_port->tied_port() != NULL); @@ -111,47 +111,36 @@ JackAudioPort::prepare_buffer(jack_nframes_t nframes) //m_patch_port->fixed_buffers(true); - //assert(m_patch_port->buffer(0)->data() == m_patch_port->tied_port()->buffer(0)->data()); - assert(m_patch_port->buffer(0)->data() == jack_buf); + //assert(m_patch_port->buffer(0)->data() == _patch_port->tied_port()->buffer(0)->data()); + assert(_patch_port->buffer(0)->data() == jack_buf); } //// JackAudioDriver //// -JackAudioDriver::JackAudioDriver() -: m_client(NULL), - m_buffer_size(0), - m_sample_rate(0), - m_is_activated(false), - m_local_client(true), - m_root_patch(NULL) +JackAudioDriver::JackAudioDriver(Engine& engine, jack_client_t* jack_client) +: _engine(engine), + _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), + _is_activated(false), + _local_client(false), + _root_patch(NULL) { - m_client = jack_client_new("Ingen"); - if (m_client == NULL) { - cerr << "[JackAudioDriver] Unable to connect to Jack. Exiting." << endl; - exit(EXIT_FAILURE); + if (!_client) { + _client = jack_client_new("Ingen"); + if (_client == NULL) { + cerr << "[JackAudioDriver] Unable to connect to Jack. Exiting." << endl; + exit(EXIT_FAILURE); + } + _buffer_size = jack_get_buffer_size(_client); + _sample_rate = jack_get_sample_rate(_client); } - jack_on_shutdown(m_client, shutdown_cb, this); - - m_buffer_size = jack_get_buffer_size(m_client); - m_sample_rate = jack_get_sample_rate(m_client); + jack_on_shutdown(_client, shutdown_cb, this); - jack_set_sample_rate_callback(m_client, sample_rate_cb, this); - jack_set_buffer_size_callback(m_client, buffer_size_cb, this); -} - -JackAudioDriver::JackAudioDriver(jack_client_t* jack_client) -: m_client(jack_client), - m_buffer_size(jack_get_buffer_size(jack_client)), - m_sample_rate(jack_get_sample_rate(jack_client)), - m_is_activated(false), - m_local_client(false) -{ - jack_on_shutdown(m_client, shutdown_cb, this); - - jack_set_sample_rate_callback(m_client, sample_rate_cb, this); - jack_set_buffer_size_callback(m_client, buffer_size_cb, this); + jack_set_sample_rate_callback(_client, sample_rate_cb, this); + jack_set_buffer_size_callback(_client, buffer_size_cb, this); } @@ -159,30 +148,30 @@ JackAudioDriver::~JackAudioDriver() { deactivate(); - if (m_local_client) - jack_client_close(m_client); + if (_local_client) + jack_client_close(_client); } void JackAudioDriver::activate() { - if (m_is_activated) { + if (_is_activated) { cerr << "[JackAudioDriver] Jack driver already activated." << endl; return; } - jack_set_process_callback(m_client, process_cb, this); + jack_set_process_callback(_client, process_cb, this); - m_is_activated = true; + _is_activated = true; - if (jack_activate(m_client)) { + if (jack_activate(_client)) { cerr << "[JackAudioDriver] Could not activate Jack client, aborting." << endl; exit(EXIT_FAILURE); } else { cout << "[JackAudioDriver] Activated Jack client." << endl; #ifdef HAVE_LASH - Engine::instance().lash_driver()->set_jack_client_name(jack_client_get_name(m_client)); + _engine.lash_driver()->set_jack_client_name(jack_client_get_name(_client)); #endif } } @@ -191,20 +180,20 @@ JackAudioDriver::activate() void JackAudioDriver::deactivate() { - if (m_is_activated) { - Engine::instance().osc_receiver()->deactivate(); + if (_is_activated) { + _engine.osc_receiver()->deactivate(); - jack_deactivate(m_client); - m_is_activated = false; + jack_deactivate(_client); + _is_activated = false; - for (List<JackAudioPort*>::iterator i = m_ports.begin(); i != m_ports.end(); ++i) - jack_port_unregister(m_client, (*i)->jack_port()); + for (List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) + jack_port_unregister(_client, (*i)->jack_port()); - m_ports.clear(); + _ports.clear(); cout << "[JackAudioDriver] Deactivated Jack client." << endl; - Engine::instance().post_processor()->stop(); + _engine.post_processor()->stop(); } } @@ -219,7 +208,7 @@ JackAudioDriver::deactivate() void JackAudioDriver::add_port(JackAudioPort* port) { - m_ports.push_back(port); + _ports.push_back(port); } @@ -234,9 +223,9 @@ JackAudioDriver::add_port(JackAudioPort* port) JackAudioPort* JackAudioDriver::remove_port(JackAudioPort* port) { - for (List<JackAudioPort*>::iterator i = m_ports.begin(); i != m_ports.end(); ++i) + for (List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) if ((*i) == port) - return m_ports.remove(i)->elem(); + return _ports.remove(i)->elem(); cerr << "[JackAudioDriver::remove_port] WARNING: Failed to find Jack port to remove!" << endl; return NULL; @@ -246,7 +235,7 @@ JackAudioDriver::remove_port(JackAudioPort* port) DriverPort* JackAudioDriver::create_port(DuplexPort<Sample>* patch_port) { - if (patch_port->buffer_size() == m_buffer_size) + if (patch_port->buffer_size() == _buffer_size) return new JackAudioPort(this, patch_port); else return NULL; @@ -258,7 +247,7 @@ JackAudioDriver::create_port(DuplexPort<Sample>* patch_port) * Called from the realtime thread once every process cycle. */ void -JackAudioDriver::process_events(jack_nframes_t block_start, jack_nframes_t block_end) +JackAudioDriver::process_events(SampleCount nframes, FrameTime cycle_start, FrameTime cycle_end) { Event* ev = NULL; @@ -266,10 +255,9 @@ JackAudioDriver::process_events(jack_nframes_t block_start, jack_nframes_t block * makes the process callback (more) realtime-safe by preventing being * choked by events coming in faster than they can be processed. * FIXME: run the math on this and figure out a good value */ - const unsigned int MAX_QUEUED_EVENTS = m_buffer_size / 100; + const unsigned int MAX_QUEUED_EVENTS = _buffer_size / 100; unsigned int num_events_processed = 0; - unsigned int offset = 0; // Process the "slow" events first, because it's possible some of the // RT events depend on them @@ -277,26 +265,21 @@ JackAudioDriver::process_events(jack_nframes_t block_start, jack_nframes_t block /* FIXME: Merge these next two loops into one */ // FIXME - while ((ev = Engine::instance().osc_receiver()->pop_earliest_queued_before(block_end))) { - ev->execute(0); // QueuedEvents are not sample accurate - Engine::instance().post_processor()->push(ev); + while ((ev = _engine.osc_receiver()->pop_earliest_queued_before(cycle_end))) { + ev->execute(nframes, cycle_start, cycle_end); + _engine.post_processor()->push(ev); if (++num_events_processed > MAX_QUEUED_EVENTS) break; } - while ((ev = Engine::instance().osc_receiver()->pop_earliest_stamped_before(block_end))) { - if (ev->time_stamp() >= block_start) - offset = ev->time_stamp() - block_start; - else - offset = 0; - - ev->execute(offset); - Engine::instance().post_processor()->push(ev); + while ((ev = _engine.osc_receiver()->pop_earliest_stamped_before(cycle_end))) { + ev->execute(nframes, cycle_start, cycle_end); + _engine.post_processor()->push(ev); ++num_events_processed; } if (num_events_processed > 0) - Engine::instance().post_processor()->whip(); + _engine.post_processor()->whip(); } @@ -310,68 +293,70 @@ JackAudioDriver::process_events(jack_nframes_t block_start, jack_nframes_t block * \callgraph */ int -JackAudioDriver::m_process_cb(jack_nframes_t nframes) +JackAudioDriver::_process_cb(jack_nframes_t nframes) { + // FIXME: all of this time stuff is screwy + static jack_nframes_t start_of_current_cycle = 0; static jack_nframes_t start_of_last_cycle = 0; // FIXME: support nframes != buffer_size, even though that never damn well happens - assert(nframes == m_buffer_size); + assert(nframes == _buffer_size); // Jack can elect to not call this function for a cycle, if overloaded // FIXME: this doesn't make sense, and the start time isn't used anyway - start_of_current_cycle = jack_last_frame_time(m_client); + start_of_current_cycle = jack_last_frame_time(_client); start_of_last_cycle = start_of_current_cycle - nframes; // FIXME: ditto assert(start_of_current_cycle - start_of_last_cycle == nframes); - m_transport_state = jack_transport_query(m_client, &m_position); + _transport_state = jack_transport_query(_client, &_position); - process_events(start_of_last_cycle, start_of_current_cycle); - Engine::instance().midi_driver()->prepare_block(start_of_last_cycle, start_of_current_cycle); + process_events(nframes, start_of_last_cycle, start_of_current_cycle); + _engine.midi_driver()->prepare_block(start_of_last_cycle, start_of_current_cycle); // Set buffers of patch ports to Jack port buffers (zero-copy processing) - for (List<JackAudioPort*>::iterator i = m_ports.begin(); i != m_ports.end(); ++i) + for (List<JackAudioPort*>::iterator i = _ports.begin(); i != _ports.end(); ++i) (*i)->prepare_buffer(nframes); // Run root patch - assert(m_root_patch != NULL); - m_root_patch->process(nframes); + assert(_root_patch != NULL); + _root_patch->process(nframes, start_of_current_cycle, start_of_current_cycle + nframes); return 0; } void -JackAudioDriver::m_shutdown_cb() +JackAudioDriver::_shutdown_cb() { cout << "[JackAudioDriver] Jack shutdown. Exiting." << endl; - Engine::instance().quit(); + _engine.quit(); } int -JackAudioDriver::m_sample_rate_cb(jack_nframes_t nframes) +JackAudioDriver::_sample_rate_cb(jack_nframes_t nframes) { - if (m_is_activated) { + if (_is_activated) { cerr << "[JackAudioDriver] On-the-fly sample rate changing not supported (yet). Aborting." << endl; exit(EXIT_FAILURE); } else { - m_sample_rate = nframes; + _sample_rate = nframes; } return 0; } int -JackAudioDriver::m_buffer_size_cb(jack_nframes_t nframes) +JackAudioDriver::_buffer_size_cb(jack_nframes_t nframes) { - if (m_is_activated) { + if (_is_activated) { cerr << "[JackAudioDriver] On-the-fly buffer size changing not supported (yet). Aborting." << endl; exit(EXIT_FAILURE); } else { - m_buffer_size = nframes; + _buffer_size = nframes; } return 0; } diff --git a/src/libs/engine/JackAudioDriver.h b/src/libs/engine/JackAudioDriver.h index 73b80a78..aa0cebbc 100644 --- a/src/libs/engine/JackAudioDriver.h +++ b/src/libs/engine/JackAudioDriver.h @@ -25,6 +25,7 @@ namespace Ingen { +class Engine; class Patch; class Port; template <typename T> class DuplexPort; @@ -44,22 +45,22 @@ public: void add_to_driver(); void remove_from_driver(); - void set_name(const string& name) { jack_port_set_name(m_jack_port, name.c_str()); }; + void set_name(const string& name) { jack_port_set_name(_jack_port, name.c_str()); }; void prepare_buffer(jack_nframes_t nframes); - jack_port_t* jack_port() const { return m_jack_port; } - DuplexPort<Sample>* patch_port() const { return m_patch_port; } + jack_port_t* jack_port() const { return _jack_port; } + DuplexPort<Sample>* patch_port() const { return _patch_port; } private: // Prevent copies (undefined) JackAudioPort(const JackAudioPort&); JackAudioPort& operator=(const JackAudioPort&); - JackAudioDriver* m_driver; - jack_port_t* m_jack_port; - jack_sample_t* m_jack_buffer; ///< Cached for output ports - DuplexPort<Sample>* m_patch_port; + JackAudioDriver* _driver; + jack_port_t* _jack_port; + jack_sample_t* _jack_buffer; ///< Cached for output ports + DuplexPort<Sample>* _patch_port; }; @@ -75,8 +76,7 @@ private: class JackAudioDriver : public AudioDriver { public: - JackAudioDriver(); - JackAudioDriver(jack_client_t *jack_client); + JackAudioDriver(Engine& engine, jack_client_t *jack_client = 0); ~JackAudioDriver(); void activate(); @@ -84,26 +84,26 @@ public: void enable(); void disable(); - void process_events(jack_nframes_t block_start, jack_nframes_t block_end); + void process_events(SampleCount nframes, FrameTime cycle_start, FrameTime cycle_end); DriverPort* create_port(DuplexPort<Sample>* patch_port); - Patch* root_patch() { return m_root_patch; } - void set_root_patch(Patch* patch) { m_root_patch = patch; } + Patch* root_patch() { return _root_patch; } + void set_root_patch(Patch* patch) { _root_patch = patch; } /** Transport state for this frame. * Intended to only be called from the audio thread. */ - inline const jack_position_t* position() { return &m_position; } - inline const jack_transport_state_t transport_state() { return m_transport_state; } + inline const jack_position_t* position() { return &_position; } + inline const jack_transport_state_t transport_state() { return _transport_state; } - bool is_realtime() { return jack_is_realtime(m_client); } + bool is_realtime() { return jack_is_realtime(_client); } - jack_client_t* jack_client() const { return m_client; } - SampleCount buffer_size() const { return m_buffer_size; } - SampleCount sample_rate() const { return m_sample_rate; } - bool is_activated() const { return m_is_activated; } + jack_client_t* jack_client() const { return _client; } + SampleCount buffer_size() const { return _buffer_size; } + SampleCount sample_rate() const { return _sample_rate; } + bool is_activated() const { return _is_activated; } - SampleCount time_stamp() const { return jack_frame_time(m_client); } + inline SampleCount frame_time() const { return jack_frame_time(_client); } private: // Prevent copies (undefined) @@ -124,45 +124,46 @@ private: inline static int sample_rate_cb(jack_nframes_t nframes, void* const jack_driver); // Non static callbacks - int m_process_cb(jack_nframes_t nframes); - void m_shutdown_cb(); - int m_buffer_size_cb(jack_nframes_t nframes); - int m_sample_rate_cb(jack_nframes_t nframes); - - jack_client_t* m_client; - jack_nframes_t m_buffer_size; - jack_nframes_t m_sample_rate; - bool m_is_activated; - bool m_local_client; ///< Whether m_client should be closed on destruction - jack_position_t m_position; - jack_transport_state_t m_transport_state; + int _process_cb(jack_nframes_t nframes); + void _shutdown_cb(); + int _buffer_size_cb(jack_nframes_t nframes); + int _sample_rate_cb(jack_nframes_t nframes); + + Engine& _engine; + jack_client_t* _client; + jack_nframes_t _buffer_size; + jack_nframes_t _sample_rate; + bool _is_activated; + bool _local_client; ///< Whether _client should be closed on destruction + jack_position_t _position; + jack_transport_state_t _transport_state; - List<JackAudioPort*> m_ports; + List<JackAudioPort*> _ports; - Patch* m_root_patch; + Patch* _root_patch; }; inline int JackAudioDriver::process_cb(jack_nframes_t nframes, void* jack_driver) { - return ((JackAudioDriver*)jack_driver)->m_process_cb(nframes); + return ((JackAudioDriver*)jack_driver)->_process_cb(nframes); } inline void JackAudioDriver::shutdown_cb(void* jack_driver) { - return ((JackAudioDriver*)jack_driver)->m_shutdown_cb(); + return ((JackAudioDriver*)jack_driver)->_shutdown_cb(); } inline int JackAudioDriver::buffer_size_cb(jack_nframes_t nframes, void* jack_driver) { - return ((JackAudioDriver*)jack_driver)->m_buffer_size_cb(nframes); + return ((JackAudioDriver*)jack_driver)->_buffer_size_cb(nframes); } inline int JackAudioDriver::sample_rate_cb(jack_nframes_t nframes, void* jack_driver) { - return ((JackAudioDriver*)jack_driver)->m_sample_rate_cb(nframes); + return ((JackAudioDriver*)jack_driver)->_sample_rate_cb(nframes); } diff --git a/src/libs/engine/LADSPANode.cpp b/src/libs/engine/LADSPANode.cpp index 96be6771..b01f8900 100644 --- a/src/libs/engine/LADSPANode.cpp +++ b/src/libs/engine/LADSPANode.cpp @@ -168,9 +168,9 @@ LADSPANode::deactivate() void -LADSPANode::process(SampleCount nframes) +LADSPANode::process(SampleCount nframes, FrameTime start, FrameTime end) { - NodeBase::process(nframes); // mixes down input ports + NodeBase::process(nframes, start, end); // mixes down input ports for (size_t i=0; i < _poly; ++i) _descriptor->run(_instances[i], nframes); } diff --git a/src/libs/engine/LADSPANode.h b/src/libs/engine/LADSPANode.h index 677145fe..7fc78fb6 100644 --- a/src/libs/engine/LADSPANode.h +++ b/src/libs/engine/LADSPANode.h @@ -41,7 +41,7 @@ public: void activate(); void deactivate(); - void process(SampleCount nframes); + void process(SampleCount nframes, FrameTime start, FrameTime end); void set_port_buffer(size_t voice, size_t port_num, void* buf); diff --git a/src/libs/engine/LV2Node.cpp b/src/libs/engine/LV2Node.cpp index d56778c1..40270409 100644 --- a/src/libs/engine/LV2Node.cpp +++ b/src/libs/engine/LV2Node.cpp @@ -164,9 +164,9 @@ LV2Node::deactivate() void -LV2Node::process(SampleCount nframes) +LV2Node::process(SampleCount nframes, FrameTime start, FrameTime end) { - NodeBase::process(nframes); // mixes down input ports + NodeBase::process(nframes, start, end); // mixes down input ports for (size_t i=0; i < _poly; ++i) slv2_instance_run(_instances[i], nframes); } diff --git a/src/libs/engine/LV2Node.h b/src/libs/engine/LV2Node.h index 1c2c8416..224024a3 100644 --- a/src/libs/engine/LV2Node.h +++ b/src/libs/engine/LV2Node.h @@ -47,7 +47,7 @@ public: void activate(); void deactivate(); - void process(SampleCount nframes); + void process(SampleCount nframes, FrameTime start, FrameTime end); void set_port_buffer(size_t voice, size_t port_num, void* buf); diff --git a/src/libs/engine/MidiControlNode.cpp b/src/libs/engine/MidiControlNode.cpp index 32f14dc2..b469f590 100644 --- a/src/libs/engine/MidiControlNode.cpp +++ b/src/libs/engine/MidiControlNode.cpp @@ -16,7 +16,6 @@ #include "MidiControlNode.h" #include <math.h> -#include "Engine.h" #include "PostProcessor.h" #include "MidiLearnEvent.h" #include "InputPort.h" @@ -63,9 +62,9 @@ MidiControlNode::MidiControlNode(const string& path, size_t poly, Patch* parent, void -MidiControlNode::process(SampleCount nframes) +MidiControlNode::process(SampleCount nframes, FrameTime start, FrameTime end) { - InternalNode::process(nframes); + InternalNode::process(nframes, start, end); MidiMessage ev; @@ -88,15 +87,18 @@ MidiControlNode::control(uchar control_num, uchar val, SampleCount offset) const Sample nval = (val / 127.0f); // normalized [0, 1] if (_learning) { + assert(false); // FIXME FIXME FIXME +#if 0 assert(_learn_event != NULL); _param_port->set_value(control_num, offset); assert(_param_port->buffer(0)->value_at(0) == control_num); _learn_event->set_value(control_num); _learn_event->execute(offset); - Engine::instance().post_processor()->push(_learn_event); - Engine::instance().post_processor()->whip(); + //Engine::instance().post_processor()->push(_learn_event); + //Engine::instance().post_processor()->whip(); _learning = false; _learn_event = NULL; +#endif } if (_log_port->buffer(0)->value_at(0) > 0.0f) { diff --git a/src/libs/engine/MidiControlNode.h b/src/libs/engine/MidiControlNode.h index 952aa0c4..b291fe9c 100644 --- a/src/libs/engine/MidiControlNode.h +++ b/src/libs/engine/MidiControlNode.h @@ -42,7 +42,7 @@ class MidiControlNode : public InternalNode public: MidiControlNode(const string& path, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size); - void process(SampleCount nframes); + void process(SampleCount nframes, FrameTime start, FrameTime end); void control(uchar control_num, uchar val, SampleCount offset); diff --git a/src/libs/engine/MidiNoteNode.cpp b/src/libs/engine/MidiNoteNode.cpp index 5d08c495..956c1494 100644 --- a/src/libs/engine/MidiNoteNode.cpp +++ b/src/libs/engine/MidiNoteNode.cpp @@ -17,7 +17,6 @@ #include "MidiNoteNode.h" #include <cmath> #include <iostream> -#include "Engine.h" #include "MidiMessage.h" #include "InputPort.h" #include "OutputPort.h" @@ -72,9 +71,9 @@ MidiNoteNode::~MidiNoteNode() void -MidiNoteNode::process(SampleCount nframes) +MidiNoteNode::process(SampleCount nframes, FrameTime start, FrameTime end) { - InternalNode::process(nframes); + InternalNode::process(nframes, start, end); MidiMessage ev; @@ -84,24 +83,24 @@ MidiNoteNode::process(SampleCount nframes) switch (ev.buffer[0] & 0xF0) { case MIDI_CMD_NOTE_ON: if (ev.buffer[2] == 0) - note_off(ev.buffer[1], ev.time); + note_off(ev.buffer[1], ev.time, nframes, start, end); else - note_on(ev.buffer[1], ev.buffer[2], ev.time); + note_on(ev.buffer[1], ev.buffer[2], ev.time, nframes, start, end); break; case MIDI_CMD_NOTE_OFF: - note_off(ev.buffer[1], ev.time); + note_off(ev.buffer[1], ev.time, nframes, start, end); break; case MIDI_CMD_CONTROL: switch (ev.buffer[1]) { case MIDI_CTL_ALL_NOTES_OFF: case MIDI_CTL_ALL_SOUNDS_OFF: - all_notes_off(ev.time); + all_notes_off(ev.time, nframes, start, end); break; case MIDI_CTL_SUSTAIN: if (ev.buffer[2] > 63) - sustain_on(); + sustain_on(ev.time, nframes, start, end); else - sustain_off(ev.time); + sustain_off(ev.time, nframes, start, end); break; case MIDI_CMD_BENDER: @@ -115,12 +114,10 @@ MidiNoteNode::process(SampleCount nframes) void -MidiNoteNode::note_on(uchar note_num, uchar velocity, SampleCount offset) +MidiNoteNode::note_on(uchar note_num, uchar velocity, SampleCount nframes, FrameTime time, FrameTime start, FrameTime end) { - // FIXME: this is stupid.. - const jack_nframes_t time_stamp = Engine::instance().audio_driver()->time_stamp(); - - assert(offset < _buffer_size); + assert(time >= start && time <= end); + assert(time - start < _buffer_size); assert(note_num <= 127); Key* key = &_keys[note_num]; @@ -165,16 +162,20 @@ MidiNoteNode::note_on(uchar note_num, uchar velocity, SampleCount offset) // Store key information for later reallocation on note off key->state = Key::Key::ON_ASSIGNED; key->voice = voice_num; - key->time = time_stamp; + key->time = time; // Trigger voice voice->state = Voice::Voice::ACTIVE; voice->note = note_num; - voice->time = time_stamp; + voice->time = time; assert(_keys[voice->note].state == Key::Key::ON_ASSIGNED); assert(_keys[voice->note].voice == voice_num); + // FIXME FIXME FIXME + + SampleCount offset = time - start; + // one-sample jitter hack to avoid having to deal with trigger sample "next time" if (offset == (SampleCount)(_buffer_size-1)) --offset; @@ -195,9 +196,10 @@ MidiNoteNode::note_on(uchar note_num, uchar velocity, SampleCount offset) void -MidiNoteNode::note_off(uchar note_num, SampleCount offset) +MidiNoteNode::note_off(uchar note_num, FrameTime time, SampleCount nframes, FrameTime start, FrameTime end) { - assert(offset < _buffer_size); + assert(time >= start && time <= end); + assert(time - start < _buffer_size); Key* key = &_keys[note_num]; @@ -208,7 +210,7 @@ MidiNoteNode::note_off(uchar note_num, SampleCount offset) key->state = Key::OFF; if ( ! _sustain) - free_voice(key->voice, offset); + free_voice(key->voice, time - start, nframes, start, end); else _voices[key->voice].state = Voice::HOLDING; } @@ -218,8 +220,11 @@ MidiNoteNode::note_off(uchar note_num, SampleCount offset) void -MidiNoteNode::free_voice(size_t voice, SampleCount offset) +MidiNoteNode::free_voice(size_t voice, FrameTime time, SampleCount nframes, FrameTime start, FrameTime end) { + assert(time >= start && time <= end); + assert(time - start < _buffer_size); + // Find a key to reassign to the freed voice (the newest, if there is one) Key* replace_key = NULL; uchar replace_key_num = 0; @@ -238,7 +243,7 @@ MidiNoteNode::free_voice(size_t voice, SampleCount offset) assert(replace_key->state == Key::ON_UNASSIGNED); // Change the freq but leave the gate high and don't retrigger - _freq_port->buffer(voice)->set(note_to_freq(replace_key_num), offset); + _freq_port->buffer(voice)->set(note_to_freq(replace_key_num), time - start); replace_key->state = Key::ON_ASSIGNED; replace_key->voice = voice; @@ -248,22 +253,24 @@ MidiNoteNode::free_voice(size_t voice, SampleCount offset) } else { // No new note for voice, deactivate (set gate low) //cerr << "[MidiNoteNode] Note off. Key " << (int)note_num << ", Voice " << voice << " Killed" << endl; - _gate_port->buffer(voice)->set(0.0f, offset); + _gate_port->buffer(voice)->set(0.0f, time - start); _voices[voice].state = Voice::FREE; } } void -MidiNoteNode::all_notes_off(SampleCount offset) +MidiNoteNode::all_notes_off(SampleCount nframes, FrameTime time, FrameTime start, FrameTime end) { + assert(time >= start && time <= end); + assert(time - start < _buffer_size); + //cerr << "Note off starting at sample " << offset << endl; - assert(offset < _buffer_size); // FIXME: set all keys to Key::OFF? for (size_t i=0; i < _poly; ++i) { - _gate_port->buffer(i)->set(0.0f, offset); + _gate_port->buffer(i)->set(0.0f, time - start); _voices[i].state = Voice::FREE; } } @@ -280,20 +287,23 @@ MidiNoteNode::note_to_freq(int num) void -MidiNoteNode::sustain_on() +MidiNoteNode::sustain_on(FrameTime time, SampleCount nframes, FrameTime start, FrameTime end) { _sustain = true; } void -MidiNoteNode::sustain_off(SampleCount offset) +MidiNoteNode::sustain_off(FrameTime time, SampleCount nframes, FrameTime start, FrameTime end) { + assert(time >= start && time <= end); + assert(time - start < _buffer_size); + _sustain = false; for (size_t i=0; i < _poly; ++i) if (_voices[i].state == Voice::HOLDING) - free_voice(i, offset); + free_voice(i, time, nframes, start, end); } diff --git a/src/libs/engine/MidiNoteNode.h b/src/libs/engine/MidiNoteNode.h index 1f727b98..ba86455d 100644 --- a/src/libs/engine/MidiNoteNode.h +++ b/src/libs/engine/MidiNoteNode.h @@ -42,17 +42,16 @@ public: MidiNoteNode(const string& path, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size); ~MidiNoteNode(); - void process(SampleCount nframes); + void process(SampleCount nframes, FrameTime start, FrameTime end); - void note_on(uchar note_num, uchar velocity, SampleCount offset); - void note_off(uchar note_num, SampleCount offset); - void all_notes_off(SampleCount offset); + void note_on(uchar note_num, uchar velocity, SampleCount nframes, FrameTime time, FrameTime start, FrameTime end); + void note_off(uchar note_num, FrameTime time, SampleCount nframes, FrameTime start, FrameTime end); + void all_notes_off(SampleCount nframes, FrameTime time, FrameTime start, FrameTime end); - void sustain_on(); - void sustain_off(SampleCount offset); + void sustain_on(FrameTime time, SampleCount nframes, FrameTime start, FrameTime end); + void sustain_off(FrameTime time, SampleCount nframes, FrameTime start, FrameTime end); private: - /** Key, one for each key on the keyboard */ struct Key { enum State { OFF, ON_ASSIGNED, ON_UNASSIGNED }; @@ -68,7 +67,7 @@ private: }; float note_to_freq(int num); - void free_voice(size_t voice, SampleCount offset); + void free_voice(size_t voice, FrameTime time, SampleCount nframes, FrameTime start, FrameTime end); Voice* _voices; Key _keys[128]; diff --git a/src/libs/engine/MidiTriggerNode.cpp b/src/libs/engine/MidiTriggerNode.cpp index c117a70c..b4b5cd8b 100644 --- a/src/libs/engine/MidiTriggerNode.cpp +++ b/src/libs/engine/MidiTriggerNode.cpp @@ -56,9 +56,9 @@ MidiTriggerNode::MidiTriggerNode(const string& path, size_t poly, Patch* parent, void -MidiTriggerNode::process(SampleCount nframes) +MidiTriggerNode::process(SampleCount nframes, FrameTime start, FrameTime end) { - InternalNode::process(nframes); + InternalNode::process(nframes, start, end); MidiMessage ev; @@ -68,12 +68,12 @@ MidiTriggerNode::process(SampleCount nframes) switch (ev.buffer[0] & 0xF0) { case MIDI_CMD_NOTE_ON: if (ev.buffer[2] == 0) - note_off(ev.buffer[1], ev.time); + note_off(ev.buffer[1], ev.time, nframes, start, end); else - note_on(ev.buffer[1], ev.buffer[2], ev.time); + note_on(ev.buffer[1], ev.buffer[2], ev.time, nframes, start, end); break; case MIDI_CMD_NOTE_OFF: - note_off(ev.buffer[1], ev.time); + note_off(ev.buffer[1], ev.time, nframes, start, end); break; case MIDI_CMD_CONTROL: if (ev.buffer[1] == MIDI_CTL_ALL_NOTES_OFF @@ -87,14 +87,19 @@ MidiTriggerNode::process(SampleCount nframes) void -MidiTriggerNode::note_on(uchar note_num, uchar velocity, SampleCount offset) +MidiTriggerNode::note_on(uchar note_num, uchar velocity, FrameTime time, SampleCount nframes, FrameTime start, FrameTime end) { + assert(time >= start && time <= end); + assert(time - start < _buffer_size); + //std::cerr << "Note on starting at sample " << offset << std::endl; - assert(offset < _buffer_size); const Sample filter_note = _note_port->buffer(0)->value_at(0); if (filter_note >= 0.0 && filter_note < 127.0 && (note_num == (uchar)filter_note)){ - + + // FIXME FIXME FIXME + SampleCount offset = time - start; + // See comments in MidiNoteNode::note_on (FIXME) if (offset == (SampleCount)(_buffer_size-1)) --offset; @@ -108,12 +113,13 @@ MidiTriggerNode::note_on(uchar note_num, uchar velocity, SampleCount offset) void -MidiTriggerNode::note_off(uchar note_num, SampleCount offset) +MidiTriggerNode::note_off(uchar note_num, FrameTime time, SampleCount nframes, FrameTime start, FrameTime end) { - assert(offset < _buffer_size); + assert(time >= start && time <= end); + assert(time - start < _buffer_size); if (note_num == lrintf(_note_port->buffer(0)->value_at(0))) - _gate_port->buffer(0)->set(0.0f, offset); + _gate_port->buffer(0)->set(0.0f, time - start); } diff --git a/src/libs/engine/MidiTriggerNode.h b/src/libs/engine/MidiTriggerNode.h index bf11f0b8..e45e6d9e 100644 --- a/src/libs/engine/MidiTriggerNode.h +++ b/src/libs/engine/MidiTriggerNode.h @@ -45,10 +45,10 @@ class MidiTriggerNode : public InternalNode public: MidiTriggerNode(const string& path, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size); - void process(SampleCount nframes); + void process(SampleCount nframes, FrameTime start, FrameTime end); - void note_on(uchar note_num, uchar velocity, SampleCount offset); - void note_off(uchar note_num, SampleCount offset); + void note_on(uchar note_num, uchar velocity, FrameTime time, SampleCount nframes, FrameTime start, FrameTime end); + void note_off(uchar note_num, FrameTime time, SampleCount nframes, FrameTime start, FrameTime end); private: InputPort<MidiMessage>* _midi_in_port; diff --git a/src/libs/engine/Node.h b/src/libs/engine/Node.h index 6d1158b0..beabb7da 100644 --- a/src/libs/engine/Node.h +++ b/src/libs/engine/Node.h @@ -63,6 +63,13 @@ public: virtual void activate() = 0; virtual void deactivate() = 0; virtual bool activated() = 0; + + /** Run the node for @a nframes input/output. + * + * @a start and @a end are transport times: end is not redundant in the case + * of varispeed, where end-start != nframes. + */ + virtual void process(SampleCount nframes, FrameTime start, FrameTime end) = 0; virtual void set_port_buffer(size_t voice, size_t port_num, void* buf) = 0; @@ -91,7 +98,7 @@ public: /** The Patch this Node belongs to. */ virtual Patch* parent_patch() const = 0; - /** Information about what 'plugin' this Node is an instance of. + /** Information about the Plugin this Node is an instance of. * Not the best name - not all nodes come from plugins (ie Patch) */ virtual const Plugin* plugin() const = 0; diff --git a/src/libs/engine/NodeBase.cpp b/src/libs/engine/NodeBase.cpp index 80ceb6ef..2532064e 100644 --- a/src/libs/engine/NodeBase.cpp +++ b/src/libs/engine/NodeBase.cpp @@ -19,7 +19,6 @@ #include <iostream> #include <stdint.h> #include "util.h" -#include "Engine.h" #include "Array.h" #include "Plugin.h" #include "ClientBroadcaster.h" @@ -35,6 +34,7 @@ namespace Ingen { NodeBase::NodeBase(const Plugin* plugin, const string& name, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size) : Node(parent, name), + _store(NULL), _plugin(plugin), _poly(poly), _srate(srate), @@ -84,16 +84,21 @@ void NodeBase::send_creation_messages(ClientInterface* client) const { cerr << "FIXME: send_creation\n"; - //Engine::instance().client_broadcaster()->send_node_to(client, this); + //_engine.client_broadcaster()->send_node_to(client, this); } */ void -NodeBase::add_to_store() +NodeBase::add_to_store(ObjectStore* store) { - Engine::instance().object_store()->add(this); + assert(!_store); + + store->add(this); + for (size_t i=0; i < num_ports(); ++i) - Engine::instance().object_store()->add(_ports->at(i)); + store->add(_ports->at(i)); + + _store = store; } @@ -101,32 +106,34 @@ void NodeBase::remove_from_store() { // Remove self - TreeNode<GraphObject*>* node = Engine::instance().object_store()->remove(path()); + TreeNode<GraphObject*>* node = _store->remove(path()); if (node != NULL) { - assert(Engine::instance().object_store()->find(path()) == NULL); + assert(_store->find(path()) == NULL); delete node; } // Remove ports for (size_t i=0; i < num_ports(); ++i) { - node = Engine::instance().object_store()->remove(_ports->at(i)->path()); + node = _store->remove(_ports->at(i)->path()); if (node != NULL) { - assert(Engine::instance().object_store()->find(_ports->at(i)->path()) == NULL); + assert(_store->find(_ports->at(i)->path()) == NULL); delete node; } } + + _store = NULL; } /** Runs the Node for the specified number of frames (block size) */ void -NodeBase::process(SampleCount nframes) +NodeBase::process(SampleCount nframes, FrameTime start, FrameTime end) { assert(_activated); // Mix down any ports with multiple inputs for (size_t i=0; i < _ports->size(); ++i) - _ports->at(i)->process(nframes); + _ports->at(i)->process(nframes, start, end); } @@ -145,23 +152,23 @@ NodeBase::set_path(const Path& new_path) // Reinsert ports for (size_t i=0; i < num_ports(); ++i) { - treenode = Engine::instance().object_store()->remove(old_path +"/"+ _ports->at(i)->name()); + treenode = _store->remove(old_path +"/"+ _ports->at(i)->name()); assert(treenode != NULL); assert(treenode->node() == _ports->at(i)); treenode->key(new_path +"/" + _ports->at(i)->name()); - Engine::instance().object_store()->add(treenode); + _store->add(treenode); } // Rename and reinsert self - treenode = Engine::instance().object_store()->remove(old_path); + treenode = _store->remove(old_path); assert(treenode != NULL); assert(treenode->node() == this); GraphObject::set_path(new_path); treenode->key(new_path); - Engine::instance().object_store()->add(treenode); + _store->add(treenode); - assert(Engine::instance().object_store()->find(new_path) == this); + assert(_store->find(new_path) == this); } diff --git a/src/libs/engine/NodeBase.h b/src/libs/engine/NodeBase.h index df9c6e7c..78a8cab5 100644 --- a/src/libs/engine/NodeBase.h +++ b/src/libs/engine/NodeBase.h @@ -28,6 +28,8 @@ namespace Ingen { class Plugin; class Patch; +class ObjectStore; + namespace Shared { class ClientInterface; } using Shared::ClientInterface; @@ -50,14 +52,14 @@ public: virtual void deactivate(); bool activated() { return _activated; } - virtual void process(SampleCount nframes); + virtual void process(SampleCount nframes, FrameTime start, FrameTime end); virtual void set_port_buffer(size_t voice, size_t port_num, void* buf) {} virtual void add_to_patch() {} virtual void remove_from_patch() {} - void add_to_store(); + void add_to_store(ObjectStore* store); void remove_from_store(); //void send_creation_messages(ClientInterface* client) const; @@ -89,6 +91,8 @@ protected: NodeBase(const NodeBase&); NodeBase& operator=(const NodeBase&); + ObjectStore* _store; + const Plugin* _plugin; size_t _poly; diff --git a/src/libs/engine/NodeFactory.cpp b/src/libs/engine/NodeFactory.cpp index 65829d97..7bac3bd8 100644 --- a/src/libs/engine/NodeFactory.cpp +++ b/src/libs/engine/NodeFactory.cpp @@ -56,8 +56,6 @@ namespace Ingen { NodeFactory::NodeFactory() : _has_loaded(false) { - pthread_mutex_init(&_plugin_list_mutex, NULL); - // Add builtin plugin types to _internal_plugins list // FIXME: ewwww, definitely a better way to do this! @@ -101,8 +99,6 @@ NodeFactory::load_plugins() // this (expensive!) stuff to happen. Not the best solution - would be nice // if clients could refresh plugins list for whatever reason :/ if (!_has_loaded) { - pthread_mutex_lock(&_plugin_list_mutex); - _plugins.clear(); _plugins = _internal_plugins; @@ -117,8 +113,6 @@ NodeFactory::load_plugins() #endif _has_loaded = true; - - pthread_mutex_unlock(&_plugin_list_mutex); } } @@ -137,8 +131,6 @@ NodeFactory::load_plugin(const Plugin* a_plugin, assert(poly == 1 || poly == parent->internal_poly()); assert(a_plugin); - pthread_mutex_lock(&_plugin_list_mutex); - Node* r = NULL; Plugin* plugin = NULL; @@ -201,8 +193,6 @@ NodeFactory::load_plugin(const Plugin* a_plugin, cerr << "[NodeFactory] WARNING: Unknown plugin type." << endl; } - pthread_mutex_unlock(&_plugin_list_mutex); - return r; } diff --git a/src/libs/engine/NodeFactory.h b/src/libs/engine/NodeFactory.h index cf2fb0d0..25408b2d 100644 --- a/src/libs/engine/NodeFactory.h +++ b/src/libs/engine/NodeFactory.h @@ -56,9 +56,6 @@ public: const list<Plugin*>& plugins() { return _plugins; } - void lock_plugin_list() { pthread_mutex_lock(&_plugin_list_mutex); } - void unlock_plugin_list() { pthread_mutex_unlock(&_plugin_list_mutex); } - private: #ifdef HAVE_LADSPA void load_ladspa_plugins(); @@ -81,9 +78,6 @@ private: list<Plugin*> _internal_plugins; list<Plugin*> _plugins; - /** Used to protect the list while load_plugins is building it. */ - pthread_mutex_t _plugin_list_mutex; - bool _has_loaded; }; diff --git a/src/libs/engine/OSCReceiver.cpp b/src/libs/engine/OSCReceiver.cpp index 3b2e0be6..5c08c17a 100644 --- a/src/libs/engine/OSCReceiver.cpp +++ b/src/libs/engine/OSCReceiver.cpp @@ -47,8 +47,8 @@ using Shared::ClientKey; */ -OSCReceiver::OSCReceiver(size_t queue_size, const char* const port) -: QueuedEngineInterface(queue_size, queue_size), // FIXME +OSCReceiver::OSCReceiver(Engine& engine, size_t queue_size, const char* const port) +: QueuedEngineInterface(engine, queue_size, queue_size), // FIXME _port(port), _server(NULL), _osc_responder(NULL) diff --git a/src/libs/engine/OSCReceiver.h b/src/libs/engine/OSCReceiver.h index d217319a..671944fd 100644 --- a/src/libs/engine/OSCReceiver.h +++ b/src/libs/engine/OSCReceiver.h @@ -59,7 +59,7 @@ inline static int name##_cb(LO_HANDLER_ARGS, void* osc_receiver)\ class OSCReceiver : public QueuedEngineInterface { public: - OSCReceiver(size_t queue_size, const char* const port); + OSCReceiver(Engine& engine, size_t queue_size, const char* const port); ~OSCReceiver(); void activate(); diff --git a/src/libs/engine/OSCResponder.cpp b/src/libs/engine/OSCResponder.cpp index 2fd68540..d67342d6 100644 --- a/src/libs/engine/OSCResponder.cpp +++ b/src/libs/engine/OSCResponder.cpp @@ -15,7 +15,6 @@ */ #include "OSCResponder.h" -#include "Engine.h" #include "ClientBroadcaster.h" #include "interface/ClientKey.h" #include <cstdlib> @@ -51,13 +50,6 @@ OSCResponder::~OSCResponder() } -CountedPtr<Shared::ClientInterface> -OSCResponder::find_client() -{ - return Engine::instance().client_broadcaster()->client(ClientKey(ClientKey::OSC_URL, _url)); -} - - void OSCResponder::respond_ok() { diff --git a/src/libs/engine/OSCResponder.h b/src/libs/engine/OSCResponder.h index 57e61886..78b40894 100644 --- a/src/libs/engine/OSCResponder.h +++ b/src/libs/engine/OSCResponder.h @@ -41,13 +41,13 @@ public: OSCResponder(int32_t id, char* url); ~OSCResponder(); - CountedPtr<Shared::ClientInterface> find_client(); - void respond_ok(); void respond_error(const string& msg); const char* url() const { return _url; } + ClientKey client_key() { return ClientKey(ClientKey::OSC_URL, _url); } + private: int32_t _id; char* const _url; diff --git a/src/libs/engine/ObjectSender.cpp b/src/libs/engine/ObjectSender.cpp index 3055217c..063a2d1d 100644 --- a/src/libs/engine/ObjectSender.cpp +++ b/src/libs/engine/ObjectSender.cpp @@ -16,7 +16,6 @@ #include "ObjectSender.h" #include "interface/ClientInterface.h" -#include "Engine.h" #include "ObjectStore.h" #include "Patch.h" #include "Node.h" @@ -27,22 +26,6 @@ namespace Ingen { -/** Send all currently existing objects to client. - */ -void -ObjectSender::send_all(ClientInterface* client) -{ - Patch* root = Engine::instance().object_store()->find_patch("/"); - assert(root); - send_patch(client, root); - /*for (Tree<GraphObject*>::iterator i = Engine::instance().object_store()->objects().begin(); - i != Engine::instance().object_store()->objects().end(); ++i) - if ((*i)->as_patch() != NULL && (*i)->parent() == NULL) - send_patch(client, (*i)->as_patch());*/ - //(*i)->as_node()->send_creation_messages(client); - -} - void ObjectSender::send_patch(ClientInterface* client, const Patch* patch) @@ -85,7 +68,7 @@ ObjectSender::send_patch(ClientInterface* client, const Patch* patch) for (map<string, string>::const_iterator j = data.begin(); j != data.end(); ++j) client->metadata_update(patch->path(), (*j).first, (*j).second); - if (patch->process()) + if (patch->enabled()) client->patch_enabled(patch->path()); } @@ -173,12 +156,8 @@ ObjectSender::send_port(ClientInterface* client, const Port* port) void -ObjectSender::send_plugins(ClientInterface* client) +ObjectSender::send_plugins(ClientInterface* client, const list<Plugin*>& plugs) { - Engine::instance().node_factory()->lock_plugin_list(); - - const list<Plugin*>& plugs = Engine::instance().node_factory()->plugins(); - /* lo_timetag tt; lo_timetag_now(&tt); @@ -221,7 +200,6 @@ ObjectSender::send_plugins(ClientInterface* client) for (list<lo_bundle>::const_iterator i = msgs.begin(); i != msgs.end(); ++i) lo_message_free(*i); */ - Engine::instance().node_factory()->unlock_plugin_list(); } diff --git a/src/libs/engine/ObjectSender.h b/src/libs/engine/ObjectSender.h index 93cdf2b9..38b1577f 100644 --- a/src/libs/engine/ObjectSender.h +++ b/src/libs/engine/ObjectSender.h @@ -17,6 +17,8 @@ #ifndef OBJECTSENDER_H #define OBJECTSENDER_H +#include <list> + namespace Ingen { namespace Shared { @@ -26,6 +28,7 @@ namespace Shared { class Patch; class Node; class Port; +class Plugin; /** Utility class for sending GraphObjects to clients through ClientInterface. @@ -42,11 +45,10 @@ public: // FIXME: Make all object parameters const - static void send_all(ClientInterface* client); static void send_patch(ClientInterface* client, const Patch* patch); static void send_node(ClientInterface* client, const Node* node); static void send_port(ClientInterface* client, const Port* port); - static void send_plugins(ClientInterface* client); + static void send_plugins(ClientInterface* client, const std::list<Plugin*>& plugs); }; } // namespace Ingen diff --git a/src/libs/engine/Patch.cpp b/src/libs/engine/Patch.cpp index c8c3dd3a..257deb59 100644 --- a/src/libs/engine/Patch.cpp +++ b/src/libs/engine/Patch.cpp @@ -94,18 +94,17 @@ Patch::deactivate() void -Patch::process(bool p) +Patch::disable() { - if (!p) { - // Write output buffers to 0 - /*for (List<InternalNode*>::iterator i = _bridge_nodes.begin(); i != _bridge_nodes.end(); ++i) { - assert((*i)->as_port() != NULL); - if ((*i)->as_port()->port_info()->is_output()) - (*i)->as_port()->clear_buffers();*/ - for (List<Port*>::iterator i = _output_ports.begin(); i != _output_ports.end(); ++i) - (*i)->clear_buffers(); - } - _process = p; + // Write output buffers to 0 + /*for (List<InternalNode*>::iterator i = _bridge_nodes.begin(); i != _bridge_nodes.end(); ++i) { + assert((*i)->as_port() != NULL); + if ((*i)->as_port()->port_info()->is_output()) + (*i)->as_port()->clear_buffers();*/ + for (List<Port*>::iterator i = _output_ports.begin(); i != _output_ports.end(); ++i) + (*i)->clear_buffers(); + + _process = false; } @@ -114,7 +113,7 @@ Patch::process(bool p) * Calls all Nodes in the order _process_order specifies. */ void -Patch::process(SampleCount nframes) +Patch::process(SampleCount nframes, FrameTime start, FrameTime end) { if (_process_order == NULL || !_process) return; @@ -123,31 +122,31 @@ Patch::process(SampleCount nframes) // Prepare input ports for nodes to consume for (List<Port*>::iterator i = _input_ports.begin(); i != _input_ports.end(); ++i) - (*i)->process(nframes); + (*i)->process(nframes, start, end); // Run all nodes (consume input ports) for (size_t i=0; i < _process_order->size(); ++i) { // Could be a gap due to a node removal event (see RemoveNodeEvent.cpp) // Yes, this is ugly if (_process_order->at(i) != NULL) - _process_order->at(i)->process(nframes); + _process_order->at(i)->process(nframes, start, end); } // Prepare output ports (for caller to consume) for (List<Port*>::iterator i = _output_ports.begin(); i != _output_ports.end(); ++i) - (*i)->process(nframes); + (*i)->process(nframes, start, end); } void -Patch::add_to_store() +Patch::add_to_store(ObjectStore* store) { // Add self and ports - NodeBase::add_to_store(); + NodeBase::add_to_store(store); // Add nodes for (List<Node*>::iterator j = _nodes.begin(); j != _nodes.end(); ++j) - (*j)->add_to_store(); + (*j)->add_to_store(store); } diff --git a/src/libs/engine/Patch.h b/src/libs/engine/Patch.h index 4a37d2d0..b6b709c4 100644 --- a/src/libs/engine/Patch.h +++ b/src/libs/engine/Patch.h @@ -54,11 +54,11 @@ public: void activate(); void deactivate(); - void process(SampleCount nframes); + void process(SampleCount nframes, FrameTime start, FrameTime end); //void send_creation_messages(ClientInterface* client) const; - void add_to_store(); + void add_to_store(ObjectStore* store); void remove_from_store(); void set_path(const Path& new_path); @@ -91,8 +91,9 @@ public: Array<Node*>* build_process_order() const; /** Whether to run this patch's DSP bits in the audio thread */ - bool process() const { return _process; } - void process(bool p); + bool enabled() const { return _process; } + void enable() { _process = true; } + void disable(); size_t internal_poly() const { return _internal_poly; } diff --git a/src/libs/engine/Plugin.cpp b/src/libs/engine/Plugin.cpp new file mode 100644 index 00000000..338e532b --- /dev/null +++ b/src/libs/engine/Plugin.cpp @@ -0,0 +1,44 @@ +/* This file is part of Ingen. Copyright (C) 2006 Dave Robillard. + * + * 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 "Plugin.h" +#include "MidiNoteNode.h" +#include "MidiTriggerNode.h" +#include "MidiControlNode.h" +#include "TransportNode.h" + +namespace Ingen { + +Node* +Plugin::instantiate(const string& name, size_t poly, Ingen::Patch* parent, SampleRate srate, size_t buffer_size) +{ + assert(_type == Internal); + + if (_uri == "ingen:note_node") { + return new MidiNoteNode(name, poly, parent, srate, buffer_size); + } else if (_uri == "ingen:trigger_node") { + return new MidiTriggerNode(name, poly, parent, srate, buffer_size); + } else if (_uri == "ingen:control_node") { + return new MidiControlNode(name, poly, parent, srate, buffer_size); + } else if (_uri == "ingen:transport_node") { + return new TransportNode(name, poly, parent, srate, buffer_size); + } else { + return NULL; + } +} + + +} // namespace Ingen diff --git a/src/libs/engine/Port.h b/src/libs/engine/Port.h index 918681e5..e538248b 100644 --- a/src/libs/engine/Port.h +++ b/src/libs/engine/Port.h @@ -43,14 +43,14 @@ class Port : public GraphObject public: virtual ~Port() {} - void add_to_store() { assert(false); } - void remove_from_store() { assert(false); } + void add_to_store(ObjectStore* store) { assert(false); } + void remove_from_store() { assert(false); } /** A port's parent is always a node, so static cast should be safe */ Node* parent_node() const { return (Node*)_parent; } /** Called once per process cycle */ - virtual void process(SampleCount nframes) = 0; + virtual void process(SampleCount nframes, FrameTime start, FrameTime end) = 0; /** Empty buffer contents completely (ie silence) */ virtual void clear_buffers() = 0; diff --git a/src/libs/engine/PostProcessor.cpp b/src/libs/engine/PostProcessor.cpp index 47a48f21..5fd1218a 100644 --- a/src/libs/engine/PostProcessor.cpp +++ b/src/libs/engine/PostProcessor.cpp @@ -18,7 +18,6 @@ #include <cassert> #include <iostream> #include <pthread.h> -#include "Engine.h" #include "Event.h" #include "util/Queue.h" #include "Maid.h" @@ -29,8 +28,9 @@ using std::cerr; using std::cout; using std::endl; namespace Ingen { -PostProcessor::PostProcessor(size_t queue_size) -: _events(queue_size) +PostProcessor::PostProcessor(Maid& maid, size_t queue_size) +: _maid(maid), + _events(queue_size) { set_name("PostProcessor"); } @@ -47,7 +47,7 @@ PostProcessor::_whipped() Event* const ev = _events.pop(); assert(ev); ev->post_process(); - Engine::instance().maid()->push(ev); + _maid.push(ev); } } diff --git a/src/libs/engine/PostProcessor.h b/src/libs/engine/PostProcessor.h index 2ae8f28b..e29175ee 100644 --- a/src/libs/engine/PostProcessor.h +++ b/src/libs/engine/PostProcessor.h @@ -20,9 +20,10 @@ #include <pthread.h> #include "types.h" #include "util/Queue.h" -#include "util/Semaphore.h" #include "Slave.h" +class Maid; + namespace Ingen { class Event; @@ -39,7 +40,7 @@ class Event; class PostProcessor : public Slave { public: - PostProcessor(size_t queue_size); + PostProcessor(Maid& maid, size_t queue_size); /** Push an event on to the process queue, realtime-safe, not thread-safe. */ inline void push(Event* const ev) { _events.push(ev); } @@ -49,6 +50,7 @@ private: PostProcessor(const PostProcessor&); PostProcessor& operator=(const PostProcessor&); + Maid& _maid; Queue<Event*> _events; virtual void _whipped(); }; diff --git a/src/libs/engine/QueuedEngineInterface.cpp b/src/libs/engine/QueuedEngineInterface.cpp index f9ad8a00..4d38f91c 100644 --- a/src/libs/engine/QueuedEngineInterface.cpp +++ b/src/libs/engine/QueuedEngineInterface.cpp @@ -23,9 +23,10 @@ namespace Ingen { -QueuedEngineInterface::QueuedEngineInterface(size_t queued_size, size_t stamped_size) +QueuedEngineInterface::QueuedEngineInterface(Engine& engine, size_t queued_size, size_t stamped_size) : QueuedEventSource(queued_size, stamped_size) , _responder(CountedPtr<Responder>(new Responder())) // NULL responder +, _engine(engine) { } @@ -33,7 +34,7 @@ QueuedEngineInterface::QueuedEngineInterface(size_t queued_size, size_t stamped_ SampleCount QueuedEngineInterface::now() const { - return Engine::instance().audio_driver()->time_stamp(); + return _engine.audio_driver()->frame_time(); } /** Set the Responder to send responses to commands with, once the commands @@ -63,14 +64,14 @@ QueuedEngineInterface::disable_responses() void QueuedEngineInterface::register_client(ClientKey key, CountedPtr<ClientInterface> client) { - push_queued(new RegisterClientEvent(_responder, now(), key, client)); + push_queued(new RegisterClientEvent(_engine, _responder, now(), key, client)); } void QueuedEngineInterface::unregister_client(ClientKey key) { - push_queued(new UnregisterClientEvent(_responder, now(), key)); + push_queued(new UnregisterClientEvent(_engine, _responder, now(), key)); } @@ -79,7 +80,7 @@ QueuedEngineInterface::unregister_client(ClientKey key) void QueuedEngineInterface::load_plugins() { - push_queued(new LoadPluginsEvent(_responder, now())); + push_queued(new LoadPluginsEvent(_engine, _responder, now())); } @@ -87,14 +88,14 @@ QueuedEngineInterface::load_plugins() void QueuedEngineInterface::activate() { - push_queued(new ActivateEvent(_responder, now())); + push_queued(new ActivateEvent(_engine, _responder, now())); } void QueuedEngineInterface::deactivate() { - push_queued(new DeactivateEvent(_responder, now())); + push_queued(new DeactivateEvent(_engine, _responder, now())); } @@ -102,7 +103,7 @@ void QueuedEngineInterface::quit() { _responder->respond_ok(); - Engine::instance().quit(); + _engine.quit(); } @@ -113,7 +114,7 @@ void QueuedEngineInterface::create_patch(const string& path, uint32_t poly) { - push_queued(new CreatePatchEvent(_responder, now(), path, poly)); + push_queued(new CreatePatchEvent(_engine, _responder, now(), path, poly)); } @@ -122,7 +123,7 @@ void QueuedEngineInterface::create_port(const string& path, const string& data_type, bool direction) { - push_queued(new AddPortEvent(_responder, now(), path, data_type, direction)); + push_queued(new AddPortEvent(_engine, _responder, now(), path, data_type, direction)); } @@ -138,7 +139,7 @@ QueuedEngineInterface::create_node(const string& path, plugin->set_type(plugin_type); plugin->uri(plugin_uri); - push_queued(new AddNodeEvent(_responder, now(), path, plugin, polyphonic)); + push_queued(new AddNodeEvent(_engine, _responder, now(), path, plugin, polyphonic)); } @@ -156,42 +157,42 @@ QueuedEngineInterface::create_node(const string& path, plugin->lib_name(plugin_lib); plugin->plug_label(plugin_label); - push_queued(new AddNodeEvent(_responder, now(), path, plugin, polyphonic)); + push_queued(new AddNodeEvent(_engine, _responder, now(), path, plugin, polyphonic)); } void QueuedEngineInterface::rename(const string& old_path, const string& new_name) { - push_queued(new RenameEvent(_responder, now(), old_path, new_name)); + push_queued(new RenameEvent(_engine, _responder, now(), old_path, new_name)); } void QueuedEngineInterface::destroy(const string& path) { - push_queued(new DestroyEvent(_responder, now(), this, path)); + push_queued(new DestroyEvent(_engine, _responder, now(), this, path)); } void QueuedEngineInterface::clear_patch(const string& patch_path) { - push_queued(new ClearPatchEvent(_responder, now(), patch_path)); + push_queued(new ClearPatchEvent(_engine, _responder, now(), patch_path)); } void QueuedEngineInterface::enable_patch(const string& patch_path) { - push_queued(new EnablePatchEvent(_responder, now(), patch_path)); + push_queued(new EnablePatchEvent(_engine, _responder, now(), patch_path)); } void QueuedEngineInterface::disable_patch(const string& patch_path) { - push_queued(new DisablePatchEvent(_responder, now(), patch_path)); + push_queued(new DisablePatchEvent(_engine, _responder, now(), patch_path)); } @@ -199,7 +200,7 @@ void QueuedEngineInterface::connect(const string& src_port_path, const string& dst_port_path) { - push_queued(new ConnectionEvent(_responder, now(), src_port_path, dst_port_path)); + push_queued(new ConnectionEvent(_engine, _responder, now(), src_port_path, dst_port_path)); } @@ -208,14 +209,14 @@ void QueuedEngineInterface::disconnect(const string& src_port_path, const string& dst_port_path) { - push_queued(new DisconnectionEvent(_responder, now(), src_port_path, dst_port_path)); + push_queued(new DisconnectionEvent(_engine, _responder, now(), src_port_path, dst_port_path)); } void QueuedEngineInterface::disconnect_all(const string& node_path) { - push_queued(new DisconnectNodeEvent(_responder, now(), node_path)); + push_queued(new DisconnectNodeEvent(_engine, _responder, now(), node_path)); } @@ -223,7 +224,7 @@ void QueuedEngineInterface::set_port_value(const string& port_path, float value) { - push_stamped(new SetPortValueEvent(_responder, now(), port_path, value)); + push_stamped(new SetPortValueEvent(_engine, _responder, now(), port_path, value)); } @@ -232,7 +233,7 @@ QueuedEngineInterface::set_port_value(const string& port_path, uint32_t voice, float value) { - push_stamped(new SetPortValueEvent(_responder, now(), voice, port_path, value)); + push_stamped(new SetPortValueEvent(_engine, _responder, now(), voice, port_path, value)); } @@ -240,7 +241,7 @@ void QueuedEngineInterface::set_port_value_queued(const string& port_path, float value) { - push_queued(new SetPortValueQueuedEvent(_responder, now(), port_path, value)); + push_queued(new SetPortValueQueuedEvent(_engine, _responder, now(), port_path, value)); } @@ -249,14 +250,14 @@ QueuedEngineInterface::set_program(const string& node_path, uint32_t bank, uint32_t program) { - push_queued(new DSSIProgramEvent(_responder, now(), node_path, bank, program)); + push_queued(new DSSIProgramEvent(_engine, _responder, now(), node_path, bank, program)); } void QueuedEngineInterface::midi_learn(const string& node_path) { - push_queued(new MidiLearnEvent(_responder, now(), node_path)); + push_queued(new MidiLearnEvent(_engine, _responder, now(), node_path)); } @@ -265,7 +266,7 @@ QueuedEngineInterface::set_metadata(const string& path, const string& predicate, const string& value) { - push_queued(new SetMetadataEvent(_responder, now(), path, predicate, value)); + push_queued(new SetMetadataEvent(_engine, _responder, now(), path, predicate, value)); } @@ -274,28 +275,28 @@ QueuedEngineInterface::set_metadata(const string& path, void QueuedEngineInterface::ping() { - push_queued(new PingQueuedEvent(_responder, now())); + push_queued(new PingQueuedEvent(_engine, _responder, now())); } void QueuedEngineInterface::request_port_value(const string& port_path) { - push_queued(new RequestPortValueEvent(_responder, now(), port_path)); + push_queued(new RequestPortValueEvent(_engine, _responder, now(), port_path)); } void QueuedEngineInterface::request_plugins() { - push_queued(new RequestPluginsEvent(_responder, now())); + push_queued(new RequestPluginsEvent(_engine, _responder, now())); } void QueuedEngineInterface::request_all_objects() { - push_queued(new RequestAllObjectsEvent(_responder, now())); + push_queued(new RequestAllObjectsEvent(_engine, _responder, now())); } diff --git a/src/libs/engine/QueuedEngineInterface.h b/src/libs/engine/QueuedEngineInterface.h index cd5ef1b7..c5904a2e 100644 --- a/src/libs/engine/QueuedEngineInterface.h +++ b/src/libs/engine/QueuedEngineInterface.h @@ -33,6 +33,7 @@ namespace Ingen { using Shared::ClientKey; using Shared::ClientInterface; using Shared::EngineInterface; +class Engine; /** A queued (preprocessed) event source / interface. @@ -58,7 +59,7 @@ using Shared::EngineInterface; class QueuedEngineInterface : public QueuedEventSource, public EngineInterface { public: - QueuedEngineInterface(size_t queued_size, size_t stamped_size); + QueuedEngineInterface(Engine& engine, size_t queued_size, size_t stamped_size); virtual ~QueuedEngineInterface() {} virtual void set_responder(CountedPtr<Responder> responder); @@ -152,6 +153,8 @@ protected: private: SampleCount now() const; + + Engine& _engine; }; diff --git a/src/libs/engine/QueuedEvent.h b/src/libs/engine/QueuedEvent.h index d88a247c..388630e7 100644 --- a/src/libs/engine/QueuedEvent.h +++ b/src/libs/engine/QueuedEvent.h @@ -49,9 +49,16 @@ public: _pre_processed = true; } - virtual void execute(SampleCount offset) { + virtual void execute(SampleCount nframes, FrameTime start, FrameTime end) { assert(_pre_processed); - Event::execute(offset); + assert(_time <= end); + + // Didn't prepare in time. QueuedEvents aren't (necessarily) sample accurate + // so just run at the beginning of this cycle + if (_time <= start) + _time = start; + + Event::execute(nframes, start, end); } virtual void post_process() {} @@ -66,17 +73,18 @@ protected: QueuedEvent(const QueuedEvent& copy); QueuedEvent& operator=(const QueuedEvent&); - QueuedEvent(CountedPtr<Responder> responder, - SampleCount timestamp, + QueuedEvent(Engine& engine, + CountedPtr<Responder> responder, + FrameTime time, bool blocking = false, QueuedEventSource* source = NULL) - : Event(responder, timestamp) + : Event(engine, responder, time) , _pre_processed(false), _blocking(blocking), _source(source) {} // NULL event base (for internal events only!) - QueuedEvent() - : Event(NULL, 0) + QueuedEvent(Engine& engine) + : Event(engine, NULL, 0) , _pre_processed(false), _blocking(false), _source(NULL) {} diff --git a/src/libs/engine/QueuedEventSource.cpp b/src/libs/engine/QueuedEventSource.cpp index 33ac130a..0ef11ac1 100644 --- a/src/libs/engine/QueuedEventSource.cpp +++ b/src/libs/engine/QueuedEventSource.cpp @@ -87,7 +87,7 @@ QueuedEventSource::pop_earliest_queued_before(const SampleCount time) QueuedEvent* const front_event = _events[_front]; // Pop - if (front_event && front_event->is_prepared() && front_event->time_stamp() < time) { + if (front_event && front_event->is_prepared() && front_event->time() < time) { _events[_front] = NULL; _front = (_front + 1) % _size; return front_event; diff --git a/src/libs/engine/QueuedEventSource.h b/src/libs/engine/QueuedEventSource.h index 5dcc9200..abdea293 100644 --- a/src/libs/engine/QueuedEventSource.h +++ b/src/libs/engine/QueuedEventSource.h @@ -94,7 +94,7 @@ private: inline Event* QueuedEventSource::pop_earliest_stamped_before(const SampleCount time) { - if (!_stamped_queue.is_empty() && _stamped_queue.front()->time_stamp() < time) + if (!_stamped_queue.is_empty() && _stamped_queue.front()->time() < time) return _stamped_queue.pop(); return NULL; } diff --git a/src/libs/engine/Responder.h b/src/libs/engine/Responder.h index 14c857bc..162af23f 100644 --- a/src/libs/engine/Responder.h +++ b/src/libs/engine/Responder.h @@ -20,12 +20,12 @@ #include <inttypes.h> #include <string> #include "util/CountedPtr.h" -#include "interface/ClientInterface.h" +#include "interface/ClientKey.h" using std::string; namespace Ingen { -using Shared::ClientInterface; +using Shared::ClientKey; /** Class to handle responding to clients. @@ -36,8 +36,8 @@ using Shared::ClientInterface; * Note that this class only handles sending responses to commands from * clients, (ie OK or an error), <b>not</b> notifications (ie new node, * disconnection) - that's what ClientInterface is for. If a command is - * a request, \ref find_client can find the corresponding ClientInterface - * for this client to send the reply to. + * a request, the ClientKey of the Responder can be used to find the + * ClientInterface which should receive the response. * * ClientInterface and Responder are seperate because responding might not * actually get exposed to the client interface (eg in simulated blocking @@ -49,8 +49,7 @@ public: Responder() {} virtual ~Responder() {} - virtual CountedPtr<Shared::ClientInterface> find_client() - { return CountedPtr<Shared::ClientInterface>(NULL); } + virtual ClientKey client_key() { return ClientKey(); } virtual void respond_ok() {} virtual void respond_error(const string& msg) {} diff --git a/src/libs/engine/TransportNode.cpp b/src/libs/engine/TransportNode.cpp index 49ab20b8..caab50d2 100644 --- a/src/libs/engine/TransportNode.cpp +++ b/src/libs/engine/TransportNode.cpp @@ -14,7 +14,6 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #include "TransportNode.h" #include <jack/transport.h> #include "OutputPort.h" @@ -81,9 +80,9 @@ TransportNode::TransportNode(const string& path, size_t poly, Patch* parent, Sam void -TransportNode::run(size_t nframes) +TransportNode::process(SampleCount nframes, FrameTime start, FrameTime end) { - NodeBase::process(nframes); + NodeBase::process(nframes, start, end); #if 0 // FIXME: this will die horribly with any driver other than jack (in theory) diff --git a/src/libs/engine/TransportNode.h b/src/libs/engine/TransportNode.h index b4547fdc..1f40e844 100644 --- a/src/libs/engine/TransportNode.h +++ b/src/libs/engine/TransportNode.h @@ -39,7 +39,7 @@ class TransportNode : public InternalNode public: TransportNode(const string& path, size_t poly, Patch* parent, SampleRate srate, size_t buffer_size); - void run(size_t nframes); + virtual void process(SampleCount nframes, FrameTime start, FrameTime end); }; diff --git a/src/libs/engine/TypedConnection.cpp b/src/libs/engine/TypedConnection.cpp index daee10d9..a0cd01e6 100644 --- a/src/libs/engine/TypedConnection.cpp +++ b/src/libs/engine/TypedConnection.cpp @@ -63,7 +63,7 @@ template TypedConnection<MidiMessage>::~TypedConnection(); template <typename Sample> void -TypedConnection<Sample>::process(SampleCount nframes) +TypedConnection<Sample>::process(SampleCount nframes, FrameTime start, FrameTime end) { // FIXME: nframes parameter not used assert(m_buffer_size == 1 || m_buffer_size == nframes); @@ -91,13 +91,13 @@ TypedConnection<Sample>::process(SampleCount nframes) m_local_buffer->scale(1.0f/(float)src_port()->poly(), 0, m_buffer_size-1); } } -template void TypedConnection<Sample>::process(SampleCount nframes); +template void TypedConnection<Sample>::process(SampleCount nframes, FrameTime start, FrameTime end); // FIXME: MIDI mixing not implemented template <> void -TypedConnection<MidiMessage>::process(SampleCount nframes) +TypedConnection<MidiMessage>::process(SampleCount nframes, FrameTime start, FrameTime end) { } diff --git a/src/libs/engine/TypedConnection.h b/src/libs/engine/TypedConnection.h index 1289e158..8fb16676 100644 --- a/src/libs/engine/TypedConnection.h +++ b/src/libs/engine/TypedConnection.h @@ -39,7 +39,7 @@ public: TypedConnection(OutputPort<T>* const src_port, InputPort<T>* const dst_port); virtual ~TypedConnection(); - void process(SampleCount nframes); + void process(SampleCount nframes, FrameTime start, FrameTime end); inline OutputPort<T>* src_port() const { return dynamic_cast<OutputPort<T>*>(m_src_port); } inline InputPort<T>* dst_port() const { return dynamic_cast<InputPort<T>*>(m_dst_port); } diff --git a/src/libs/engine/TypedPort.cpp b/src/libs/engine/TypedPort.cpp index 176c658c..484dcaf7 100644 --- a/src/libs/engine/TypedPort.cpp +++ b/src/libs/engine/TypedPort.cpp @@ -102,7 +102,7 @@ template void TypedPort<MidiMessage>::allocate_buffers(); template <typename T> void -TypedPort<T>::process(SampleCount nframes) +TypedPort<T>::process(SampleCount nframes, FrameTime start, FrameTime end) { for (size_t i=0; i < _poly; ++i) m_buffers.at(i)->prepare(nframes); diff --git a/src/libs/engine/TypedPort.h b/src/libs/engine/TypedPort.h index 4958269b..cf4c36a2 100644 --- a/src/libs/engine/TypedPort.h +++ b/src/libs/engine/TypedPort.h @@ -49,7 +49,7 @@ public: Buffer<T>* buffer(size_t voice) const { return m_buffers.at(voice); } - virtual void process(SampleCount nframes); + virtual void process(SampleCount nframes, FrameTime start, FrameTime end); virtual void clear_buffers(); /** Used by drivers to prevent port from changing buffers */ diff --git a/src/libs/engine/events/ActivateEvent.cpp b/src/libs/engine/events/ActivateEvent.cpp index 31a218ad..9d8162ec 100644 --- a/src/libs/engine/events/ActivateEvent.cpp +++ b/src/libs/engine/events/ActivateEvent.cpp @@ -21,8 +21,8 @@ namespace Ingen { -ActivateEvent::ActivateEvent(CountedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(responder, timestamp) +ActivateEvent::ActivateEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp) +: QueuedEvent(engine, responder, timestamp) { } @@ -32,7 +32,7 @@ ActivateEvent::pre_process() { QueuedEvent::pre_process(); - Engine::instance().activate(); + _engine.activate(); } diff --git a/src/libs/engine/events/ActivateEvent.h b/src/libs/engine/events/ActivateEvent.h index de47ddf3..26ee5b84 100644 --- a/src/libs/engine/events/ActivateEvent.h +++ b/src/libs/engine/events/ActivateEvent.h @@ -29,7 +29,7 @@ namespace Ingen { class ActivateEvent : public QueuedEvent { public: - ActivateEvent(CountedPtr<Responder> responder, SampleCount timestamp); + ActivateEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp); void pre_process(); void post_process(); diff --git a/src/libs/engine/events/AddNodeEvent.cpp b/src/libs/engine/events/AddNodeEvent.cpp index a5dc7538..5287c7cd 100644 --- a/src/libs/engine/events/AddNodeEvent.cpp +++ b/src/libs/engine/events/AddNodeEvent.cpp @@ -33,8 +33,8 @@ namespace Ingen { -AddNodeEvent::AddNodeEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& path, Plugin* plugin, bool poly) -: QueuedEvent(responder, timestamp), +AddNodeEvent::AddNodeEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, Plugin* plugin, bool poly) +: QueuedEvent(engine, responder, timestamp), m_path(path), m_plugin(plugin), m_poly(poly), @@ -55,19 +55,19 @@ AddNodeEvent::~AddNodeEvent() void AddNodeEvent::pre_process() { - if (Engine::instance().object_store()->find(m_path) != NULL) { + if (_engine.object_store()->find(m_path) != NULL) { m_node_already_exists = true; QueuedEvent::pre_process(); return; } - m_patch = Engine::instance().object_store()->find_patch(m_path.parent()); + m_patch = _engine.object_store()->find_patch(m_path.parent()); if (m_patch != NULL) { if (m_poly) - m_node = Engine::instance().node_factory()->load_plugin(m_plugin, m_path.name(), m_patch->internal_poly(), m_patch); + m_node = _engine.node_factory()->load_plugin(m_plugin, m_path.name(), m_patch->internal_poly(), m_patch); else - m_node = Engine::instance().node_factory()->load_plugin(m_plugin, m_path.name(), 1, m_patch); + m_node = _engine.node_factory()->load_plugin(m_plugin, m_path.name(), 1, m_patch); if (m_node != NULL) { m_node->activate(); @@ -75,9 +75,9 @@ AddNodeEvent::pre_process() // This can be done here because the audio thread doesn't touch the // node tree - just the process order array m_patch->add_node(new ListNode<Node*>(m_node)); - m_node->add_to_store(); + m_node->add_to_store(_engine.object_store()); - if (m_patch->process()) + if (m_patch->enabled()) m_process_order = m_patch->build_process_order(); } } @@ -86,15 +86,15 @@ AddNodeEvent::pre_process() void -AddNodeEvent::execute(SampleCount offset) +AddNodeEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); if (m_node != NULL) { m_node->add_to_patch(); if (m_patch->process_order() != NULL) - Engine::instance().maid()->push(m_patch->process_order()); + _engine.maid()->push(m_patch->process_order()); m_patch->process_order(m_process_order); } } @@ -117,8 +117,8 @@ AddNodeEvent::post_process() _responder->respond_error(msg); } else { _responder->respond_ok(); - //Engine::instance().client_broadcaster()->send_node_creation_messages(m_node); - Engine::instance().client_broadcaster()->send_node(m_node); + //_engine.client_broadcaster()->send_node_creation_messages(m_node); + _engine.client_broadcaster()->send_node(m_node); } } diff --git a/src/libs/engine/events/AddNodeEvent.h b/src/libs/engine/events/AddNodeEvent.h index c2ec043a..c7616c2b 100644 --- a/src/libs/engine/events/AddNodeEvent.h +++ b/src/libs/engine/events/AddNodeEvent.h @@ -39,11 +39,11 @@ class Plugin; class AddNodeEvent : public QueuedEvent { public: - AddNodeEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& path, Plugin* plugin, bool poly); + AddNodeEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, Plugin* plugin, bool poly); ~AddNodeEvent(); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/AddPortEvent.cpp b/src/libs/engine/events/AddPortEvent.cpp index cf40b45f..7b034f43 100644 --- a/src/libs/engine/events/AddPortEvent.cpp +++ b/src/libs/engine/events/AddPortEvent.cpp @@ -36,8 +36,8 @@ namespace Ingen { -AddPortEvent::AddPortEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output) -: QueuedEvent(responder, timestamp), +AddPortEvent::AddPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output) +: QueuedEvent(engine, responder, timestamp), _path(path), _type(type), _is_output(is_output), @@ -57,21 +57,21 @@ AddPortEvent::AddPortEvent(CountedPtr<Responder> responder, SampleCount timestam void AddPortEvent::pre_process() { - if (Engine::instance().object_store()->find(_path) != NULL) { + if (_engine.object_store()->find(_path) != NULL) { QueuedEvent::pre_process(); return; } // FIXME: this is just a mess :/ - _patch = Engine::instance().object_store()->find_patch(_path.parent()); + _patch = _engine.object_store()->find_patch(_path.parent()); if (_patch != NULL) { assert(_patch->path() == _path.parent()); size_t buffer_size = 1; if (_type == "AUDIO" || _type == "MIDI") - buffer_size = Engine::instance().audio_driver()->buffer_size(); + buffer_size = _engine.audio_driver()->buffer_size(); _patch_port = _patch->create_port(_path.name(), _data_type, buffer_size, _is_output); if (_patch_port) { @@ -86,14 +86,14 @@ AddPortEvent::pre_process() _ports_array = new Array<Port*>(_patch->num_ports() + 1, NULL); _ports_array->at(_patch->num_ports()) = _patch_port; - Engine::instance().object_store()->add(_patch_port); + _engine.object_store()->add(_patch_port); if (!_patch->parent()) { if (_type == "AUDIO") - _driver_port = Engine::instance().audio_driver()->create_port( + _driver_port = _engine.audio_driver()->create_port( dynamic_cast<DuplexPort<Sample>*>(_patch_port)); else if (_type == "MIDI") - _driver_port = Engine::instance().midi_driver()->create_port( + _driver_port = _engine.midi_driver()->create_port( dynamic_cast<DuplexPort<MidiMessage>*>(_patch_port)); } } @@ -103,12 +103,12 @@ AddPortEvent::pre_process() void -AddPortEvent::execute(SampleCount offset) +AddPortEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); if (_patch_port) { - Engine::instance().maid()->push(_patch->external_ports()); + _engine.maid()->push(_patch->external_ports()); //_patch->add_port(_port); _patch->external_ports(_ports_array); } @@ -126,7 +126,7 @@ AddPortEvent::post_process() _responder->respond_error(msg); } else { _responder->respond_ok(); - Engine::instance().client_broadcaster()->send_port(_patch_port); + _engine.client_broadcaster()->send_port(_patch_port); } } diff --git a/src/libs/engine/events/AddPortEvent.h b/src/libs/engine/events/AddPortEvent.h index 9643bd13..070d07df 100644 --- a/src/libs/engine/events/AddPortEvent.h +++ b/src/libs/engine/events/AddPortEvent.h @@ -41,10 +41,10 @@ class DriverPort; class AddPortEvent : public QueuedEvent { public: - AddPortEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output); + AddPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& type, bool is_output); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/AllNotesOffEvent.cpp b/src/libs/engine/events/AllNotesOffEvent.cpp index 349c6cd5..b26f1315 100644 --- a/src/libs/engine/events/AllNotesOffEvent.cpp +++ b/src/libs/engine/events/AllNotesOffEvent.cpp @@ -24,8 +24,8 @@ namespace Ingen { /** Note off with patch explicitly passed - triggered by MIDI. */ -AllNotesOffEvent::AllNotesOffEvent(CountedPtr<Responder> responder, SampleCount timestamp, Patch* patch) -: Event(responder, timestamp), +AllNotesOffEvent::AllNotesOffEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, Patch* patch) +: Event(engine, responder, timestamp), m_patch(patch) { } @@ -33,8 +33,8 @@ AllNotesOffEvent::AllNotesOffEvent(CountedPtr<Responder> responder, SampleCount /** Note off event with lookup - triggered by OSC. */ -AllNotesOffEvent::AllNotesOffEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path) -: Event(responder, timestamp), +AllNotesOffEvent::AllNotesOffEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path) +: Event(engine, responder, timestamp), m_patch(NULL), m_patch_path(patch_path) { @@ -42,10 +42,10 @@ AllNotesOffEvent::AllNotesOffEvent(CountedPtr<Responder> responder, SampleCount void -AllNotesOffEvent::execute(SampleCount offset) +AllNotesOffEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { if (m_patch == NULL && m_patch_path != "") - m_patch = Engine::instance().object_store()->find_patch(m_patch_path); + m_patch = _engine.object_store()->find_patch(m_patch_path); //if (m_patch != NULL) // for (List<MidiInNode*>::iterator j = m_patch->midi_in_nodes().begin(); j != m_patch->midi_in_nodes().end(); ++j) diff --git a/src/libs/engine/events/AllNotesOffEvent.h b/src/libs/engine/events/AllNotesOffEvent.h index 56d52a25..5c8f46f0 100644 --- a/src/libs/engine/events/AllNotesOffEvent.h +++ b/src/libs/engine/events/AllNotesOffEvent.h @@ -33,10 +33,10 @@ class Patch; class AllNotesOffEvent : public Event { public: - AllNotesOffEvent(CountedPtr<Responder> responder, SampleCount timestamp, Patch* patch); - AllNotesOffEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path); + AllNotesOffEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, Patch* patch); + AllNotesOffEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/ClearPatchEvent.cpp b/src/libs/engine/events/ClearPatchEvent.cpp index 3cd8faab..e73fd376 100644 --- a/src/libs/engine/events/ClearPatchEvent.cpp +++ b/src/libs/engine/events/ClearPatchEvent.cpp @@ -30,8 +30,8 @@ namespace Ingen { -ClearPatchEvent::ClearPatchEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path) -: QueuedEvent(responder, true), +ClearPatchEvent::ClearPatchEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path) +: QueuedEvent(engine, responder, true), m_patch_path(patch_path), m_patch(NULL), m_process(false) @@ -42,11 +42,11 @@ ClearPatchEvent::ClearPatchEvent(CountedPtr<Responder> responder, SampleCount ti void ClearPatchEvent::pre_process() { - m_patch = Engine::instance().object_store()->find_patch(m_patch_path); + m_patch = _engine.object_store()->find_patch(m_patch_path); if (m_patch != NULL) { - m_process = m_patch->process(); + m_process = m_patch->enabled(); for (List<Node*>::const_iterator i = m_patch->nodes().begin(); i != m_patch->nodes().end(); ++i) (*i)->remove_from_store(); @@ -57,21 +57,21 @@ ClearPatchEvent::pre_process() void -ClearPatchEvent::execute(SampleCount offset) +ClearPatchEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { if (m_patch != NULL) { - m_patch->process(false); + m_patch->disable(); for (List<Node*>::const_iterator i = m_patch->nodes().begin(); i != m_patch->nodes().end(); ++i) (*i)->remove_from_patch(); if (m_patch->process_order() != NULL) { - Engine::instance().maid()->push(m_patch->process_order()); + _engine.maid()->push(m_patch->process_order()); m_patch->process_order(NULL); } } - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); } @@ -92,7 +92,10 @@ ClearPatchEvent::post_process() m_patch->connections().clear(); // Restore patch's run state - m_patch->process(m_process); + if (m_process) + m_patch->enable(); + else + m_patch->disable(); // Make sure everything's sane assert(m_patch->nodes().size() == 0); @@ -100,7 +103,7 @@ ClearPatchEvent::post_process() // Reply _responder->respond_ok(); - Engine::instance().client_broadcaster()->send_patch_cleared(m_patch_path); + _engine.client_broadcaster()->send_patch_cleared(m_patch_path); } else { _responder->respond_error(string("Patch ") + m_patch_path + " not found"); } diff --git a/src/libs/engine/events/ClearPatchEvent.h b/src/libs/engine/events/ClearPatchEvent.h index bef90477..0eb9b495 100644 --- a/src/libs/engine/events/ClearPatchEvent.h +++ b/src/libs/engine/events/ClearPatchEvent.h @@ -35,10 +35,10 @@ class Patch; class ClearPatchEvent : public QueuedEvent { public: - ClearPatchEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path); + ClearPatchEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/ConnectionEvent.cpp b/src/libs/engine/events/ConnectionEvent.cpp index bf64df0a..b873bccb 100644 --- a/src/libs/engine/events/ConnectionEvent.cpp +++ b/src/libs/engine/events/ConnectionEvent.cpp @@ -36,8 +36,8 @@ namespace Ingen { //// ConnectionEvent //// -ConnectionEvent::ConnectionEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path) -: QueuedEvent(responder, timestamp), +ConnectionEvent::ConnectionEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path) +: QueuedEvent(engine, responder, timestamp), m_src_port_path(src_port_path), m_dst_port_path(dst_port_path), m_patch(NULL), @@ -66,7 +66,7 @@ ConnectionEvent::pre_process() return; } - /*m_patch = Engine::instance().object_store()->find_patch(m_src_port_path.parent().parent()); + /*m_patch = _engine.object_store()->find_patch(m_src_port_path.parent().parent()); if (m_patch == NULL) { m_error = PORT_NOT_FOUND; @@ -74,8 +74,8 @@ ConnectionEvent::pre_process() return; }*/ - m_src_port = Engine::instance().object_store()->find_port(m_src_port_path); - m_dst_port = Engine::instance().object_store()->find_port(m_dst_port_path); + m_src_port = _engine.object_store()->find_port(m_src_port_path); + m_dst_port = _engine.object_store()->find_port(m_dst_port_path); if (m_src_port == NULL || m_dst_port == NULL) { m_error = PORT_NOT_FOUND; @@ -104,10 +104,10 @@ ConnectionEvent::pre_process() // Create the typed event to actually do the work const DataType type = m_src_port->type(); if (type == DataType::FLOAT) { - m_typed_event = new TypedConnectionEvent<Sample>(_responder, _time_stamp, + m_typed_event = new TypedConnectionEvent<Sample>(_engine, _responder, _time, dynamic_cast<OutputPort<Sample>*>(m_src_port), dynamic_cast<InputPort<Sample>*>(m_dst_port)); } else if (type == DataType::MIDI) { - m_typed_event = new TypedConnectionEvent<MidiMessage>(_responder, _time_stamp, + m_typed_event = new TypedConnectionEvent<MidiMessage>(_engine, _responder, _time, dynamic_cast<OutputPort<MidiMessage>*>(m_src_port), dynamic_cast<InputPort<MidiMessage>*>(m_dst_port)); } else { m_error = TYPE_MISMATCH; @@ -122,12 +122,12 @@ ConnectionEvent::pre_process() void -ConnectionEvent::execute(SampleCount offset) +ConnectionEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); if (m_error == NO_ERROR) - m_typed_event->execute(offset); + m_typed_event->execute(nframes, start, end); } @@ -150,8 +150,8 @@ ConnectionEvent::post_process() template <typename T> -TypedConnectionEvent<T>::TypedConnectionEvent(CountedPtr<Responder> responder, SampleCount timestamp, OutputPort<T>* src_port, InputPort<T>* dst_port) -: QueuedEvent(responder, timestamp), +TypedConnectionEvent<T>::TypedConnectionEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, OutputPort<T>* src_port, InputPort<T>* dst_port) +: QueuedEvent(engine, responder, timestamp), m_src_port(src_port), m_dst_port(dst_port), m_patch(NULL), @@ -221,21 +221,21 @@ TypedConnectionEvent<T>::pre_process() src_node->dependants()->push_back(new ListNode<Node*>(dst_node)); } - if (m_patch->process()) + if (m_patch->enabled()) m_process_order = m_patch->build_process_order(); } template <typename T> void -TypedConnectionEvent<T>::execute(SampleCount offset) +TypedConnectionEvent<T>::execute(SampleCount nframes, FrameTime start, FrameTime end) { if (m_succeeded) { // These must be inserted here, since they're actually used by the audio thread m_dst_port->add_connection(m_port_listnode); m_patch->add_connection(m_patch_listnode); if (m_patch->process_order() != NULL) - Engine::instance().maid()->push(m_patch->process_order()); + _engine.maid()->push(m_patch->process_order()); m_patch->process_order(m_process_order); } } @@ -250,7 +250,7 @@ TypedConnectionEvent<T>::post_process() _responder->respond_ok(); - Engine::instance().client_broadcaster()->send_connection(m_connection); + _engine.client_broadcaster()->send_connection(m_connection); } else { _responder->respond_error("Unable to make connection."); } diff --git a/src/libs/engine/events/ConnectionEvent.h b/src/libs/engine/events/ConnectionEvent.h index d5a580a5..2f65eb3a 100644 --- a/src/libs/engine/events/ConnectionEvent.h +++ b/src/libs/engine/events/ConnectionEvent.h @@ -46,11 +46,11 @@ template <typename T> class TypedConnectionEvent; // helper, defined below class ConnectionEvent : public QueuedEvent { public: - ConnectionEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path); + ConnectionEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path); ~ConnectionEvent(); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: @@ -80,10 +80,10 @@ template <typename T> class TypedConnectionEvent : public QueuedEvent { public: - TypedConnectionEvent(CountedPtr<Responder> responder, SampleCount timestamp, OutputPort<T>* src_port, InputPort<T>* dst_port); + TypedConnectionEvent(Engine& engine, CountedPtr<Responder> responder, FrameTime time, OutputPort<T>* src_port, InputPort<T>* dst_port); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/CreatePatchEvent.cpp b/src/libs/engine/events/CreatePatchEvent.cpp index 65e2106d..d66a3ff9 100644 --- a/src/libs/engine/events/CreatePatchEvent.cpp +++ b/src/libs/engine/events/CreatePatchEvent.cpp @@ -30,8 +30,8 @@ namespace Ingen { -CreatePatchEvent::CreatePatchEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& path, int poly) -: QueuedEvent(responder, timestamp), +CreatePatchEvent::CreatePatchEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, int poly) +: QueuedEvent(engine, responder, timestamp), m_path(path), m_patch(NULL), m_parent(NULL), @@ -45,7 +45,7 @@ CreatePatchEvent::CreatePatchEvent(CountedPtr<Responder> responder, SampleCount void CreatePatchEvent::pre_process() { - if (Engine::instance().object_store()->find(m_path) != NULL) { + if (_engine.object_store()->find(m_path) != NULL) { m_error = OBJECT_EXISTS; QueuedEvent::pre_process(); return; @@ -58,7 +58,7 @@ CreatePatchEvent::pre_process() } if (m_path != "/") { - m_parent = Engine::instance().object_store()->find_patch(m_path.parent()); + m_parent = _engine.object_store()->find_patch(m_path.parent()); if (m_parent == NULL) { m_error = PARENT_NOT_FOUND; QueuedEvent::pre_process(); @@ -70,34 +70,34 @@ CreatePatchEvent::pre_process() if (m_parent != NULL && m_poly > 1 && m_poly == static_cast<int>(m_parent->internal_poly())) poly = m_poly; - m_patch = new Patch(m_path.name(), poly, m_parent, Engine::instance().audio_driver()->sample_rate(), Engine::instance().audio_driver()->buffer_size(), m_poly); + m_patch = new Patch(m_path.name(), poly, m_parent, _engine.audio_driver()->sample_rate(), _engine.audio_driver()->buffer_size(), m_poly); if (m_parent != NULL) { m_parent->add_node(new ListNode<Node*>(m_patch)); - if (m_parent->process()) + if (m_parent->enabled()) m_process_order = m_parent->build_process_order(); } m_patch->activate(); // Insert into ObjectStore - m_patch->add_to_store(); + m_patch->add_to_store(_engine.object_store()); QueuedEvent::pre_process(); } void -CreatePatchEvent::execute(SampleCount offset) +CreatePatchEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); if (m_patch != NULL) { if (m_parent == NULL) { assert(m_path == "/"); assert(m_patch->parent_patch() == NULL); - Engine::instance().audio_driver()->set_root_patch(m_patch); + _engine.audio_driver()->set_root_patch(m_patch); } else { assert(m_parent != NULL); assert(m_path != "/"); @@ -105,7 +105,7 @@ CreatePatchEvent::execute(SampleCount offset) m_patch->add_to_patch(); if (m_parent->process_order() != NULL) - Engine::instance().maid()->push(m_parent->process_order()); + _engine.maid()->push(m_parent->process_order()); m_parent->process_order(m_process_order); } } @@ -121,10 +121,10 @@ CreatePatchEvent::post_process() _responder->respond_ok(); // Don't want to send nodes that have been added since prepare() - //Engine::instance().client_broadcaster()->send_node_creation_messages(m_patch); + //_engine.client_broadcaster()->send_node_creation_messages(m_patch); // Patches are always empty on creation, so this is fine - Engine::instance().client_broadcaster()->send_patch(m_patch); + _engine.client_broadcaster()->send_patch(m_patch); } else if (m_error == OBJECT_EXISTS) { string msg = "Unable to create patch: "; diff --git a/src/libs/engine/events/CreatePatchEvent.h b/src/libs/engine/events/CreatePatchEvent.h index 581bb381..63a33271 100644 --- a/src/libs/engine/events/CreatePatchEvent.h +++ b/src/libs/engine/events/CreatePatchEvent.h @@ -39,10 +39,10 @@ class Plugin; class CreatePatchEvent : public QueuedEvent { public: - CreatePatchEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& path, int poly); + CreatePatchEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, int poly); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/DSSIConfigureEvent.cpp b/src/libs/engine/events/DSSIConfigureEvent.cpp index 59a7401c..de79a083 100644 --- a/src/libs/engine/events/DSSIConfigureEvent.cpp +++ b/src/libs/engine/events/DSSIConfigureEvent.cpp @@ -24,8 +24,8 @@ namespace Ingen { -DSSIConfigureEvent::DSSIConfigureEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, const string& key, const string& val) -: QueuedEvent(responder, timestamp), +DSSIConfigureEvent::DSSIConfigureEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, const string& key, const string& val) +: QueuedEvent(engine, responder, timestamp), m_node_path(node_path), m_key(key), m_val(val), @@ -37,7 +37,7 @@ DSSIConfigureEvent::DSSIConfigureEvent(CountedPtr<Responder> responder, SampleCo void DSSIConfigureEvent::pre_process() { - Node* node = Engine::instance().object_store()->find_node(m_node_path); + Node* node = _engine.object_store()->find_node(m_node_path); if (node != NULL && node->plugin()->type() == Plugin::DSSI) { m_node = (DSSINode*)node; @@ -49,7 +49,7 @@ DSSIConfigureEvent::pre_process() void -DSSIConfigureEvent::execute(SampleCount offset) +DSSIConfigureEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { // Nothing. } @@ -63,7 +63,7 @@ DSSIConfigureEvent::post_process() } else { string key = "dssi-configure--"; key += m_key; - Engine::instance().client_broadcaster()->send_metadata_update(m_node_path, key, m_val); + _engine.client_broadcaster()->send_metadata_update(m_node_path, key, m_val); } } diff --git a/src/libs/engine/events/DSSIConfigureEvent.h b/src/libs/engine/events/DSSIConfigureEvent.h index 80769929..bef3fbb7 100644 --- a/src/libs/engine/events/DSSIConfigureEvent.h +++ b/src/libs/engine/events/DSSIConfigureEvent.h @@ -30,10 +30,10 @@ namespace Ingen { class DSSIConfigureEvent : public QueuedEvent { public: - DSSIConfigureEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, const string& key, const string& val); + DSSIConfigureEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, const string& key, const string& val); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/DSSIControlEvent.cpp b/src/libs/engine/events/DSSIControlEvent.cpp index 5ba8a87e..9ae4274b 100644 --- a/src/libs/engine/events/DSSIControlEvent.cpp +++ b/src/libs/engine/events/DSSIControlEvent.cpp @@ -23,8 +23,8 @@ namespace Ingen { -DSSIControlEvent::DSSIControlEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, int port_num, Sample val) -: QueuedEvent(responder, timestamp), +DSSIControlEvent::DSSIControlEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, int port_num, Sample val) +: QueuedEvent(engine, responder, timestamp), m_node_path(node_path), m_port_num(port_num), m_val(val), @@ -36,7 +36,7 @@ DSSIControlEvent::DSSIControlEvent(CountedPtr<Responder> responder, SampleCount void DSSIControlEvent::pre_process() { - Node* node = Engine::instance().object_store()->find_node(m_node_path); + Node* node = _engine.object_store()->find_node(m_node_path); if (node->plugin()->type() != Plugin::DSSI) m_node = NULL; @@ -48,7 +48,7 @@ DSSIControlEvent::pre_process() void -DSSIControlEvent::execute(SampleCount offset) +DSSIControlEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { if (m_node != NULL) m_node->set_control(m_port_num, m_val); diff --git a/src/libs/engine/events/DSSIControlEvent.h b/src/libs/engine/events/DSSIControlEvent.h index e7c8605d..9eeeb136 100644 --- a/src/libs/engine/events/DSSIControlEvent.h +++ b/src/libs/engine/events/DSSIControlEvent.h @@ -32,10 +32,10 @@ namespace Ingen { class DSSIControlEvent : public QueuedEvent { public: - DSSIControlEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, int port_num, Sample val); + DSSIControlEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, int port_num, Sample val); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/DSSIProgramEvent.cpp b/src/libs/engine/events/DSSIProgramEvent.cpp index 3d62e5b8..4545268a 100644 --- a/src/libs/engine/events/DSSIProgramEvent.cpp +++ b/src/libs/engine/events/DSSIProgramEvent.cpp @@ -28,8 +28,8 @@ using std::cout; using std::cerr; using std::endl; namespace Ingen { -DSSIProgramEvent::DSSIProgramEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, int bank, int program) -: QueuedEvent(responder, timestamp), +DSSIProgramEvent::DSSIProgramEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, int bank, int program) +: QueuedEvent(engine, responder, timestamp), m_node_path(node_path), m_bank(bank), m_program(program), @@ -41,7 +41,7 @@ DSSIProgramEvent::DSSIProgramEvent(CountedPtr<Responder> responder, SampleCount void DSSIProgramEvent::pre_process() { - Node* node = Engine::instance().object_store()->find_node(m_node_path); + Node* node = _engine.object_store()->find_node(m_node_path); if (node != NULL && node->plugin()->type() == Plugin::DSSI) m_node = (DSSINode*)node; @@ -51,7 +51,7 @@ DSSIProgramEvent::pre_process() void -DSSIProgramEvent::execute(SampleCount offset) +DSSIProgramEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { if (m_node != NULL) m_node->program(m_bank, m_program); @@ -67,7 +67,7 @@ DSSIProgramEvent::post_process() // sends program as metadata in the form bank/program char* temp_buf = new char[16]; snprintf(temp_buf, 16, "%d/%d", m_bank, m_program); - Engine::instance().client_broadcaster()->send_metadata_update(m_node_path, "dssi-program", temp_buf); + _engine.client_broadcaster()->send_metadata_update(m_node_path, "dssi-program", temp_buf); } } diff --git a/src/libs/engine/events/DSSIProgramEvent.h b/src/libs/engine/events/DSSIProgramEvent.h index 864110f4..51967cf0 100644 --- a/src/libs/engine/events/DSSIProgramEvent.h +++ b/src/libs/engine/events/DSSIProgramEvent.h @@ -30,10 +30,10 @@ namespace Ingen { class DSSIProgramEvent : public QueuedEvent { public: - DSSIProgramEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, int bank, int program); + DSSIProgramEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, int bank, int program); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/DSSIUpdateEvent.cpp b/src/libs/engine/events/DSSIUpdateEvent.cpp index 48590917..d2953a9b 100644 --- a/src/libs/engine/events/DSSIUpdateEvent.cpp +++ b/src/libs/engine/events/DSSIUpdateEvent.cpp @@ -27,8 +27,8 @@ using std::cerr; using std::endl; namespace Ingen { -DSSIUpdateEvent::DSSIUpdateEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& url) -: QueuedEvent(responder, timestamp), +DSSIUpdateEvent::DSSIUpdateEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& url) +: QueuedEvent(engine, responder, timestamp), m_path(path), m_url(url), m_node(NULL) @@ -39,7 +39,7 @@ DSSIUpdateEvent::DSSIUpdateEvent(CountedPtr<Responder> responder, SampleCount ti void DSSIUpdateEvent::pre_process() { - Node* node = Engine::instance().object_store()->find_node(m_path); + Node* node = _engine.object_store()->find_node(m_path); if (node == NULL || node->plugin()->type() != Plugin::DSSI) { m_node = NULL; @@ -54,13 +54,13 @@ DSSIUpdateEvent::pre_process() void -DSSIUpdateEvent::execute(SampleCount offset) +DSSIUpdateEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { if (m_node != NULL) { m_node->set_ui_url(m_url); } - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); } diff --git a/src/libs/engine/events/DSSIUpdateEvent.h b/src/libs/engine/events/DSSIUpdateEvent.h index bddbc21d..91163efe 100644 --- a/src/libs/engine/events/DSSIUpdateEvent.h +++ b/src/libs/engine/events/DSSIUpdateEvent.h @@ -36,10 +36,10 @@ class DSSINode; class DSSIUpdateEvent : public QueuedEvent { public: - DSSIUpdateEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& url); + DSSIUpdateEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& url); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/DeactivateEvent.cpp b/src/libs/engine/events/DeactivateEvent.cpp index e1c0541e..ff1740dc 100644 --- a/src/libs/engine/events/DeactivateEvent.cpp +++ b/src/libs/engine/events/DeactivateEvent.cpp @@ -21,8 +21,8 @@ namespace Ingen { -DeactivateEvent::DeactivateEvent(CountedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(responder, timestamp) +DeactivateEvent::DeactivateEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp) +: QueuedEvent(engine, responder, timestamp) { } @@ -35,9 +35,9 @@ DeactivateEvent::pre_process() void -DeactivateEvent::execute(SampleCount offset) +DeactivateEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); } @@ -45,7 +45,7 @@ void DeactivateEvent::post_process() { _responder->respond_ok(); - Engine::instance().deactivate(); + _engine.deactivate(); } diff --git a/src/libs/engine/events/DeactivateEvent.h b/src/libs/engine/events/DeactivateEvent.h index 0fd79d32..ddeb75f5 100644 --- a/src/libs/engine/events/DeactivateEvent.h +++ b/src/libs/engine/events/DeactivateEvent.h @@ -29,10 +29,10 @@ namespace Ingen { class DeactivateEvent : public QueuedEvent { public: - DeactivateEvent(CountedPtr<Responder> responder, SampleCount timestamp); + DeactivateEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); }; diff --git a/src/libs/engine/events/DestroyEvent.cpp b/src/libs/engine/events/DestroyEvent.cpp index d55a2935..dd172e7f 100644 --- a/src/libs/engine/events/DestroyEvent.cpp +++ b/src/libs/engine/events/DestroyEvent.cpp @@ -34,8 +34,8 @@ namespace Ingen { -DestroyEvent::DestroyEvent(CountedPtr<Responder> responder, SampleCount timestamp, QueuedEventSource* source, const string& path, bool lock_mutex) -: QueuedEvent(responder, true, source), +DestroyEvent::DestroyEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, QueuedEventSource* source, const string& path, bool lock_mutex) +: QueuedEvent(engine, responder, true, source), m_path(path), m_node(NULL), m_patch_listnode(NULL), @@ -47,8 +47,8 @@ DestroyEvent::DestroyEvent(CountedPtr<Responder> responder, SampleCount timestam } -DestroyEvent::DestroyEvent(CountedPtr<Responder> responder, SampleCount timestamp, Node* node, bool lock_mutex) -: QueuedEvent(responder, true), +DestroyEvent::DestroyEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, Node* node, bool lock_mutex) +: QueuedEvent(engine, responder, true), m_path(node->path()), m_node(node), m_patch_listnode(NULL), @@ -71,7 +71,7 @@ void DestroyEvent::pre_process() { if (m_node == NULL) - m_node = Engine::instance().object_store()->find_node(m_path); + m_node = _engine.object_store()->find_node(m_path); if (m_node != NULL && m_path != "/") { assert(m_node->parent_patch() != NULL); @@ -82,7 +82,7 @@ DestroyEvent::pre_process() m_node->remove_from_store(); if (m_node->providers()->size() != 0 || m_node->dependants()->size() != 0) { - m_disconnect_event = new DisconnectNodeEvent(m_node); + m_disconnect_event = new DisconnectNodeEvent(_engine, m_node); m_disconnect_event->pre_process(); } @@ -90,11 +90,11 @@ DestroyEvent::pre_process() cerr << "FIXME: Destroy bridge\n"; /*Port* parent_port = m_patch_listnode->elem()->as_port(); if (parent_port != NULL) { // Bridge node - m_parent_disconnect_event = new DisconnectPortEvent(parent_port); + m_parent_disconnect_event = new DisconnectPortEvent(Engine& engine, parent_port); m_parent_disconnect_event->pre_process(); }*/ - if (m_node->parent_patch()->process()) { + if (m_node->parent_patch()->enabled()) { m_process_order = m_node->parent_patch()->build_process_order(); // Remove node to be removed from the process order so it isn't executed by // Patch::run and can safely be destroyed @@ -116,20 +116,20 @@ DestroyEvent::pre_process() void -DestroyEvent::execute(SampleCount offset) +DestroyEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); if (m_patch_listnode != NULL) { m_node->remove_from_patch(); if (m_disconnect_event != NULL) - m_disconnect_event->execute(offset); + m_disconnect_event->execute(nframes, start, end); if (m_parent_disconnect_event != NULL) - m_parent_disconnect_event->execute(offset); + m_parent_disconnect_event->execute(nframes, start, end); if (m_node->parent_patch()->process_order() != NULL) - Engine::instance().maid()->push(m_node->parent_patch()->process_order()); + _engine.maid()->push(m_node->parent_patch()->process_order()); m_node->parent_patch()->process_order(m_process_order); } } @@ -153,9 +153,9 @@ DestroyEvent::post_process() m_disconnect_event->post_process(); if (m_parent_disconnect_event != NULL) m_parent_disconnect_event->post_process(); - Engine::instance().client_broadcaster()->send_destroyed(m_path); - Engine::instance().maid()->push(m_patch_listnode); - Engine::instance().maid()->push(m_node); + _engine.client_broadcaster()->send_destroyed(m_path); + _engine.maid()->push(m_patch_listnode); + _engine.maid()->push(m_node); } else { _responder->respond_error("Unable to destroy object"); } diff --git a/src/libs/engine/events/DestroyEvent.h b/src/libs/engine/events/DestroyEvent.h index de4686c1..6eda8006 100644 --- a/src/libs/engine/events/DestroyEvent.h +++ b/src/libs/engine/events/DestroyEvent.h @@ -44,12 +44,12 @@ class DisconnectPortEvent; class DestroyEvent : public QueuedEvent { public: - DestroyEvent(CountedPtr<Responder> responder, SampleCount timestamp, QueuedEventSource* source, const string& path, bool lock_mutex = true); - DestroyEvent(CountedPtr<Responder> responder, SampleCount timestamp, Node* node, bool lock_mutex = true); + DestroyEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, QueuedEventSource* source, const string& path, bool lock_mutex = true); + DestroyEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, Node* node, bool lock_mutex = true); ~DestroyEvent(); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/DisablePatchEvent.cpp b/src/libs/engine/events/DisablePatchEvent.cpp index 45b19f54..299e4fdc 100644 --- a/src/libs/engine/events/DisablePatchEvent.cpp +++ b/src/libs/engine/events/DisablePatchEvent.cpp @@ -26,8 +26,8 @@ namespace Ingen { -DisablePatchEvent::DisablePatchEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path) -: QueuedEvent(responder, timestamp), +DisablePatchEvent::DisablePatchEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path) +: QueuedEvent(engine, responder, timestamp), m_patch_path(patch_path), m_patch(NULL) { @@ -37,19 +37,19 @@ DisablePatchEvent::DisablePatchEvent(CountedPtr<Responder> responder, SampleCoun void DisablePatchEvent::pre_process() { - m_patch = Engine::instance().object_store()->find_patch(m_patch_path); + m_patch = _engine.object_store()->find_patch(m_patch_path); QueuedEvent::pre_process(); } void -DisablePatchEvent::execute(SampleCount offset) +DisablePatchEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { if (m_patch != NULL) - m_patch->process(false); + m_patch->disable(); - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); } @@ -58,7 +58,7 @@ DisablePatchEvent::post_process() { if (m_patch != NULL) { _responder->respond_ok(); - Engine::instance().client_broadcaster()->send_patch_disable(m_patch_path); + _engine.client_broadcaster()->send_patch_disable(m_patch_path); } else { _responder->respond_error(string("Patch ") + m_patch_path + " not found"); } diff --git a/src/libs/engine/events/DisablePatchEvent.h b/src/libs/engine/events/DisablePatchEvent.h index 10721825..09347b08 100644 --- a/src/libs/engine/events/DisablePatchEvent.h +++ b/src/libs/engine/events/DisablePatchEvent.h @@ -34,10 +34,10 @@ class Patch; class DisablePatchEvent : public QueuedEvent { public: - DisablePatchEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path); + DisablePatchEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/DisconnectNodeEvent.cpp b/src/libs/engine/events/DisconnectNodeEvent.cpp index 7955f602..c1a965ad 100644 --- a/src/libs/engine/events/DisconnectNodeEvent.cpp +++ b/src/libs/engine/events/DisconnectNodeEvent.cpp @@ -38,8 +38,8 @@ using std::cerr; using std::endl; namespace Ingen { -DisconnectNodeEvent::DisconnectNodeEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path) -: QueuedEvent(responder, timestamp), +DisconnectNodeEvent::DisconnectNodeEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path) +: QueuedEvent(engine, responder, timestamp), m_node_path(node_path), m_patch(NULL), m_node(NULL), @@ -51,8 +51,8 @@ DisconnectNodeEvent::DisconnectNodeEvent(CountedPtr<Responder> responder, Sample /** Internal version, disconnects parent port as well (in the case of InputNode, etc). */ -DisconnectNodeEvent::DisconnectNodeEvent(Node* node) -: QueuedEvent(), +DisconnectNodeEvent::DisconnectNodeEvent(Engine& engine, Node* node) +: QueuedEvent(engine), m_node_path(""), m_patch(node->parent_patch()), m_node(node), @@ -77,7 +77,7 @@ DisconnectNodeEvent::pre_process() // cerr << "Preparing disconnection event...\n"; if (m_lookup) { - m_patch = Engine::instance().object_store()->find_patch(m_node_path.parent()); + m_patch = _engine.object_store()->find_patch(m_node_path.parent()); if (m_patch == NULL) { m_succeeded = false; @@ -85,7 +85,7 @@ DisconnectNodeEvent::pre_process() return; } - m_node = Engine::instance().object_store()->find_node(m_node_path); + m_node = _engine.object_store()->find_node(m_node_path); if (m_node == NULL) { m_succeeded = false; @@ -98,7 +98,7 @@ DisconnectNodeEvent::pre_process() for (ConnectionListIterator i = m_patch->connections().begin(); i != m_patch->connections().end(); ++i) { c = (*i); if ((c->src_port()->parent_node() == m_node || c->dst_port()->parent_node() == m_node) && !c->pending_disconnection()) { - DisconnectionEvent* ev = new DisconnectionEvent(CountedPtr<Responder>(new Responder()), _time_stamp, + DisconnectionEvent* ev = new DisconnectionEvent(_engine, CountedPtr<Responder>(new Responder()), _time, c->src_port(), c->dst_port()); ev->pre_process(); m_disconnection_events.push_back(new ListNode<DisconnectionEvent*>(ev)); @@ -112,14 +112,14 @@ DisconnectNodeEvent::pre_process() void -DisconnectNodeEvent::execute(SampleCount offset) +DisconnectNodeEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { if (m_succeeded) { for (List<DisconnectionEvent*>::iterator i = m_disconnection_events.begin(); i != m_disconnection_events.end(); ++i) - (*i)->execute(offset); + (*i)->execute(nframes, start, end); } - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); } diff --git a/src/libs/engine/events/DisconnectNodeEvent.h b/src/libs/engine/events/DisconnectNodeEvent.h index d45fff39..90aeabed 100644 --- a/src/libs/engine/events/DisconnectNodeEvent.h +++ b/src/libs/engine/events/DisconnectNodeEvent.h @@ -42,12 +42,12 @@ template <typename T> class OutputPort; class DisconnectNodeEvent : public QueuedEvent { public: - DisconnectNodeEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path); - DisconnectNodeEvent(Node* node); + DisconnectNodeEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path); + DisconnectNodeEvent(Engine& engine, Node* node); ~DisconnectNodeEvent(); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/DisconnectPortEvent.cpp b/src/libs/engine/events/DisconnectPortEvent.cpp index 2126dffd..41ceff8b 100644 --- a/src/libs/engine/events/DisconnectPortEvent.cpp +++ b/src/libs/engine/events/DisconnectPortEvent.cpp @@ -38,8 +38,8 @@ using std::cerr; using std::endl; namespace Ingen { -DisconnectPortEvent::DisconnectPortEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path) -: QueuedEvent(responder, timestamp), +DisconnectPortEvent::DisconnectPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path) +: QueuedEvent(engine, responder, timestamp), m_port_path(port_path), m_patch(NULL), m_port(NULL), @@ -50,8 +50,8 @@ DisconnectPortEvent::DisconnectPortEvent(CountedPtr<Responder> responder, Sample } -DisconnectPortEvent::DisconnectPortEvent(Port* port) -: QueuedEvent(), +DisconnectPortEvent::DisconnectPortEvent(Engine& engine, Port* port) +: QueuedEvent(engine), m_port_path(""), m_patch((port->parent_node() == NULL) ? NULL : port->parent_node()->parent_patch()), m_port(port), @@ -59,7 +59,7 @@ DisconnectPortEvent::DisconnectPortEvent(Port* port) m_succeeded(true), m_lookup(false) { - //cerr << "DisconnectPortEvent()\n"; + //cerr << "DisconnectPortEvent(Engine& engine, )\n"; } @@ -76,7 +76,7 @@ DisconnectPortEvent::pre_process() // cerr << "Preparing disconnection event...\n"; if (m_lookup) { - m_patch = Engine::instance().object_store()->find_patch(m_port_path.parent().parent()); + m_patch = _engine.object_store()->find_patch(m_port_path.parent().parent()); if (m_patch == NULL) { m_succeeded = false; @@ -84,7 +84,7 @@ DisconnectPortEvent::pre_process() return; } - m_port = Engine::instance().object_store()->find_port(m_port_path); + m_port = _engine.object_store()->find_port(m_port_path); if (m_port == NULL) { m_succeeded = false; @@ -103,7 +103,7 @@ DisconnectPortEvent::pre_process() for (List<Connection*>::const_iterator i = m_patch->connections().begin(); i != m_patch->connections().end(); ++i) { c = (*i); if ((c->src_port() == m_port || c->dst_port() == m_port) && !c->pending_disconnection()) { - DisconnectionEvent* ev = new DisconnectionEvent(CountedPtr<Responder>(new Responder()), _time_stamp, + DisconnectionEvent* ev = new DisconnectionEvent(_engine, CountedPtr<Responder>(new Responder()), _time, c->src_port(), c->dst_port()); ev->pre_process(); m_disconnection_events.push_back(new ListNode<DisconnectionEvent*>(ev)); @@ -117,14 +117,14 @@ DisconnectPortEvent::pre_process() void -DisconnectPortEvent::execute(SampleCount offset) +DisconnectPortEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { if (m_succeeded) { for (List<DisconnectionEvent*>::iterator i = m_disconnection_events.begin(); i != m_disconnection_events.end(); ++i) - (*i)->execute(offset); + (*i)->execute(nframes, start, end); } - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); } diff --git a/src/libs/engine/events/DisconnectPortEvent.h b/src/libs/engine/events/DisconnectPortEvent.h index 639de102..0c185317 100644 --- a/src/libs/engine/events/DisconnectPortEvent.h +++ b/src/libs/engine/events/DisconnectPortEvent.h @@ -43,12 +43,12 @@ using std::string; class DisconnectPortEvent : public QueuedEvent { public: - DisconnectPortEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path); - DisconnectPortEvent(Port* port); + DisconnectPortEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path); + DisconnectPortEvent(Engine& engine, Port* port); ~DisconnectPortEvent(); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/DisconnectionEvent.cpp b/src/libs/engine/events/DisconnectionEvent.cpp index 431061a2..c246e9dc 100644 --- a/src/libs/engine/events/DisconnectionEvent.cpp +++ b/src/libs/engine/events/DisconnectionEvent.cpp @@ -35,8 +35,8 @@ namespace Ingen { //// DisconnectionEvent //// -DisconnectionEvent::DisconnectionEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path) -: QueuedEvent(responder, timestamp), +DisconnectionEvent::DisconnectionEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path) +: QueuedEvent(engine, responder, timestamp), m_src_port_path(src_port_path), m_dst_port_path(dst_port_path), m_patch(NULL), @@ -49,8 +49,8 @@ DisconnectionEvent::DisconnectionEvent(CountedPtr<Responder> responder, SampleCo } -DisconnectionEvent::DisconnectionEvent(CountedPtr<Responder> responder, SampleCount timestamp, Port* const src_port, Port* const dst_port) -: QueuedEvent(responder, timestamp), +DisconnectionEvent::DisconnectionEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, Port* const src_port, Port* const dst_port) +: QueuedEvent(engine, responder, timestamp), m_src_port_path(src_port->path()), m_dst_port_path(dst_port->path()), m_patch(src_port->parent_node()->parent_patch()), @@ -85,7 +85,7 @@ DisconnectionEvent::pre_process() return; } - /*m_patch = Engine::instance().object_store()->find_patch(m_src_port_path.parent().parent()); + /*m_patch = _engine.object_store()->find_patch(m_src_port_path.parent().parent()); if (m_patch == NULL) { m_error = PORT_NOT_FOUND; @@ -93,8 +93,8 @@ DisconnectionEvent::pre_process() return; }*/ - m_src_port = Engine::instance().object_store()->find_port(m_src_port_path); - m_dst_port = Engine::instance().object_store()->find_port(m_dst_port_path); + m_src_port = _engine.object_store()->find_port(m_src_port_path); + m_dst_port = _engine.object_store()->find_port(m_dst_port_path); } if (m_src_port == NULL || m_dst_port == NULL) { @@ -112,10 +112,10 @@ DisconnectionEvent::pre_process() // Create the typed event to actually do the work const DataType type = m_src_port->type(); if (type == DataType::FLOAT) { - m_typed_event = new TypedDisconnectionEvent<Sample>(_responder, _time_stamp, + m_typed_event = new TypedDisconnectionEvent<Sample>(_engine, _responder, _time, dynamic_cast<OutputPort<Sample>*>(m_src_port), dynamic_cast<InputPort<Sample>*>(m_dst_port)); } else if (type == DataType::MIDI) { - m_typed_event = new TypedDisconnectionEvent<MidiMessage>(_responder, _time_stamp, + m_typed_event = new TypedDisconnectionEvent<MidiMessage>(_engine, _responder, _time, dynamic_cast<OutputPort<MidiMessage>*>(m_src_port), dynamic_cast<InputPort<MidiMessage>*>(m_dst_port)); } else { m_error = TYPE_MISMATCH; @@ -131,12 +131,12 @@ DisconnectionEvent::pre_process() void -DisconnectionEvent::execute(SampleCount offset) +DisconnectionEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); if (m_error == NO_ERROR) - m_typed_event->execute(offset); + m_typed_event->execute(nframes, start, end); } @@ -159,8 +159,8 @@ DisconnectionEvent::post_process() template <typename T> -TypedDisconnectionEvent<T>::TypedDisconnectionEvent(CountedPtr<Responder> responder, SampleCount timestamp, OutputPort<T>* src_port, InputPort<T>* dst_port) -: QueuedEvent(responder, timestamp), +TypedDisconnectionEvent<T>::TypedDisconnectionEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, OutputPort<T>* src_port, InputPort<T>* dst_port) +: QueuedEvent(engine, responder, timestamp), m_src_port(src_port), m_dst_port(dst_port), m_patch(NULL), @@ -223,7 +223,7 @@ TypedDisconnectionEvent<T>::pre_process() break; } - if (m_patch->process()) + if (m_patch->enabled()) m_process_order = m_patch->build_process_order(); m_succeeded = true; @@ -233,7 +233,7 @@ TypedDisconnectionEvent<T>::pre_process() template <typename T> void -TypedDisconnectionEvent<T>::execute(SampleCount offset) +TypedDisconnectionEvent<T>::execute(SampleCount nframes, FrameTime start, FrameTime end) { if (m_succeeded) { @@ -248,18 +248,18 @@ TypedDisconnectionEvent<T>::execute(SampleCount offset) assert((Connection*)port_connection->elem() == patch_connection->elem()); // Clean up both the list node and the connection itself... - Engine::instance().maid()->push(port_connection); - Engine::instance().maid()->push(patch_connection); - Engine::instance().maid()->push(port_connection->elem()); + _engine.maid()->push(port_connection); + _engine.maid()->push(patch_connection); + _engine.maid()->push(port_connection->elem()); if (m_patch->process_order() != NULL) - Engine::instance().maid()->push(m_patch->process_order()); + _engine.maid()->push(m_patch->process_order()); m_patch->process_order(m_process_order); } else { m_succeeded = false; // Ports weren't connected } } - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); } @@ -271,7 +271,7 @@ TypedDisconnectionEvent<T>::post_process() _responder->respond_ok(); - Engine::instance().client_broadcaster()->send_disconnection(m_src_port->path(), m_dst_port->path()); + _engine.client_broadcaster()->send_disconnection(m_src_port->path(), m_dst_port->path()); } else { _responder->respond_error("Unable to disconnect ports."); } diff --git a/src/libs/engine/events/DisconnectionEvent.h b/src/libs/engine/events/DisconnectionEvent.h index 3108f2f8..1dc53d13 100644 --- a/src/libs/engine/events/DisconnectionEvent.h +++ b/src/libs/engine/events/DisconnectionEvent.h @@ -46,12 +46,12 @@ template <typename T> class TypedDisconnectionEvent; // helper, defined below class DisconnectionEvent : public QueuedEvent { public: - DisconnectionEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path); - DisconnectionEvent(CountedPtr<Responder> responder, SampleCount timestamp, Port* const src_port, Port* const dst_port); + DisconnectionEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& src_port_path, const string& dst_port_path); + DisconnectionEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, Port* const src_port, Port* const dst_port); ~DisconnectionEvent(); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: @@ -82,10 +82,10 @@ template <typename T> class TypedDisconnectionEvent : public QueuedEvent { public: - TypedDisconnectionEvent(CountedPtr<Responder> responder, SampleCount timestamp, OutputPort<T>* src_port, InputPort<T>* dst_port); + TypedDisconnectionEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, OutputPort<T>* src_port, InputPort<T>* dst_port); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/EnablePatchEvent.cpp b/src/libs/engine/events/EnablePatchEvent.cpp index b2b3ee08..132aefcc 100644 --- a/src/libs/engine/events/EnablePatchEvent.cpp +++ b/src/libs/engine/events/EnablePatchEvent.cpp @@ -25,8 +25,8 @@ namespace Ingen { -EnablePatchEvent::EnablePatchEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path) -: QueuedEvent(responder, timestamp), +EnablePatchEvent::EnablePatchEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path) +: QueuedEvent(engine, responder, timestamp), m_patch_path(patch_path), m_patch(NULL), m_process_order(NULL) @@ -37,7 +37,7 @@ EnablePatchEvent::EnablePatchEvent(CountedPtr<Responder> responder, SampleCount void EnablePatchEvent::pre_process() { - m_patch = Engine::instance().object_store()->find_patch(m_patch_path); + m_patch = _engine.object_store()->find_patch(m_patch_path); if (m_patch != NULL) { /* Any event that requires a new process order will set the patch's @@ -52,16 +52,16 @@ EnablePatchEvent::pre_process() void -EnablePatchEvent::execute(SampleCount offset) +EnablePatchEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { if (m_patch != NULL) { - m_patch->process(true); + m_patch->enable(); if (m_patch->process_order() == NULL) m_patch->process_order(m_process_order); } - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); } @@ -70,7 +70,7 @@ EnablePatchEvent::post_process() { if (m_patch != NULL) { _responder->respond_ok(); - Engine::instance().client_broadcaster()->send_patch_enable(m_patch_path); + _engine.client_broadcaster()->send_patch_enable(m_patch_path); } else { _responder->respond_error(string("Patch ") + m_patch_path + " not found"); } diff --git a/src/libs/engine/events/EnablePatchEvent.h b/src/libs/engine/events/EnablePatchEvent.h index 4ae93099..8e39e3a7 100644 --- a/src/libs/engine/events/EnablePatchEvent.h +++ b/src/libs/engine/events/EnablePatchEvent.h @@ -37,10 +37,10 @@ class Node; class EnablePatchEvent : public QueuedEvent { public: - EnablePatchEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path); + EnablePatchEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& patch_path); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/LashRestoreDoneEvent.h b/src/libs/engine/events/LashRestoreDoneEvent.h index b543905c..be07bed0 100644 --- a/src/libs/engine/events/LashRestoreDoneEvent.h +++ b/src/libs/engine/events/LashRestoreDoneEvent.h @@ -39,7 +39,7 @@ class Port; class LashRestoreDoneEvent : public QueuedEvent { public: - LashRestoreDoneEvent(CountedPtr<Responder> responder, SampleCount timestamp) : QueuedEvent(responder, timestamp) {} + LashRestoreDoneEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp) : QueuedEvent(engine, responder, timestamp) {} void post_process() { diff --git a/src/libs/engine/events/LoadPluginsEvent.cpp b/src/libs/engine/events/LoadPluginsEvent.cpp index cae25733..6962387b 100644 --- a/src/libs/engine/events/LoadPluginsEvent.cpp +++ b/src/libs/engine/events/LoadPluginsEvent.cpp @@ -25,11 +25,11 @@ using std::cerr; namespace Ingen { -LoadPluginsEvent::LoadPluginsEvent(CountedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(responder, timestamp) +LoadPluginsEvent::LoadPluginsEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp) +: QueuedEvent(engine, responder, timestamp) { cerr << "LOADING PLUGINS\n"; - Engine::instance().node_factory()->load_plugins(); + _engine.node_factory()->load_plugins(); } diff --git a/src/libs/engine/events/LoadPluginsEvent.h b/src/libs/engine/events/LoadPluginsEvent.h index 0e40ca7e..ae784e3a 100644 --- a/src/libs/engine/events/LoadPluginsEvent.h +++ b/src/libs/engine/events/LoadPluginsEvent.h @@ -29,7 +29,7 @@ namespace Ingen { class LoadPluginsEvent : public QueuedEvent { public: - LoadPluginsEvent(CountedPtr<Responder> responder, SampleCount timestamp); + LoadPluginsEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp); void post_process(); }; diff --git a/src/libs/engine/events/MidiLearnEvent.cpp b/src/libs/engine/events/MidiLearnEvent.cpp index 814ecdb5..822573e0 100644 --- a/src/libs/engine/events/MidiLearnEvent.cpp +++ b/src/libs/engine/events/MidiLearnEvent.cpp @@ -30,15 +30,15 @@ namespace Ingen { void MidiLearnResponseEvent::post_process() { - Engine::instance().client_broadcaster()->send_control_change(m_port_path, m_value); + _engine.client_broadcaster()->send_control_change(m_port_path, m_value); } // MidiLearnEvent -MidiLearnEvent::MidiLearnEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path) -: QueuedEvent(responder, timestamp), +MidiLearnEvent::MidiLearnEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path) +: QueuedEvent(engine, responder, timestamp), m_node_path(node_path), m_node(NULL), m_response_event(NULL) @@ -49,17 +49,17 @@ MidiLearnEvent::MidiLearnEvent(CountedPtr<Responder> responder, SampleCount time void MidiLearnEvent::pre_process() { - m_node = Engine::instance().object_store()->find_node(m_node_path); - m_response_event = new MidiLearnResponseEvent(m_node_path + "/Controller_Number", _time_stamp); + m_node = _engine.object_store()->find_node(m_node_path); + m_response_event = new MidiLearnResponseEvent(_engine, m_node_path + "/Controller_Number", _time); QueuedEvent::pre_process(); } void -MidiLearnEvent::execute(SampleCount offset) +MidiLearnEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); // FIXME: this isn't very good at all. if (m_node != NULL && m_node->plugin()->type() == Plugin::Internal diff --git a/src/libs/engine/events/MidiLearnEvent.h b/src/libs/engine/events/MidiLearnEvent.h index 558261a8..7a36706c 100644 --- a/src/libs/engine/events/MidiLearnEvent.h +++ b/src/libs/engine/events/MidiLearnEvent.h @@ -37,8 +37,8 @@ class ControlChangeEvent; class MidiLearnResponseEvent : public Event { public: - MidiLearnResponseEvent(const string& port_path, SampleCount timestamp) - : Event(NULL, timestamp), + MidiLearnResponseEvent(Engine& engine, const string& port_path, SampleCount timestamp) + : Event(engine, NULL, timestamp), m_port_path(port_path), m_value(0.0f) {} @@ -64,10 +64,10 @@ private: class MidiLearnEvent : public QueuedEvent { public: - MidiLearnEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path); + MidiLearnEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/NoteOffEvent.cpp b/src/libs/engine/events/NoteOffEvent.cpp index 027e9f1f..8145c208 100644 --- a/src/libs/engine/events/NoteOffEvent.cpp +++ b/src/libs/engine/events/NoteOffEvent.cpp @@ -27,8 +27,8 @@ namespace Ingen { /** Note off with patch explicitly passed - triggered by MIDI. */ -NoteOffEvent::NoteOffEvent(CountedPtr<Responder> responder, SampleCount timestamp, Node* node, uchar note_num) -: Event(responder, timestamp), +NoteOffEvent::NoteOffEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, Node* node, uchar note_num) +: Event(engine, responder, timestamp), m_node(node), m_note_num(note_num) { @@ -37,8 +37,8 @@ NoteOffEvent::NoteOffEvent(CountedPtr<Responder> responder, SampleCount timestam /** Note off event with lookup - triggered by OSC. */ -NoteOffEvent::NoteOffEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, uchar note_num) -: Event(responder, timestamp), +NoteOffEvent::NoteOffEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, uchar note_num) +: Event(engine, responder, timestamp), m_node(NULL), m_node_path(node_path), m_note_num(note_num) @@ -47,17 +47,19 @@ NoteOffEvent::NoteOffEvent(CountedPtr<Responder> responder, SampleCount timestam void -NoteOffEvent::execute(SampleCount offset) +NoteOffEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { + assert(_time >= start && _time <= end); + if (m_node == NULL && m_node_path != "") - m_node = Engine::instance().object_store()->find_node(m_node_path); + m_node = _engine.object_store()->find_node(m_node_path); // FIXME: this isn't very good at all. if (m_node != NULL && m_node->plugin()->type() == Plugin::Internal) { if (m_node->plugin()->plug_label() == "note_in") - ((MidiNoteNode*)m_node)->note_off(m_note_num, offset); + ((MidiNoteNode*)m_node)->note_off(m_note_num, _time, nframes, start, end); else if (m_node->plugin()->plug_label() == "trigger_in") - ((MidiTriggerNode*)m_node)->note_off(m_note_num, offset); + ((MidiTriggerNode*)m_node)->note_off(m_note_num, _time, nframes, start, end); } } diff --git a/src/libs/engine/events/NoteOffEvent.h b/src/libs/engine/events/NoteOffEvent.h index 707077a1..e3e9a56b 100644 --- a/src/libs/engine/events/NoteOffEvent.h +++ b/src/libs/engine/events/NoteOffEvent.h @@ -34,10 +34,10 @@ class Node; class NoteOffEvent : public Event { public: - NoteOffEvent(CountedPtr<Responder> responder, SampleCount timestamp, Node* node, uchar note_num); - NoteOffEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, uchar note_num); + NoteOffEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, Node* node, uchar note_num); + NoteOffEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, uchar note_num); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/NoteOnEvent.cpp b/src/libs/engine/events/NoteOnEvent.cpp index cbbc0e1d..7a98c58d 100644 --- a/src/libs/engine/events/NoteOnEvent.cpp +++ b/src/libs/engine/events/NoteOnEvent.cpp @@ -30,8 +30,8 @@ namespace Ingen { * * Used to be triggered by MIDI. Not used anymore. */ -NoteOnEvent::NoteOnEvent(CountedPtr<Responder> responder, SampleCount timestamp, Node* patch, uchar note_num, uchar velocity) -: Event(responder, timestamp), +NoteOnEvent::NoteOnEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, Node* patch, uchar note_num, uchar velocity) +: Event(engine, responder, timestamp), m_node(patch), m_note_num(note_num), m_velocity(velocity), @@ -44,8 +44,8 @@ NoteOnEvent::NoteOnEvent(CountedPtr<Responder> responder, SampleCount timestamp, * * Triggered by OSC. */ -NoteOnEvent::NoteOnEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, uchar note_num, uchar velocity) -: Event(responder, timestamp), +NoteOnEvent::NoteOnEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, uchar note_num, uchar velocity) +: Event(engine, responder, timestamp), m_node(NULL), m_node_path(node_path), m_note_num(note_num), @@ -56,18 +56,20 @@ NoteOnEvent::NoteOnEvent(CountedPtr<Responder> responder, SampleCount timestamp, void -NoteOnEvent::execute(SampleCount offset) +NoteOnEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { + assert(_time >= start && _time <= end); + // Lookup if neccessary if (m_is_osc_triggered) - m_node = Engine::instance().object_store()->find_node(m_node_path); + m_node = _engine.object_store()->find_node(m_node_path); // FIXME: this isn't very good at all. if (m_node != NULL && m_node->plugin()->type() == Plugin::Internal) { if (m_node->plugin()->plug_label() == "note_in") - ((MidiNoteNode*)m_node)->note_on(m_note_num, m_velocity, offset); + ((MidiNoteNode*)m_node)->note_on(m_note_num, m_velocity, _time, nframes, start, end); else if (m_node->plugin()->plug_label() == "trigger_in") - ((MidiTriggerNode*)m_node)->note_on(m_note_num, m_velocity, offset); + ((MidiTriggerNode*)m_node)->note_on(m_note_num, m_velocity, _time, nframes, start, end); } } diff --git a/src/libs/engine/events/NoteOnEvent.h b/src/libs/engine/events/NoteOnEvent.h index 209e7137..92ffbca5 100644 --- a/src/libs/engine/events/NoteOnEvent.h +++ b/src/libs/engine/events/NoteOnEvent.h @@ -34,10 +34,10 @@ class Node; class NoteOnEvent : public Event { public: - NoteOnEvent(CountedPtr<Responder> responder, SampleCount timestamp, Node* patch, uchar note_num, uchar velocity); - NoteOnEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, uchar note_num, uchar velocity); + NoteOnEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, Node* patch, uchar note_num, uchar velocity); + NoteOnEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, uchar note_num, uchar velocity); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/PingQueuedEvent.h b/src/libs/engine/events/PingQueuedEvent.h index 10e3a3bb..883ee818 100644 --- a/src/libs/engine/events/PingQueuedEvent.h +++ b/src/libs/engine/events/PingQueuedEvent.h @@ -34,7 +34,7 @@ class Port; class PingQueuedEvent : public QueuedEvent { public: - PingQueuedEvent(CountedPtr<Responder> responder, SampleCount timestamp) : QueuedEvent(responder, timestamp) {} + PingQueuedEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp) : QueuedEvent(engine, responder, timestamp) {} void post_process() { _responder->respond_ok(); } }; diff --git a/src/libs/engine/events/RegisterClientEvent.cpp b/src/libs/engine/events/RegisterClientEvent.cpp index ab076059..e35b7fdb 100644 --- a/src/libs/engine/events/RegisterClientEvent.cpp +++ b/src/libs/engine/events/RegisterClientEvent.cpp @@ -22,11 +22,11 @@ namespace Ingen { -RegisterClientEvent::RegisterClientEvent(CountedPtr<Responder> responder, +RegisterClientEvent::RegisterClientEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, ClientKey key, CountedPtr<ClientInterface> client) -: QueuedEvent(responder, timestamp) +: QueuedEvent(engine, responder, timestamp) , _key(key) , _client(client) { @@ -36,7 +36,7 @@ RegisterClientEvent::RegisterClientEvent(CountedPtr<Responder> responder, void RegisterClientEvent::pre_process() { - Engine::instance().client_broadcaster()->register_client(_key, _client); + _engine.client_broadcaster()->register_client(_key, _client); QueuedEvent::pre_process(); } diff --git a/src/libs/engine/events/RegisterClientEvent.h b/src/libs/engine/events/RegisterClientEvent.h index bc26c3bb..d68a0f83 100644 --- a/src/libs/engine/events/RegisterClientEvent.h +++ b/src/libs/engine/events/RegisterClientEvent.h @@ -35,7 +35,7 @@ namespace Ingen { class RegisterClientEvent : public QueuedEvent { public: - RegisterClientEvent(CountedPtr<Responder> responder, + RegisterClientEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, ClientKey key, CountedPtr<ClientInterface> client); diff --git a/src/libs/engine/events/RenameEvent.cpp b/src/libs/engine/events/RenameEvent.cpp index 25a54285..465f4946 100644 --- a/src/libs/engine/events/RenameEvent.cpp +++ b/src/libs/engine/events/RenameEvent.cpp @@ -27,8 +27,8 @@ namespace Ingen { -RenameEvent::RenameEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& name) -: QueuedEvent(responder, timestamp), +RenameEvent::RenameEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& name) +: QueuedEvent(engine, responder, timestamp), m_old_path(path), m_name(name), m_new_path(m_old_path.parent().base_path() + name), @@ -58,13 +58,13 @@ RenameEvent::pre_process() return; } - if (Engine::instance().object_store()->find(m_new_path)) { + if (_engine.object_store()->find(m_new_path)) { m_error = OBJECT_EXISTS; QueuedEvent::pre_process(); return; } - GraphObject* obj = Engine::instance().object_store()->find(m_old_path); + GraphObject* obj = _engine.object_store()->find(m_old_path); if (obj == NULL) { m_error = OBJECT_NOT_FOUND; @@ -89,10 +89,10 @@ RenameEvent::pre_process() void -RenameEvent::execute(SampleCount offset) +RenameEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { //cout << "Executing rename event..."; - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); } @@ -103,7 +103,7 @@ RenameEvent::post_process() if (m_error == NO_ERROR) { _responder->respond_ok(); - Engine::instance().client_broadcaster()->send_rename(m_old_path, m_new_path); + _engine.client_broadcaster()->send_rename(m_old_path, m_new_path); } else { if (m_error == OBJECT_EXISTS) msg.append("Object already exists at ").append(m_new_path); diff --git a/src/libs/engine/events/RenameEvent.h b/src/libs/engine/events/RenameEvent.h index d13efea9..fd01820b 100644 --- a/src/libs/engine/events/RenameEvent.h +++ b/src/libs/engine/events/RenameEvent.h @@ -42,11 +42,11 @@ class DisconnectPortEvent; class RenameEvent : public QueuedEvent { public: - RenameEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& name); + RenameEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& name); ~RenameEvent(); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/RequestAllObjectsEvent.cpp b/src/libs/engine/events/RequestAllObjectsEvent.cpp index b28294cc..5eb780b3 100644 --- a/src/libs/engine/events/RequestAllObjectsEvent.cpp +++ b/src/libs/engine/events/RequestAllObjectsEvent.cpp @@ -18,12 +18,14 @@ #include "Responder.h" #include "Engine.h" #include "ObjectSender.h" +#include "ClientBroadcaster.h" +#include "ObjectStore.h" namespace Ingen { -RequestAllObjectsEvent::RequestAllObjectsEvent(CountedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(responder, timestamp), +RequestAllObjectsEvent::RequestAllObjectsEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp) +: QueuedEvent(engine, responder, timestamp), m_client(CountedPtr<ClientInterface>(NULL)) { } @@ -32,7 +34,7 @@ RequestAllObjectsEvent::RequestAllObjectsEvent(CountedPtr<Responder> responder, void RequestAllObjectsEvent::pre_process() { - m_client = _responder->find_client(); + m_client = _engine.client_broadcaster()->client(_responder->client_key()); QueuedEvent::pre_process(); } @@ -43,9 +45,14 @@ RequestAllObjectsEvent::post_process() { if (m_client) { _responder->respond_ok(); - ObjectSender::send_all(m_client.get()); + + // Everything is a child of the root patch, so this sends it all + Patch* root = _engine.object_store()->find_patch("/"); + if (root) + ObjectSender::send_patch(m_client.get(), root); + } else { - _responder->respond_error("Invalid URL"); + _responder->respond_error("Unable to find client to send all objects"); } } diff --git a/src/libs/engine/events/RequestAllObjectsEvent.h b/src/libs/engine/events/RequestAllObjectsEvent.h index 760a06ea..7651700f 100644 --- a/src/libs/engine/events/RequestAllObjectsEvent.h +++ b/src/libs/engine/events/RequestAllObjectsEvent.h @@ -35,7 +35,7 @@ namespace Shared { class RequestAllObjectsEvent : public QueuedEvent { public: - RequestAllObjectsEvent(CountedPtr<Responder> responder, SampleCount timestamp); + RequestAllObjectsEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp); void pre_process(); void post_process(); diff --git a/src/libs/engine/events/RequestMetadataEvent.cpp b/src/libs/engine/events/RequestMetadataEvent.cpp index e8112797..03d84d7f 100644 --- a/src/libs/engine/events/RequestMetadataEvent.cpp +++ b/src/libs/engine/events/RequestMetadataEvent.cpp @@ -27,8 +27,8 @@ using std::string; namespace Ingen { -RequestMetadataEvent::RequestMetadataEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, const string& key) -: QueuedEvent(responder, timestamp), +RequestMetadataEvent::RequestMetadataEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& node_path, const string& key) +: QueuedEvent(engine, responder, timestamp), m_path(node_path), m_key(key), m_value(""), @@ -41,10 +41,10 @@ RequestMetadataEvent::RequestMetadataEvent(CountedPtr<Responder> responder, Samp void RequestMetadataEvent::pre_process() { - m_client = _responder->find_client(); + m_client = _engine.client_broadcaster()->client(_responder->client_key()); if (m_client) { - m_object = Engine::instance().object_store()->find(m_path); + m_object = _engine.object_store()->find(m_path); if (m_object == NULL) { QueuedEvent::pre_process(); return; diff --git a/src/libs/engine/events/RequestMetadataEvent.h b/src/libs/engine/events/RequestMetadataEvent.h index 0b1cc267..4f99e023 100644 --- a/src/libs/engine/events/RequestMetadataEvent.h +++ b/src/libs/engine/events/RequestMetadataEvent.h @@ -37,7 +37,7 @@ namespace Shared { class RequestMetadataEvent : public QueuedEvent { public: - RequestMetadataEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& key); + RequestMetadataEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& key); void pre_process(); void post_process(); diff --git a/src/libs/engine/events/RequestPluginsEvent.cpp b/src/libs/engine/events/RequestPluginsEvent.cpp index 65dfb7aa..9efb2388 100644 --- a/src/libs/engine/events/RequestPluginsEvent.cpp +++ b/src/libs/engine/events/RequestPluginsEvent.cpp @@ -18,12 +18,13 @@ #include "Responder.h" #include "Engine.h" #include "ClientBroadcaster.h" +#include "NodeFactory.h" namespace Ingen { -RequestPluginsEvent::RequestPluginsEvent(CountedPtr<Responder> responder, SampleCount timestamp) -: QueuedEvent(responder, timestamp), +RequestPluginsEvent::RequestPluginsEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp) +: QueuedEvent(engine, responder, timestamp), m_client(CountedPtr<ClientInterface>(NULL)) { } @@ -32,8 +33,12 @@ RequestPluginsEvent::RequestPluginsEvent(CountedPtr<Responder> responder, Sample void RequestPluginsEvent::pre_process() { - m_client = _responder->find_client(); + m_client = _engine.client_broadcaster()->client(_responder->client_key()); + // Take a copy to send in the post processing thread (to avoid problems + // because std::list isn't thread safe) + m_plugins = _engine.node_factory()->plugins(); + QueuedEvent::pre_process(); } @@ -42,10 +47,10 @@ void RequestPluginsEvent::post_process() { if (m_client) { - Engine::instance().client_broadcaster()->send_plugins_to(m_client.get()); + _engine.client_broadcaster()->send_plugins_to(m_client.get(), m_plugins); _responder->respond_ok(); } else { - _responder->respond_error("Invalid URL"); + _responder->respond_error("Unable to find client to send plugins"); } } diff --git a/src/libs/engine/events/RequestPluginsEvent.h b/src/libs/engine/events/RequestPluginsEvent.h index 0a35a1ad..cd2d05fc 100644 --- a/src/libs/engine/events/RequestPluginsEvent.h +++ b/src/libs/engine/events/RequestPluginsEvent.h @@ -18,11 +18,13 @@ #define REQUESTPLUGINSEVENT_H #include <string> +#include <list> #include "QueuedEvent.h" using std::string; namespace Ingen { +class Plugin; class Responder; namespace Shared { class ClientInterface; @@ -36,13 +38,14 @@ namespace Shared { class RequestPluginsEvent : public QueuedEvent { public: - RequestPluginsEvent(CountedPtr<Responder> responder, SampleCount timestamp); + RequestPluginsEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp); void pre_process(); void post_process(); private: CountedPtr<ClientInterface> m_client; + std::list<Plugin*> m_plugins; }; diff --git a/src/libs/engine/events/RequestPortValueEvent.cpp b/src/libs/engine/events/RequestPortValueEvent.cpp index d02eed6a..830ef852 100644 --- a/src/libs/engine/events/RequestPortValueEvent.cpp +++ b/src/libs/engine/events/RequestPortValueEvent.cpp @@ -28,8 +28,8 @@ using std::string; namespace Ingen { -RequestPortValueEvent::RequestPortValueEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path) -: QueuedEvent(responder, timestamp), +RequestPortValueEvent::RequestPortValueEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path) +: QueuedEvent(engine, responder, timestamp), m_port_path(port_path), m_port(NULL), m_value(0.0), @@ -41,22 +41,24 @@ RequestPortValueEvent::RequestPortValueEvent(CountedPtr<Responder> responder, Sa void RequestPortValueEvent::pre_process() { - m_client = _responder->find_client(); - m_port = Engine::instance().object_store()->find_port(m_port_path); + m_client = _engine.client_broadcaster()->client(_responder->client_key()); + m_port = _engine.object_store()->find_port(m_port_path); QueuedEvent::pre_process(); } void -RequestPortValueEvent::execute(SampleCount offset) +RequestPortValueEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { + assert(_time >= start && _time <= end); + if (m_port != NULL && m_port->type() == DataType::FLOAT) - m_value = ((TypedPort<Sample>*)m_port)->buffer(0)->value_at(offset); + m_value = ((TypedPort<Sample>*)m_port)->buffer(0)->value_at(_time - start); else m_port = NULL; // triggers error response - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); } @@ -70,7 +72,7 @@ RequestPortValueEvent::post_process() _responder->respond_ok(); m_client->control_change(m_port_path, m_value); } else { - _responder->respond_error("Invalid URL"); + _responder->respond_error("Unable to find client to send port value"); } } diff --git a/src/libs/engine/events/RequestPortValueEvent.h b/src/libs/engine/events/RequestPortValueEvent.h index 9b809b3d..204f1911 100644 --- a/src/libs/engine/events/RequestPortValueEvent.h +++ b/src/libs/engine/events/RequestPortValueEvent.h @@ -37,10 +37,10 @@ using Shared::ClientInterface; class RequestPortValueEvent : public QueuedEvent { public: - RequestPortValueEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path); + RequestPortValueEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/SetMetadataEvent.cpp b/src/libs/engine/events/SetMetadataEvent.cpp index 3d77b77b..1ce5d6f4 100644 --- a/src/libs/engine/events/SetMetadataEvent.cpp +++ b/src/libs/engine/events/SetMetadataEvent.cpp @@ -27,8 +27,8 @@ using std::string; namespace Ingen { -SetMetadataEvent::SetMetadataEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& key, const string& value) -: QueuedEvent(responder, timestamp), +SetMetadataEvent::SetMetadataEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& key, const string& value) +: QueuedEvent(engine, responder, timestamp), m_path(path), m_key(key), m_value(value), @@ -40,7 +40,7 @@ SetMetadataEvent::SetMetadataEvent(CountedPtr<Responder> responder, SampleCount void SetMetadataEvent::pre_process() { - m_object = Engine::instance().object_store()->find(m_path); + m_object = _engine.object_store()->find(m_path); if (m_object == NULL) { QueuedEvent::pre_process(); return; @@ -53,11 +53,11 @@ SetMetadataEvent::pre_process() void -SetMetadataEvent::execute(SampleCount offset) +SetMetadataEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { // Do nothing - QueuedEvent::execute(offset); + QueuedEvent::execute(nframes, start, end); } @@ -70,7 +70,7 @@ SetMetadataEvent::post_process() _responder->respond_error(msg); } else { _responder->respond_ok(); - Engine::instance().client_broadcaster()->send_metadata_update(m_path, m_key, m_value); + _engine.client_broadcaster()->send_metadata_update(m_path, m_key, m_value); } } diff --git a/src/libs/engine/events/SetMetadataEvent.h b/src/libs/engine/events/SetMetadataEvent.h index 7ea534a1..855aeb62 100644 --- a/src/libs/engine/events/SetMetadataEvent.h +++ b/src/libs/engine/events/SetMetadataEvent.h @@ -34,10 +34,10 @@ class GraphObject; class SetMetadataEvent : public QueuedEvent { public: - SetMetadataEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& key, const string& value); + SetMetadataEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& path, const string& key, const string& value); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/SetPortValueEvent.cpp b/src/libs/engine/events/SetPortValueEvent.cpp index 6331a4b5..4018139a 100644 --- a/src/libs/engine/events/SetPortValueEvent.cpp +++ b/src/libs/engine/events/SetPortValueEvent.cpp @@ -27,8 +27,8 @@ namespace Ingen { /** Voice-specific control setting */ -SetPortValueEvent::SetPortValueEvent(CountedPtr<Responder> responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val) -: Event(responder, timestamp), +SetPortValueEvent::SetPortValueEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val) +: Event(engine, responder, timestamp), m_voice_num(voice_num), m_port_path(port_path), m_val(val), @@ -38,8 +38,8 @@ SetPortValueEvent::SetPortValueEvent(CountedPtr<Responder> responder, SampleCoun } -SetPortValueEvent::SetPortValueEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path, Sample val) -: Event(responder, timestamp), +SetPortValueEvent::SetPortValueEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path, Sample val) +: Event(engine, responder, timestamp), m_voice_num(-1), m_port_path(port_path), m_val(val), @@ -50,10 +50,12 @@ SetPortValueEvent::SetPortValueEvent(CountedPtr<Responder> responder, SampleCoun void -SetPortValueEvent::execute(SampleCount offset) +SetPortValueEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { + assert(_time >= start && _time <= end); + if (m_port == NULL) - m_port = Engine::instance().object_store()->find_port(m_port_path); + m_port = _engine.object_store()->find_port(m_port_path); if (m_port == NULL) { m_error = PORT_NOT_FOUND; @@ -61,9 +63,9 @@ SetPortValueEvent::execute(SampleCount offset) m_error = TYPE_MISMATCH; } else { if (m_voice_num == -1) - ((TypedPort<Sample>*)m_port)->set_value(m_val, offset); + ((TypedPort<Sample>*)m_port)->set_value(m_val, _time - start); else - ((TypedPort<Sample>*)m_port)->set_value(m_voice_num, m_val, offset); + ((TypedPort<Sample>*)m_port)->set_value(m_voice_num, m_val, _time - start); //((TypedPort<Sample>*)m_port)->buffer(m_voice_num)->set(m_val, offset); // FIXME: check range } } @@ -76,13 +78,13 @@ SetPortValueEvent::post_process() assert(m_port != NULL); _responder->respond_ok(); - Engine::instance().client_broadcaster()->send_control_change(m_port_path, m_val); + _engine.client_broadcaster()->send_control_change(m_port_path, m_val); // Send patch port control change, if this is a bridge port /*Port* parent_port = m_port->parent_node()->as_port(); if (parent_port != NULL) { assert(parent_port->type() == DataType::FLOAT); - Engine::instance().client_broadcaster()->send_control_change(parent_port->path(), m_val); + _engine.client_broadcaster()->send_control_change(parent_port->path(), m_val); }*/ } else if (m_error == PORT_NOT_FOUND) { diff --git a/src/libs/engine/events/SetPortValueEvent.h b/src/libs/engine/events/SetPortValueEvent.h index ecd1557a..2572df55 100644 --- a/src/libs/engine/events/SetPortValueEvent.h +++ b/src/libs/engine/events/SetPortValueEvent.h @@ -34,10 +34,10 @@ class Port; class SetPortValueEvent : public Event { public: - SetPortValueEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path, Sample val); - SetPortValueEvent(CountedPtr<Responder> responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val); + SetPortValueEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path, Sample val); + SetPortValueEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/SetPortValueQueuedEvent.cpp b/src/libs/engine/events/SetPortValueQueuedEvent.cpp index 8a5afc65..caee68a6 100644 --- a/src/libs/engine/events/SetPortValueQueuedEvent.cpp +++ b/src/libs/engine/events/SetPortValueQueuedEvent.cpp @@ -28,8 +28,8 @@ namespace Ingen { /** Voice-specific control setting */ -SetPortValueQueuedEvent::SetPortValueQueuedEvent(CountedPtr<Responder> responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val) -: QueuedEvent(responder, timestamp), +SetPortValueQueuedEvent::SetPortValueQueuedEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val) +: QueuedEvent(engine, responder, timestamp), m_voice_num(voice_num), m_port_path(port_path), m_val(val), @@ -39,8 +39,8 @@ SetPortValueQueuedEvent::SetPortValueQueuedEvent(CountedPtr<Responder> responder } -SetPortValueQueuedEvent::SetPortValueQueuedEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path, Sample val) -: QueuedEvent(responder, timestamp), +SetPortValueQueuedEvent::SetPortValueQueuedEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path, Sample val) +: QueuedEvent(engine, responder, timestamp), m_voice_num(-1), m_port_path(port_path), m_val(val), @@ -54,7 +54,7 @@ void SetPortValueQueuedEvent::pre_process() { if (m_port == NULL) - m_port = Engine::instance().object_store()->find_port(m_port_path); + m_port = _engine.object_store()->find_port(m_port_path); if (m_port == NULL) { m_error = PORT_NOT_FOUND; @@ -67,16 +67,18 @@ SetPortValueQueuedEvent::pre_process() void -SetPortValueQueuedEvent::execute(SampleCount offset) +SetPortValueQueuedEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) { - QueuedEvent::execute(offset); + assert(_time >= start && _time <= end); + + QueuedEvent::execute(nframes, start, end); if (m_error == NO_ERROR) { assert(m_port != NULL); if (m_voice_num == -1) - ((TypedPort<Sample>*)m_port)->set_value(m_val, offset); + ((TypedPort<Sample>*)m_port)->set_value(m_val, _time - start); else - ((TypedPort<Sample>*)m_port)->buffer(m_voice_num)->set(m_val, offset); // FIXME: check range + ((TypedPort<Sample>*)m_port)->buffer(m_voice_num)->set(m_val, _time - start); // FIXME: check range } } @@ -88,13 +90,13 @@ SetPortValueQueuedEvent::post_process() assert(m_port != NULL); _responder->respond_ok(); - Engine::instance().client_broadcaster()->send_control_change(m_port_path, m_val); + _engine.client_broadcaster()->send_control_change(m_port_path, m_val); // Send patch port control change, if this is a bridge port /*Port* parent_port = m_port->parent_node()->as_port(); if (parent_port != NULL) { assert(parent_port->type() == DataType::FLOAT); - Engine::instance().client_broadcaster()->send_control_change(parent_port->path(), m_val); + _engine.client_broadcaster()->send_control_change(parent_port->path(), m_val); }*/ } else if (m_error == PORT_NOT_FOUND) { diff --git a/src/libs/engine/events/SetPortValueQueuedEvent.h b/src/libs/engine/events/SetPortValueQueuedEvent.h index 9e83e045..dc5add84 100644 --- a/src/libs/engine/events/SetPortValueQueuedEvent.h +++ b/src/libs/engine/events/SetPortValueQueuedEvent.h @@ -34,11 +34,11 @@ class Port; class SetPortValueQueuedEvent : public QueuedEvent { public: - SetPortValueQueuedEvent(CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path, Sample val); - SetPortValueQueuedEvent(CountedPtr<Responder> responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val); + SetPortValueQueuedEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, const string& port_path, Sample val); + SetPortValueQueuedEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val); void pre_process(); - void execute(SampleCount offset); + void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: diff --git a/src/libs/engine/events/UnregisterClientEvent.cpp b/src/libs/engine/events/UnregisterClientEvent.cpp index 5e720a24..13709959 100644 --- a/src/libs/engine/events/UnregisterClientEvent.cpp +++ b/src/libs/engine/events/UnregisterClientEvent.cpp @@ -23,8 +23,8 @@ namespace Ingen { -UnregisterClientEvent::UnregisterClientEvent(CountedPtr<Responder> responder, SampleCount timestamp, ClientKey key) -: QueuedEvent(responder, timestamp) +UnregisterClientEvent::UnregisterClientEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, ClientKey key) +: QueuedEvent(engine, responder, timestamp) , _key(key) { } @@ -33,7 +33,7 @@ UnregisterClientEvent::UnregisterClientEvent(CountedPtr<Responder> responder, Sa void UnregisterClientEvent::post_process() { - if (Engine::instance().client_broadcaster()->unregister_client(_key)) + if (_engine.client_broadcaster()->unregister_client(_key)) _responder->respond_ok(); else _responder->respond_error("Unable to unregister client"); diff --git a/src/libs/engine/events/UnregisterClientEvent.h b/src/libs/engine/events/UnregisterClientEvent.h index 1523394e..29166345 100644 --- a/src/libs/engine/events/UnregisterClientEvent.h +++ b/src/libs/engine/events/UnregisterClientEvent.h @@ -39,7 +39,7 @@ using Shared::ClientKey; class UnregisterClientEvent : public QueuedEvent { public: - UnregisterClientEvent(CountedPtr<Responder> responder, SampleCount timestamp, ClientKey key); + UnregisterClientEvent(Engine& engine, CountedPtr<Responder> responder, SampleCount timestamp, ClientKey key); void post_process(); diff --git a/src/libs/engine/types.h b/src/libs/engine/types.h index 73cc5c73..b4c23486 100644 --- a/src/libs/engine/types.h +++ b/src/libs/engine/types.h @@ -27,6 +27,7 @@ typedef unsigned long ulong; typedef jack_default_audio_sample_t Sample; typedef jack_nframes_t SampleCount; typedef jack_nframes_t SampleRate; +typedef jack_nframes_t FrameTime; /** A type that Ingen can process/patch (eg can be stored in a port) */ enum DataType { FLOAT, MIDI, UNKNOWN }; diff --git a/src/progs/server/main.cpp b/src/progs/server/main.cpp index 8ded37b7..ec1788f0 100644 --- a/src/progs/server/main.cpp +++ b/src/progs/server/main.cpp @@ -32,6 +32,9 @@ using std::cout; using std::endl; using std::cerr; +Ingen::Engine* engine; + + void catch_int(int) { @@ -39,7 +42,7 @@ catch_int(int) signal(SIGTERM, catch_int); std::cout << "[Main] Ingen interrupted." << std::endl; - Ingen::Engine::instance().quit(); + engine->quit(); } @@ -132,20 +135,19 @@ main(int argc, char** argv) Ingen::set_denormal_flags(); - Ingen::Engine::instantiate(args_info.port_arg); + engine = new Ingen::Engine(args_info.port_arg); #ifdef HAVE_LASH Ingen::lash_driver = new Ingen::LashDriver(Ingen::om, lash_args); #endif - Ingen::Engine::instance().main(); + engine->main(); #ifdef HAVE_LASH delete Ingen::lash_driver; #endif - // FIXME: leak - //delete Ingen::om; + delete engine; } return ret; |