From c1160ffc8a5dfb38891b0faa6373c9eecdd8e4c9 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 22 Sep 2007 23:51:00 +0000 Subject: Type oblivious set_port_value interface. git-svn-id: http://svn.drobilla.net/lad/ingen@765 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/engine/events/SetPortValueEvent.cpp | 84 ++++++++++++++++------ src/libs/engine/events/SetPortValueEvent.hpp | 26 +++++-- src/libs/engine/events/SetPortValueQueuedEvent.cpp | 56 ++++++++++----- src/libs/engine/events/SetPortValueQueuedEvent.hpp | 26 +++++-- 4 files changed, 141 insertions(+), 51 deletions(-) (limited to 'src/libs/engine/events') diff --git a/src/libs/engine/events/SetPortValueEvent.cpp b/src/libs/engine/events/SetPortValueEvent.cpp index 581defa6..fa2238e2 100644 --- a/src/libs/engine/events/SetPortValueEvent.cpp +++ b/src/libs/engine/events/SetPortValueEvent.cpp @@ -15,6 +15,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include "Responder.hpp" #include "SetPortValueEvent.hpp" #include "Engine.hpp" @@ -23,31 +24,57 @@ #include "Node.hpp" #include "ObjectStore.hpp" #include "AudioBuffer.hpp" +#include "MidiBuffer.hpp" + +using namespace std; namespace Ingen { -/** Voice-specific control setting - */ -SetPortValueEvent::SetPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val) +/** Omni (all voices) control setting */ +SetPortValueEvent::SetPortValueEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const string& port_path, + uint32_t data_size, + const void* data) : Event(engine, responder, timestamp), - _voice_num(voice_num), + _omni(true), + _voice_num(0), _port_path(port_path), - _val(val), + _data_size(data_size), + _data(malloc(data_size)), _port(NULL), _error(NO_ERROR) { + memcpy(_data, data, data_size); } -SetPortValueEvent::SetPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path, Sample val) +/** Voice-specific control setting */ +SetPortValueEvent::SetPortValueEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + uint32_t voice_num, + const string& port_path, + uint32_t data_size, + const void* data) : Event(engine, responder, timestamp), - _voice_num(-1), + _omni(false), + _voice_num(voice_num), _port_path(port_path), - _val(val), + _data_size(data_size), + _data(malloc(data_size)), _port(NULL), _error(NO_ERROR) { + memcpy(_data, data, data_size); +} + + +SetPortValueEvent::~SetPortValueEvent() +{ + free(_data); } @@ -62,16 +89,28 @@ SetPortValueEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) if (_port == NULL) { _error = PORT_NOT_FOUND; - } else if (!(_port->type() == DataType::FLOAT)) { - _error = TYPE_MISMATCH; +/* } else if (_port->buffer(0)->size() < _data_size) { + _error = NO_SPACE;*/ } else { - AudioBuffer* const buf = (AudioBuffer*)_port->buffer(0); - const size_t offset = (buf->size() == 1) ? 0 : _time - start; - if (_voice_num == -1) - for (uint32_t i=0; i < _port->poly(); ++i) - ((AudioBuffer*)_port->buffer(i))->set(_val, offset); - else - ((AudioBuffer*)_port->buffer(_voice_num))->set(_val, offset); + Buffer* const buf = _port->buffer(0); + AudioBuffer* const abuf = dynamic_cast(buf); + if (abuf) { + const size_t offset = (buf->size() == 1) ? 0 : _time - start; + + if (_omni) + for (uint32_t i=0; i < _port->poly(); ++i) + ((AudioBuffer*)_port->buffer(i))->set(*(float*)_data, offset); + else + ((AudioBuffer*)_port->buffer(_voice_num))->set(*(float*)_data, offset); + + return; + } + + MidiBuffer* const mbuf = dynamic_cast(buf); + if (mbuf) { + const double stamp = std::max((double)_time, mbuf->latest_stamp()); + mbuf->append(stamp, _data_size, (const unsigned char*)_data); + } } } @@ -83,17 +122,18 @@ SetPortValueEvent::post_process() assert(_port != NULL); _responder->respond_ok(); - _engine.broadcaster()->send_control_change(_port_path, _val); + _engine.broadcaster()->send_control_change(_port_path, *(float*)_data); } else if (_error == PORT_NOT_FOUND) { string msg = "Unable to find port "; msg.append(_port_path).append(" for set_port_value"); _responder->respond_error(msg); - } else if (_error == TYPE_MISMATCH) { - string msg = "Attempt to set "; - msg.append(_port_path).append(" to incompatible type"); - _responder->respond_error(msg); + } else if (_error == NO_SPACE) { + std::ostringstream msg("Attempt to write "); + msg << _data_size << " bytes to " << _port_path << ", with capacity " + << _port->buffer_size() << endl; + _responder->respond_error(msg.str()); } } diff --git a/src/libs/engine/events/SetPortValueEvent.hpp b/src/libs/engine/events/SetPortValueEvent.hpp index da378347..4b6e8d92 100644 --- a/src/libs/engine/events/SetPortValueEvent.hpp +++ b/src/libs/engine/events/SetPortValueEvent.hpp @@ -35,18 +35,34 @@ class Port; class SetPortValueEvent : public Event { public: - SetPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path, Sample val); - SetPortValueEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val); + SetPortValueEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const string& port_path, + uint32_t data_size, + const void* data); + + SetPortValueEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + uint32_t voice_num, + const string& port_path, + uint32_t data_size, + const void* data); + + ~SetPortValueEvent(); void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: - enum ErrorType { NO_ERROR, PORT_NOT_FOUND, TYPE_MISMATCH }; + enum ErrorType { NO_ERROR, PORT_NOT_FOUND, NO_SPACE }; - int _voice_num; + bool _omni; + uint32_t _voice_num; string _port_path; - float _val; + uint32_t _data_size; + void* _data; Port* _port; ErrorType _error; }; diff --git a/src/libs/engine/events/SetPortValueQueuedEvent.cpp b/src/libs/engine/events/SetPortValueQueuedEvent.cpp index 35c2f270..8940d4c5 100644 --- a/src/libs/engine/events/SetPortValueQueuedEvent.cpp +++ b/src/libs/engine/events/SetPortValueQueuedEvent.cpp @@ -15,6 +15,7 @@ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include "SetPortValueQueuedEvent.hpp" #include "Responder.hpp" #include "Engine.hpp" @@ -28,27 +29,44 @@ namespace Ingen { -/** Voice-specific control setting - */ -SetPortValueQueuedEvent::SetPortValueQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val) +/** Omni (all voices) control setting */ +SetPortValueQueuedEvent::SetPortValueQueuedEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const string& port_path, + uint32_t data_size, + const void* data) : QueuedEvent(engine, responder, timestamp), - _voice_num(voice_num), + _omni(true), + _voice_num(0), _port_path(port_path), - _val(val), + _data_size(data_size), + _data(malloc(data_size)), _port(NULL), _error(NO_ERROR) { + memcpy(_data, data, data_size); } -SetPortValueQueuedEvent::SetPortValueQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path, Sample val) +/** Voice-specific control setting */ +SetPortValueQueuedEvent::SetPortValueQueuedEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + uint32_t voice_num, + const string& port_path, + uint32_t data_size, + const void* data) : QueuedEvent(engine, responder, timestamp), - _voice_num(-1), + _omni(false), + _voice_num(voice_num), _port_path(port_path), - _val(val), + _data_size(data_size), + _data(malloc(data_size)), _port(NULL), _error(NO_ERROR) { + memcpy(_data, data, data_size); } @@ -60,8 +78,8 @@ SetPortValueQueuedEvent::pre_process() if (_port == NULL) { _error = PORT_NOT_FOUND; - } else if ( !(_port->type() == DataType::FLOAT) ) { - _error = TYPE_MISMATCH; +/* } else if (_port->buffer_size() < _data_size) { + _error = NO_SPACE;*/ } QueuedEvent::pre_process(); @@ -78,11 +96,12 @@ SetPortValueQueuedEvent::execute(SampleCount nframes, FrameTime start, FrameTime assert(_port); AudioBuffer* const buf = (AudioBuffer*)_port->buffer(0); const size_t offset = (buf->size() == 1) ? 0 : _time - start; - if (_voice_num == -1) + + if (_omni) for (uint32_t i=0; i < _port->poly(); ++i) - ((AudioBuffer*)_port->buffer(i))->set(_val, offset); + ((AudioBuffer*)_port->buffer(i))->set(*(float*)_data, offset); else - ((AudioBuffer*)_port->buffer(_voice_num))->set(_val, offset); + ((AudioBuffer*)_port->buffer(_voice_num))->set(*(float*)_data, offset); } } @@ -94,7 +113,7 @@ SetPortValueQueuedEvent::post_process() assert(_port != NULL); _responder->respond_ok(); - _engine.broadcaster()->send_control_change(_port_path, _val); + _engine.broadcaster()->send_control_change(_port_path, *(float*)_data); // Send patch port control change, if this is a bridge port /*Port* parent_port = _port->parent_node()->as_port(); @@ -108,10 +127,11 @@ SetPortValueQueuedEvent::post_process() msg.append(_port_path).append(" for set_port_value_slow"); _responder->respond_error(msg); - } else if (_error == TYPE_MISMATCH) { - string msg = "Attempt to set "; - msg.append(_port_path).append(" to incompatible type"); - _responder->respond_error(msg); + } else if (_error == NO_SPACE) { + std::ostringstream msg("Attempt to write "); + msg << _data_size << " bytes to " << _port_path << ", with capacity " + << _port->buffer_size() << endl; + _responder->respond_error(msg.str()); } } diff --git a/src/libs/engine/events/SetPortValueQueuedEvent.hpp b/src/libs/engine/events/SetPortValueQueuedEvent.hpp index 43e3d0f8..b64cf903 100644 --- a/src/libs/engine/events/SetPortValueQueuedEvent.hpp +++ b/src/libs/engine/events/SetPortValueQueuedEvent.hpp @@ -35,19 +35,33 @@ class Port; class SetPortValueQueuedEvent : public QueuedEvent { public: - SetPortValueQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, const string& port_path, Sample val); - SetPortValueQueuedEvent(Engine& engine, SharedPtr responder, SampleCount timestamp, size_t voice_num, const string& port_path, Sample val); - + SetPortValueQueuedEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + const string& port_path, + uint32_t data_size, + const void* data); + + SetPortValueQueuedEvent(Engine& engine, + SharedPtr responder, + SampleCount timestamp, + uint32_t voice_num, + const string& port_path, + uint32_t data_size, + const void* data); + void pre_process(); void execute(SampleCount nframes, FrameTime start, FrameTime end); void post_process(); private: - enum ErrorType { NO_ERROR, PORT_NOT_FOUND, TYPE_MISMATCH }; + enum ErrorType { NO_ERROR, PORT_NOT_FOUND, NO_SPACE }; - int _voice_num; + bool _omni; + uint32_t _voice_num; string _port_path; - float _val; + uint32_t _data_size; + void* _data; Port* _port; ErrorType _error; }; -- cgit v1.2.1