diff options
Diffstat (limited to 'src/libs/engine')
-rw-r--r-- | src/libs/engine/Engine.cpp | 5 | ||||
-rw-r--r-- | src/libs/engine/Event.cpp | 3 | ||||
-rw-r--r-- | src/libs/engine/EventBuffer.cpp | 40 | ||||
-rw-r--r-- | src/libs/engine/EventBuffer.hpp | 2 | ||||
-rw-r--r-- | src/libs/engine/LV2Info.cpp | 3 | ||||
-rw-r--r-- | src/libs/engine/NodeBase.cpp | 3 | ||||
-rw-r--r-- | src/libs/engine/OSCClientSender.cpp | 2 | ||||
-rw-r--r-- | src/libs/engine/OSCEngineReceiver.cpp | 94 | ||||
-rw-r--r-- | src/libs/engine/QueuedEngineInterface.cpp | 25 | ||||
-rw-r--r-- | src/libs/engine/QueuedEngineInterface.hpp | 5 | ||||
-rw-r--r-- | src/libs/engine/events/CreatePortEvent.cpp | 2 | ||||
-rw-r--r-- | src/libs/engine/events/SetPortValueEvent.cpp | 20 | ||||
-rw-r--r-- | src/libs/engine/events/SetPortValueEvent.hpp | 3 | ||||
-rw-r--r-- | src/libs/engine/events/SetPortValueQueuedEvent.cpp | 57 | ||||
-rw-r--r-- | src/libs/engine/events/SetPortValueQueuedEvent.hpp | 17 |
15 files changed, 182 insertions, 99 deletions
diff --git a/src/libs/engine/Engine.cpp b/src/libs/engine/Engine.cpp index 41ae9a43..6b98566d 100644 --- a/src/libs/engine/Engine.cpp +++ b/src/libs/engine/Engine.cpp @@ -177,7 +177,10 @@ Engine::start_osc_driver(int port) SharedPtr<QueuedEngineInterface> Engine::new_queued_interface() { - assert(!_event_source); + if (_event_source) { + cerr << "WARNING: Replacing event source" << endl; + _event_source.reset(); + } SharedPtr<QueuedEngineInterface> result(new QueuedEngineInterface( *this, Ingen::event_queue_size, Ingen::event_queue_size)); diff --git a/src/libs/engine/Event.cpp b/src/libs/engine/Event.cpp index 1db466ce..8e5c33da 100644 --- a/src/libs/engine/Event.cpp +++ b/src/libs/engine/Event.cpp @@ -40,7 +40,8 @@ Event::execute(ProcessContext& context) void Event::post_process() { - assert(ThreadManager::current_thread_id() == THREAD_POST_PROCESS); + // FIXME: Not true witn monolithic GUI/engine + //assert(ThreadManager::current_thread_id() == THREAD_POST_PROCESS); } diff --git a/src/libs/engine/EventBuffer.cpp b/src/libs/engine/EventBuffer.cpp index 9985e2b7..dfeff610 100644 --- a/src/libs/engine/EventBuffer.cpp +++ b/src/libs/engine/EventBuffer.cpp @@ -178,6 +178,9 @@ EventBuffer::append(uint32_t frames, } #endif + /*cout << "Appending event type " << type << ", size " << size + << " @ " << frames << "." << subframes << endl;*/ + bool ret = lv2_event_write(&_iter, frames, subframes, type, size, data); if (!ret) @@ -190,6 +193,43 @@ EventBuffer::append(uint32_t frames, } +/** Append a buffer of events to the buffer. + * + * \a timestamp must be >= the latest event in the buffer, + * and < this_nframes() + * + * \return true on success + */ +bool +EventBuffer::append(const LV2_Event_Buffer* buf) +{ + uint8_t** data; + bool ret = true; + + LV2_Event_Iterator iter; + for (lv2_event_begin(&iter, _buf); lv2_event_is_valid(&iter); lv2_event_increment(&iter)) { + LV2_Event* ev = lv2_event_get(&iter, data); + +#ifndef NDEBUG + assert((ev->frames > _latest_frames) + || (ev->frames == _latest_frames + && ev->subframes >= _latest_subframes)); +#endif + + if (!(ret = append(ev->frames, ev->subframes, ev->type, ev->size, *data))) { + cerr << "ERROR: Failed to write event." << endl; + break; + } else { + } + + _latest_frames = ev->frames; + _latest_subframes = ev->subframes; + } + + return ret; +} + + /** Read an event from the current position in the buffer * * \return true if read was successful, or false if end of buffer reached diff --git a/src/libs/engine/EventBuffer.hpp b/src/libs/engine/EventBuffer.hpp index 148b5420..20fde057 100644 --- a/src/libs/engine/EventBuffer.hpp +++ b/src/libs/engine/EventBuffer.hpp @@ -83,6 +83,8 @@ public: uint16_t size, const uint8_t* data); + bool append(const LV2_Event_Buffer* buf); + bool merge(const EventBuffer& a, const EventBuffer& b); private: diff --git a/src/libs/engine/LV2Info.cpp b/src/libs/engine/LV2Info.cpp index e5e9dde2..4d934855 100644 --- a/src/libs/engine/LV2Info.cpp +++ b/src/libs/engine/LV2Info.cpp @@ -34,9 +34,6 @@ LV2Info::LV2Info(Ingen::Shared::World* world) , event_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_EVENT)) , _world(world) { - // Client would never add the event referencing feature - assert( ! world->lv2_features->feature(LV2_EVENT_URI)); - LV2_Event_Feature* ev_data = (LV2_Event_Feature*)malloc(sizeof(LV2_Event_Feature)); ev_data->lv2_event_ref = &LV2Info::event_ref; ev_data->lv2_event_unref = &LV2Info::event_ref; diff --git a/src/libs/engine/NodeBase.cpp b/src/libs/engine/NodeBase.cpp index 54217aae..a6bfa9ce 100644 --- a/src/libs/engine/NodeBase.cpp +++ b/src/libs/engine/NodeBase.cpp @@ -91,7 +91,8 @@ NodeBase::activate() void NodeBase::deactivate() { - assert(ThreadManager::current_thread_id() == THREAD_POST_PROCESS); + // FIXME: Not true witn monolithic GUI/engine + //assert(ThreadManager::current_thread_id() == THREAD_POST_PROCESS); assert(_activated); _activated = false; } diff --git a/src/libs/engine/OSCClientSender.cpp b/src/libs/engine/OSCClientSender.cpp index aff7fa50..98164de7 100644 --- a/src/libs/engine/OSCClientSender.cpp +++ b/src/libs/engine/OSCClientSender.cpp @@ -98,7 +98,7 @@ void OSCClientSender::send_message(const char* path, lo_message msg) { // FIXME: size? liblo doesn't export this. - // Don't want to exceed max UDP packet size (1500 bytes?}) + // Don't want to exceed max UDP packet size (1500 bytes?) static const size_t MAX_BUNDLE_SIZE = 1500 - 32*5; if (!_enabled) diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp index 5308a2f2..d9cebba4 100644 --- a/src/libs/engine/OSCEngineReceiver.cpp +++ b/src/libs/engine/OSCEngineReceiver.cpp @@ -610,12 +610,14 @@ OSCEngineReceiver::_disconnect_all_cb(const char* path, const char* types, lo_ar * <p> \b /ingen/set_port_value_immediate - Sets the value of a port for all voices (both AR and CR) * \arg \b response-id (integer) * \arg \b port-path (string) - Name of port + * \arg \b type (string (URI or QName)) - Type of value being set (ingen:Float or ingen:EventBuffer) * \arg \b value (float or blob) - Value to set port to </p> \n \n */ /** \page engine_osc_namespace * <p> \b /ingen/set_port_value_immediate - Sets the value of a port for a specific voice (both AR and CR) * \arg \b response-id (integer) * \arg \b port-path (string) - Name of port + * \arg \b type (string (URI or QName)) - Type of value being set (ingen:Float or ingen:Event) * \arg \b voice (integer) - Voice to set port value for * \arg \b value (float or blob) - Value to set port to </p> \n \n * @@ -624,39 +626,29 @@ OSCEngineReceiver::_disconnect_all_cb(const char* path, const char* types, lo_ar int OSCEngineReceiver::_set_port_value_immediate_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) { - if (argc < 3 || argc > 4 || strncmp(types, "is", 2)) + if (argc < 3 || argc > 5 || strncmp(types, "is", 2)) return 1; const char* port_path = &argv[1]->s; - if (argc == 3) { - if (types[2] == 'f') { - const float value = argv[2]->f; - set_port_value_immediate(port_path, "", sizeof(float), &value); - return 0; - } else if (types[2] == 'b') { - lo_blob b = argv[2]; - size_t data_size = lo_blob_datasize(b); - void* data = lo_blob_dataptr(b); - set_port_value_immediate(port_path, "", data_size, data); - return 0; - } else { - return 1; - } + if (!strcmp(types, "isf")) { // float, all voices + const float value = argv[2]->f; + set_port_value_immediate(port_path, "ingen:Float", sizeof(float), &value); + } else if (!strcmp(types, "isif")) { // float, specific voice + const float value = argv[3]->f; + set_port_value_immediate(port_path, "ingen:Float", argv[2]->i, sizeof(float), &value); + } else if (!strcmp(types, "issb")) { // blob (event), all voices + lo_blob b = argv[3]; + size_t data_size = lo_blob_datasize(b); + void* data = lo_blob_dataptr(b); + set_port_value_immediate(port_path, &argv[2]->s, data_size, data); + } else if (!strcmp(types, "isisb")) { // blob (event), specific voice + lo_blob b = argv[4]; + size_t data_size = lo_blob_datasize(b); + void* data = lo_blob_dataptr(b); + set_port_value_immediate(port_path, &argv[3]->s, argv[2]->i, data_size, data); } else { - if (types[3] == 'f') { - const float value = argv[3]->f; - set_port_value_immediate(port_path, "", argv[2]->i, sizeof(float), &value); - return 0; - } else if (types[3] == 'b') { - lo_blob b = argv[3]; - size_t data_size = lo_blob_datasize(b); - void* data = lo_blob_dataptr(b); - set_port_value_immediate(port_path, "", argv[2]->i, data_size, data); - return 0; - } else { - return 1; - } + return 1; } return 0; @@ -694,39 +686,29 @@ OSCEngineReceiver::_set_port_value_immediate_cb(const char* path, const char* ty int OSCEngineReceiver::_set_port_value_cb(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg) { - if (argc < 3 || argc > 4 || strncmp(types, "is", 2)) + if (argc < 3 || argc > 5 || strncmp(types, "is", 2)) return 1; const char* port_path = &argv[1]->s; - if (argc == 3) { - if (types[2] == 'f') { - const float value = argv[2]->f; - set_port_value(port_path, "who cares", sizeof(float), &value); - return 0; - } else if (types[2] == 'b') { - lo_blob b = argv[2]; - size_t data_size = lo_blob_datasize(b); - void* data = lo_blob_dataptr(b); - set_port_value(port_path, "who cares", data_size, data); - return 0; - } else { - return 1; - } + if (!strcmp(types, "isf")) { // float, all voices + const float value = argv[2]->f; + set_port_value_immediate(port_path, "ingen:Float", sizeof(float), &value); + } else if (!strcmp(types, "isif")) { // float, specific voice + const float value = argv[3]->f; + set_port_value_immediate(port_path, "ingen:Float", argv[2]->i, sizeof(float), &value); + } else if (!strcmp(types, "issb")) { // blob (event), all voices + lo_blob b = argv[3]; + size_t data_size = lo_blob_datasize(b); + void* data = lo_blob_dataptr(b); + set_port_value_immediate(port_path, &argv[2]->s, data_size, data); + } else if (!strcmp(types, "isisb")) { // blob (event), specific voice + lo_blob b = argv[4]; + size_t data_size = lo_blob_datasize(b); + void* data = lo_blob_dataptr(b); + set_port_value_immediate(port_path, &argv[3]->s, argv[2]->i, data_size, data); } else { - if (types[3] == 'f') { - const float value = argv[3]->f; - set_port_value(port_path, "who cares", argv[2]->i, sizeof(float), &value); - return 0; - } else if (types[3] == 'b') { - lo_blob b = argv[3]; - size_t data_size = lo_blob_datasize(b); - void* data = lo_blob_dataptr(b); - set_port_value(port_path, "who cares", argv[2]->i, data_size, data); - return 0; - } else { - return 1; - } + return 1; } return 0; diff --git a/src/libs/engine/QueuedEngineInterface.cpp b/src/libs/engine/QueuedEngineInterface.cpp index feb08c9c..08ab781a 100644 --- a/src/libs/engine/QueuedEngineInterface.cpp +++ b/src/libs/engine/QueuedEngineInterface.cpp @@ -29,6 +29,7 @@ QueuedEngineInterface::QueuedEngineInterface(Engine& engine, size_t queued_size, : QueuedEventSource(queued_size, stamped_size) , _responder(new Responder(NULL, 0)) , _engine(engine) + , _in_bundle(false) { } @@ -116,8 +117,23 @@ QueuedEngineInterface::quit() _responder->respond_ok(); _engine.quit(); } + + +// Bundle commands + +void +QueuedEngineInterface::bundle_begin() +{ + _in_bundle = true; +} +void +QueuedEngineInterface::bundle_end() +{ + _in_bundle = false; +} + // Object commands @@ -126,7 +142,6 @@ QueuedEngineInterface::create_patch(const string& path, uint32_t poly) { push_queued(new CreatePatchEvent(_engine, _responder, now(), path, poly)); - } @@ -240,7 +255,7 @@ QueuedEngineInterface::set_port_value(const string& port_path, uint32_t data_size, const void* data) { - push_queued(new SetPortValueQueuedEvent(_engine, _responder, now(), port_path, data_size, data)); + push_queued(new SetPortValueQueuedEvent(_engine, _responder, now(), port_path, type_uri, data_size, data)); } @@ -251,7 +266,7 @@ QueuedEngineInterface::set_port_value(const string& port_path, uint32_t data_size, const void* data) { - push_queued(new SetPortValueQueuedEvent(_engine, _responder, now(), voice, port_path, data_size, data)); + push_queued(new SetPortValueQueuedEvent(_engine, _responder, now(), voice, port_path, type_uri, data_size, data)); } @@ -261,7 +276,7 @@ QueuedEngineInterface::set_port_value_immediate(const string& port_path, uint32_t data_size, const void* data) { - push_stamped(new SetPortValueEvent(_engine, _responder, now(), port_path, data_size, data)); + push_stamped(new SetPortValueEvent(_engine, _responder, now(), port_path, type_uri, data_size, data)); } @@ -272,7 +287,7 @@ QueuedEngineInterface::set_port_value_immediate(const string& port_path, uint32_t data_size, const void* data) { - push_stamped(new SetPortValueEvent(_engine, _responder, now(), voice, port_path, data_size, data)); + push_stamped(new SetPortValueEvent(_engine, _responder, now(), voice, port_path, type_uri, data_size, data)); } diff --git a/src/libs/engine/QueuedEngineInterface.hpp b/src/libs/engine/QueuedEngineInterface.hpp index 54b3b5fd..adf6d263 100644 --- a/src/libs/engine/QueuedEngineInterface.hpp +++ b/src/libs/engine/QueuedEngineInterface.hpp @@ -74,6 +74,10 @@ public: virtual void activate(); virtual void deactivate(); virtual void quit(); + + // Bundles + virtual void bundle_begin(); + virtual void bundle_end(); // Object commands @@ -177,6 +181,7 @@ protected: SharedPtr<Responder> _responder; ///< NULL if responding disabled Engine& _engine; + bool _in_bundle; ///< True iff a bundle is currently being received private: SampleCount now() const; diff --git a/src/libs/engine/events/CreatePortEvent.cpp b/src/libs/engine/events/CreatePortEvent.cpp index 7c7d671b..272ef561 100644 --- a/src/libs/engine/events/CreatePortEvent.cpp +++ b/src/libs/engine/events/CreatePortEvent.cpp @@ -85,7 +85,7 @@ CreatePortEvent::pre_process() assert(_patch->path() == _path.parent()); size_t buffer_size = 1; - if (_type != "ingen:control") + if (_type != "ingen:Float") buffer_size = _engine.audio_driver()->buffer_size(); const uint32_t old_num_ports = _patch->num_ports(); diff --git a/src/libs/engine/events/SetPortValueEvent.cpp b/src/libs/engine/events/SetPortValueEvent.cpp index 36f60809..cf9e60c3 100644 --- a/src/libs/engine/events/SetPortValueEvent.cpp +++ b/src/libs/engine/events/SetPortValueEvent.cpp @@ -38,12 +38,14 @@ SetPortValueEvent::SetPortValueEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& port_path, + const string& data_type, uint32_t data_size, const void* data) : Event(engine, responder, timestamp) , _omni(true) , _voice_num(0) , _port_path(port_path) + , _data_type(data_type) , _data_size(data_size) , _data(malloc(data_size)) , _port(NULL) @@ -59,12 +61,13 @@ SetPortValueEvent::SetPortValueEvent(Engine& engine, SampleCount timestamp, uint32_t voice_num, const string& port_path, + const string& data_type, uint32_t data_size, const void* data) : Event(engine, responder, timestamp) , _omni(false) , _voice_num(voice_num) - , _port_path(port_path) + , _data_type(data_type) , _data_size(data_size) , _data(malloc(data_size)) , _port(NULL) @@ -109,14 +112,23 @@ SetPortValueEvent::execute(ProcessContext& context) } EventBuffer* const ebuf = dynamic_cast<EventBuffer*>(buf); - if (ebuf) { + // FIXME: eliminate string comparisons + if (ebuf && _data_type == "lv2_midi:MidiEvent") { + const LV2Features::Feature* f = _engine.world()->lv2_features->feature(LV2_URI_MAP_URI); + LV2URIMap* map = (LV2URIMap*)f->controller; + const uint32_t type_id = map->uri_to_id(NULL, "http://lv2plug.in/ns/ext/midi#MidiEvent"); const uint32_t frames = std::max((uint32_t)(_time - context.start()), ebuf->latest_frames()); - // FIXME: type ebuf->prepare_write(context.nframes()); - ebuf->append(frames, 0, 0, _data_size, (const unsigned char*)_data); + // FIXME: how should this work? binary over OSC, ick + // Message is an event: + ebuf->append(frames, 0, type_id, _data_size, (const unsigned char*)_data); + // Message is an event buffer: + //ebuf->append((LV2_Event_Buffer*)_data); _port->raise_set_by_user_flag(); return; } + + cerr << "WARNING: Unknown value type " << _data_type << ", ignoring" << endl; } } diff --git a/src/libs/engine/events/SetPortValueEvent.hpp b/src/libs/engine/events/SetPortValueEvent.hpp index e6497aa5..d814a55b 100644 --- a/src/libs/engine/events/SetPortValueEvent.hpp +++ b/src/libs/engine/events/SetPortValueEvent.hpp @@ -39,6 +39,7 @@ public: SharedPtr<Responder> responder, SampleCount timestamp, const string& port_path, + const string& data_type, uint32_t data_size, const void* data); @@ -47,6 +48,7 @@ public: SampleCount timestamp, uint32_t voice_num, const string& port_path, + const string& data_type, uint32_t data_size, const void* data); @@ -61,6 +63,7 @@ private: bool _omni; uint32_t _voice_num; const string _port_path; + const string _data_type; uint32_t _data_size; void* _data; PortImpl* _port; diff --git a/src/libs/engine/events/SetPortValueQueuedEvent.cpp b/src/libs/engine/events/SetPortValueQueuedEvent.cpp index 28bb6df1..14060134 100644 --- a/src/libs/engine/events/SetPortValueQueuedEvent.cpp +++ b/src/libs/engine/events/SetPortValueQueuedEvent.cpp @@ -16,6 +16,7 @@ */ #include <sstream> +#include <iostream> #include "SetPortValueQueuedEvent.hpp" #include "Responder.hpp" #include "Engine.hpp" @@ -28,6 +29,8 @@ #include "EventBuffer.hpp" #include "ProcessContext.hpp" +using namespace std; + namespace Ingen { @@ -36,16 +39,18 @@ SetPortValueQueuedEvent::SetPortValueQueuedEvent(Engine& engine, SharedPtr<Responder> responder, SampleCount timestamp, const string& port_path, + const string& data_type, uint32_t data_size, const void* data) -: QueuedEvent(engine, responder, timestamp), - _omni(true), - _voice_num(0), - _port_path(port_path), - _data_size(data_size), - _data(malloc(data_size)), - _port(NULL), - _error(NO_ERROR) + : QueuedEvent(engine, responder, timestamp) + , _omni(true) + , _voice_num(0) + , _port_path(port_path) + , _data_type(data_type) + , _data_size(data_size) + , _data(malloc(data_size)) + , _port(NULL) + , _error(NO_ERROR) { memcpy(_data, data, data_size); } @@ -57,16 +62,18 @@ SetPortValueQueuedEvent::SetPortValueQueuedEvent(Engine& engine, SampleCount timestamp, uint32_t voice_num, const string& port_path, + const string& data_type, uint32_t data_size, const void* data) -: QueuedEvent(engine, responder, timestamp), - _omni(false), - _voice_num(voice_num), - _port_path(port_path), - _data_size(data_size), - _data(malloc(data_size)), - _port(NULL), - _error(NO_ERROR) + : QueuedEvent(engine, responder, timestamp) + , _omni(false) + , _voice_num(voice_num) + , _port_path(port_path) + , _data_type(data_type) + , _data_size(data_size) + , _data(malloc(data_size)) + , _port(NULL) + , _error(NO_ERROR) { memcpy(_data, data, data_size); } @@ -112,11 +119,23 @@ SetPortValueQueuedEvent::execute(ProcessContext& context) } EventBuffer* const ebuf = dynamic_cast<EventBuffer*>(buf); - if (ebuf) { + // FIXME: eliminate string comparisons + if (ebuf && _data_type == "lv2_midi:MidiEvent") { + const LV2Features::Feature* f = _engine.world()->lv2_features->feature(LV2_URI_MAP_URI); + LV2URIMap* map = (LV2URIMap*)f->controller; + const uint32_t type_id = map->uri_to_id(NULL, "http://lv2plug.in/ns/ext/midi#MidiEvent"); const uint32_t frames = std::max((uint32_t)(_time - context.start()), ebuf->latest_frames()); - // FIXME: type - ebuf->append(frames, 0, 0, _data_size, (const unsigned char*)_data); + ebuf->prepare_write(context.nframes()); + // FIXME: how should this work? binary over OSC, ick + // Message is an event: + ebuf->append(frames, 0, type_id, _data_size, (const unsigned char*)_data); + // Message is an event buffer: + //ebuf->append((LV2_Event_Buffer*)_data); + _port->raise_set_by_user_flag(); + return; } + + cerr << "WARNING: Unknown value type " << _data_type << ", ignoring" << endl; } } diff --git a/src/libs/engine/events/SetPortValueQueuedEvent.hpp b/src/libs/engine/events/SetPortValueQueuedEvent.hpp index 382a574e..937a3ad8 100644 --- a/src/libs/engine/events/SetPortValueQueuedEvent.hpp +++ b/src/libs/engine/events/SetPortValueQueuedEvent.hpp @@ -39,6 +39,7 @@ public: SharedPtr<Responder> responder, SampleCount timestamp, const string& port_path, + const string& data_type, uint32_t data_size, const void* data); @@ -47,6 +48,7 @@ public: SampleCount timestamp, uint32_t voice_num, const string& port_path, + const string& data_type, uint32_t data_size, const void* data); @@ -57,13 +59,14 @@ public: private: enum ErrorType { NO_ERROR, PORT_NOT_FOUND, NO_SPACE }; - bool _omni; - uint32_t _voice_num; - string _port_path; - uint32_t _data_size; - void* _data; - PortImpl* _port; - ErrorType _error; + bool _omni; + uint32_t _voice_num; + string _port_path; + const string _data_type; + uint32_t _data_size; + void* _data; + PortImpl* _port; + ErrorType _error; }; |