summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-11-12 06:56:26 +0000
committerDavid Robillard <d@drobilla.net>2009-11-12 06:56:26 +0000
commit64bd557e75113743f179086b365ea7d97b72ee3e (patch)
tree6a6f5b72a8ce97616cd5ccff188f2e44e92d1ba8 /src/engine
parent023dcf4cb297928879eb0e53cf0216edb562f6fa (diff)
downloadingen-64bd557e75113743f179086b365ea7d97b72ee3e.tar.gz
ingen-64bd557e75113743f179086b365ea7d97b72ee3e.tar.bz2
ingen-64bd557e75113743f179086b365ea7d97b72ee3e.zip
String port support.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2255 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/AudioBuffer.cpp1
-rw-r--r--src/engine/AudioBuffer.hpp2
-rw-r--r--src/engine/Buffer.cpp3
-rw-r--r--src/engine/Buffer.hpp12
-rw-r--r--src/engine/EventBuffer.hpp15
-rw-r--r--src/engine/LV2Info.cpp3
-rw-r--r--src/engine/LV2Info.hpp1
-rw-r--r--src/engine/LV2Node.cpp70
-rw-r--r--src/engine/PortImpl.cpp29
-rw-r--r--src/engine/PortImpl.hpp2
-rw-r--r--src/engine/StringBuffer.cpp121
-rw-r--r--src/engine/StringBuffer.hpp59
-rw-r--r--src/engine/events/RequestMetadata.cpp13
-rw-r--r--src/engine/events/RequestMetadata.hpp10
-rw-r--r--src/engine/events/SendPortValue.hpp21
-rw-r--r--src/engine/events/SetPortValue.cpp24
-rw-r--r--src/engine/internals/Note.cpp6
-rw-r--r--src/engine/wscript1
18 files changed, 315 insertions, 78 deletions
diff --git a/src/engine/AudioBuffer.cpp b/src/engine/AudioBuffer.cpp
index dc7efee5..02ebea57 100644
--- a/src/engine/AudioBuffer.cpp
+++ b/src/engine/AudioBuffer.cpp
@@ -35,7 +35,6 @@ AudioBuffer::AudioBuffer(size_t size)
: Buffer((size == 1) ? DataType::CONTROL : DataType::AUDIO, size)
, _data(NULL)
, _local_data(NULL)
- , _size(size)
, _filled_size(0)
, _state(OK)
, _set_value(0)
diff --git a/src/engine/AudioBuffer.hpp b/src/engine/AudioBuffer.hpp
index 732ff0db..aff990ec 100644
--- a/src/engine/AudioBuffer.hpp
+++ b/src/engine/AudioBuffer.hpp
@@ -56,7 +56,6 @@ public:
void prepare_read(FrameTime start, SampleCount nframes);
void prepare_write(FrameTime start, SampleCount nframes) {}
- void rewind() const {}
void resize(size_t size);
void filled_size(size_t size) { _filled_size = size; }
@@ -72,7 +71,6 @@ private:
Sample* _data; ///< Used data pointer (probably same as _local_data)
Sample* _local_data; ///< Locally allocated buffer (possibly unused if joined or set_data used)
- size_t _size; ///< Allocated buffer size
size_t _filled_size; ///< Usable buffer size (for MIDI ports etc)
State _state; ///< State of buffer for setting values next cycle
Sample _set_value; ///< Value set by set_value (for completing the set next cycle)
diff --git a/src/engine/Buffer.cpp b/src/engine/Buffer.cpp
index a8b091e0..14d97314 100644
--- a/src/engine/Buffer.cpp
+++ b/src/engine/Buffer.cpp
@@ -17,6 +17,7 @@
#include "AudioBuffer.hpp"
#include "EventBuffer.hpp"
+#include "StringBuffer.hpp"
namespace Ingen {
@@ -31,6 +32,8 @@ Buffer::create(DataType type, size_t size)
return new AudioBuffer(size);
else if (type.is_event())
return new EventBuffer(size);
+ else if (type.is_string())
+ return new StringBuffer(size);
else
throw;
}
diff --git a/src/engine/Buffer.hpp b/src/engine/Buffer.hpp
index c6b6dd1b..a1a56725 100644
--- a/src/engine/Buffer.hpp
+++ b/src/engine/Buffer.hpp
@@ -44,25 +44,25 @@ public:
/** Clear contents and reset state */
virtual void clear() = 0;
+ virtual void resize(size_t size) { _size = size; }
+
virtual void* raw_data() = 0;
virtual const void* raw_data() const = 0;
/** Rewind (ie reset read pointer), but leave contents unchanged */
- virtual void rewind() const = 0;
+ virtual void rewind() const {}
+
+ virtual void copy(const Buffer* src, size_t start_sample, size_t end_sample) = 0;
virtual void prepare_read(FrameTime start, SampleCount nframes) = 0;
virtual void prepare_write(FrameTime start, SampleCount nframes) = 0;
- bool is_joined() const { return (_joined_buf != NULL); }
+ bool is_joined() const { return (_joined_buf != NULL); }
Buffer* joined_buffer() const { return _joined_buf; }
virtual bool join(Buffer* buf) = 0;
virtual void unjoin() = 0;
- virtual void copy(const Buffer* src, size_t start_sample, size_t end_sample) = 0;
-
- virtual void resize(size_t size) { _size = size; }
-
Shared::DataType type() const { return _type; }
size_t size() const { return _size; }
diff --git a/src/engine/EventBuffer.hpp b/src/engine/EventBuffer.hpp
index b35fb13e..f89705b0 100644
--- a/src/engine/EventBuffer.hpp
+++ b/src/engine/EventBuffer.hpp
@@ -31,17 +31,20 @@ class EventBuffer : public Buffer {
public:
EventBuffer(size_t capacity);
- void prepare_read(FrameTime start, SampleCount nframes);
- void prepare_write(FrameTime start, SampleCount nframes);
-
bool join(Buffer* buf);
void unjoin();
+ void clear() { reset(_this_nframes); }
+
void* raw_data() { return _buf; }
const void* raw_data() const { return _buf; }
- void copy(const Buffer* src, size_t start_sample, size_t end_sample);
+ void rewind() const { _buf->rewind(); }
+ void prepare_read(FrameTime start, SampleCount nframes);
+ void prepare_write(FrameTime start, SampleCount nframes);
+
+ void copy(const Buffer* src, size_t start_sample, size_t end_sample);
bool merge(const EventBuffer& a, const EventBuffer& b);
bool increment() const { return _buf->increment(); }
@@ -52,10 +55,6 @@ public:
inline uint32_t this_nframes() const { return _this_nframes; }
inline uint32_t event_count() const { return _buf->event_count(); }
- inline void rewind() const { _buf->rewind(); }
-
- inline void clear() { reset(_this_nframes); }
-
inline void reset(SampleCount nframes) {
_this_nframes = nframes;
_buf->reset();
diff --git a/src/engine/LV2Info.cpp b/src/engine/LV2Info.cpp
index 91db3e7b..10541d0c 100644
--- a/src/engine/LV2Info.cpp
+++ b/src/engine/LV2Info.cpp
@@ -32,6 +32,8 @@ LV2Info::LV2Info(Ingen::Shared::World* world)
, control_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_CONTROL))
, audio_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_AUDIO))
, event_class(slv2_value_new_uri(world->slv2_world, SLV2_PORT_CLASS_EVENT))
+ , string_class(slv2_value_new_uri(world->slv2_world,
+ "http://lv2plug.in/ns/dev/string-port#StringPort"))
, _world(world)
{
assert(world);
@@ -55,6 +57,7 @@ LV2Info::~LV2Info()
slv2_value_free(control_class);
slv2_value_free(audio_class);
slv2_value_free(event_class);
+ slv2_value_free(string_class);
}
diff --git a/src/engine/LV2Info.hpp b/src/engine/LV2Info.hpp
index 2486efca..6f34dc57 100644
--- a/src/engine/LV2Info.hpp
+++ b/src/engine/LV2Info.hpp
@@ -47,6 +47,7 @@ public:
SLV2Value control_class;
SLV2Value audio_class;
SLV2Value event_class;
+ SLV2Value string_class;
Ingen::Shared::World& world() { return *_world; }
SLV2World lv2_world() { return _world->slv2_world; }
diff --git a/src/engine/LV2Node.cpp b/src/engine/LV2Node.cpp
index df2ccbb2..70ee2e08 100644
--- a/src/engine/LV2Node.cpp
+++ b/src/engine/LV2Node.cpp
@@ -43,11 +43,11 @@ using namespace Shared;
* (It _will_ crash!)
*/
LV2Node::LV2Node(LV2Plugin* plugin,
- const string& name,
- bool polyphonic,
- PatchImpl* parent,
- SampleRate srate,
- size_t buffer_size)
+ const string& name,
+ bool polyphonic,
+ PatchImpl* parent,
+ SampleRate srate,
+ size_t buffer_size)
: NodeBase(plugin, name, polyphonic, parent, srate, buffer_size)
, _lv2_plugin(plugin)
, _instances(NULL)
@@ -168,7 +168,7 @@ LV2Node::instantiate()
(*_instances)[i], LV2_CONTEXT_MESSAGE);
if (i == 0 && ctx_ext) {
- cerr << "HAS CONTEXT EXTENSION" << endl;
+ cerr << _lv2_plugin->uri() << " has message context" << endl;
assert(!_message_funcs);
_message_funcs = (LV2MessageContext*)ctx_ext;
}
@@ -184,9 +184,17 @@ LV2Node::instantiate()
float* def_values = new float[num_ports];
slv2_plugin_get_port_ranges_float(plug, 0, 0, def_values);
- SLV2Value pred = slv2_value_new_uri(info->lv2_world(),
+ SLV2Value context_pred = slv2_value_new_uri(info->lv2_world(),
"http://lv2plug.in/ns/dev/contexts#context");
+ // FIXME: Why doesn't this just use lv2:default?
+ SLV2Value default_pred = slv2_value_new_uri(info->lv2_world(),
+ "http://lv2plug.in/ns/dev/string-port#default");
+
+ // FIXME: Make this a separate extension
+ SLV2Value size_pred = slv2_value_new_uri(info->lv2_world(),
+ "http://lv2plug.in/ns/dev/string-port#requiredSpace");
+
for (uint32_t j=0; j < num_ports; ++j) {
SLV2Port id = slv2_plugin_get_port_by_index(plug, j);
@@ -196,6 +204,7 @@ LV2Node::instantiate()
port_path = path().child(port_name);
+ Raul::Atom val;
DataType data_type = DataType::UNKNOWN;
if (slv2_port_is_a(plug, id, info->control_class)) {
data_type = DataType::CONTROL;
@@ -206,6 +215,34 @@ LV2Node::instantiate()
} else if (slv2_port_is_a(plug, id, info->event_class)) {
data_type = DataType::EVENT;
port_buffer_size = _buffer_size;
+ } else if (slv2_port_is_a(plug, id, info->string_class)) {
+ data_type = DataType::STRING;
+ port_buffer_size = 0;
+
+ // Get default value, and its length
+ SLV2Values defaults = slv2_port_get_value(plug, id, default_pred);
+ for (uint32_t i = 0; i < slv2_values_size(defaults); ++i) {
+ SLV2Value d = slv2_values_get_at(defaults, i);
+ if (slv2_value_is_string(d)) {
+ const char* str_val = slv2_value_as_string(d);
+ const size_t str_val_len = strlen(str_val);
+ if (str_val_len >= port_buffer_size) {
+ val = str_val;
+ port_buffer_size = str_val_len;
+ }
+ }
+ }
+
+ // Get minimum size, if set in data
+ SLV2Values sizes = slv2_port_get_value(plug, id, size_pred);
+ for (uint32_t i = 0; i < slv2_values_size(sizes); ++i) {
+ SLV2Value d = slv2_values_get_at(sizes, i);
+ if (slv2_value_is_int(d)) {
+ size_t size_val = slv2_value_as_int(d);
+ if (size_val > port_buffer_size)
+ port_buffer_size = size_val;
+ }
+ }
}
enum { UNKNOWN, INPUT, OUTPUT } direction = UNKNOWN;
@@ -223,31 +260,30 @@ LV2Node::instantiate()
return false;
}
- // FIXME: need nice type preserving SLV2Value -> Raul::Atom conversion
- const float def = isnan(def_values[j]) ? 0.0f : def_values[j];
- const Raul::Atom defatm = def;
+ if (val.type() == Atom::NIL)
+ val = isnan(def_values[j]) ? 0.0f : def_values[j];
if (direction == INPUT)
- port = new InputPort(this, port_name, j, _polyphony, data_type, defatm, port_buffer_size);
+ port = new InputPort(this, port_name, j, _polyphony, data_type, val, port_buffer_size);
else
- port = new OutputPort(this, port_name, j, _polyphony, data_type, defatm, port_buffer_size);
+ port = new OutputPort(this, port_name, j, _polyphony, data_type, val, port_buffer_size);
if (direction == INPUT && data_type == DataType::CONTROL)
- ((AudioBuffer*)port->buffer(0))->set_value(def, 0, 0);
+ ((AudioBuffer*)port->buffer(0))->set_value(val.get_float(), 0, 0);
- SLV2Values contexts = slv2_port_get_value(plug, id, pred);
+ SLV2Values contexts = slv2_port_get_value(plug, id, context_pred);
for (uint32_t i = 0; i < slv2_values_size(contexts); ++i) {
SLV2Value c = slv2_values_get_at(contexts, i);
const char* context = slv2_value_as_string(c);
if (!strcmp("http://lv2plug.in/ns/dev/contexts#MessageContext", context)) {
- cout << "MESSAGE CONTEXT!" << endl;
+ cerr << _lv2_plugin->uri() << " port " << i << " has message context" << endl;
if (!_message_funcs) {
- cerr << "Plugin " << _lv2_plugin->uri()
+ cerr << _lv2_plugin->uri()
<< " has a message port, but no context extension data." << endl;
}
port->set_context(Context::MESSAGE);
} else {
- cout << "UNKNOWN CONTEXT: "
+ cout << _lv2_plugin->uri() << " port " << i << " has unknown context "
<< slv2_value_as_string(slv2_values_get_at(contexts, i))
<< endl;
}
diff --git a/src/engine/PortImpl.cpp b/src/engine/PortImpl.cpp
index 05fcfe67..7559ae02 100644
--- a/src/engine/PortImpl.cpp
+++ b/src/engine/PortImpl.cpp
@@ -18,14 +18,15 @@
#include <iostream>
#include "raul/Array.hpp"
#include "raul/Maid.hpp"
-#include "PortImpl.hpp"
-#include "NodeImpl.hpp"
#include "interface/DataType.hpp"
+#include "events/SendPortValue.hpp"
+#include "events/SendPortActivity.hpp"
#include "AudioBuffer.hpp"
#include "EventBuffer.hpp"
+#include "NodeImpl.hpp"
+#include "PortImpl.hpp"
#include "ProcessContext.hpp"
-#include "events/SendPortValue.hpp"
-#include "events/SendPortActivity.hpp"
+#include "StringBuffer.hpp"
using namespace std;
using namespace Raul;
@@ -177,19 +178,13 @@ PortImpl::clear_buffers()
void
PortImpl::broadcast_value(ProcessContext& context, bool force)
{
+ Raul::Atom val;
switch (_type.symbol()) {
case DataType::UNKNOWN:
break;
case DataType::AUDIO:
case DataType::CONTROL:
- {
- const Sample val = ((AudioBuffer*)buffer(0))->value_at(0);
- if (force || val != _last_broadcasted_value) {
- _last_broadcasted_value = val;
- const Events::SendPortValue ev(context.engine(), context.start(), this, false, 0, val);
- context.event_sink().write(sizeof(ev), &ev);
- }
- }
+ val = ((AudioBuffer*)buffer(0))->value_at(0);
break;
case DataType::EVENT:
if (((EventBuffer*)buffer(0))->event_count() > 0) {
@@ -197,7 +192,17 @@ PortImpl::broadcast_value(ProcessContext& context, bool force)
context.event_sink().write(sizeof(ev), &ev);
}
break;
+ case DataType::STRING:
+ val = Raul::Atom(((StringBuffer*)buffer(0))->data());
+ break;
}
+
+ if (val.type() == Atom::FLOAT && (force || val != _last_broadcasted_value)) {
+ _last_broadcasted_value = val;
+ const Events::SendPortValue ev(context.engine(), context.start(), this, false, 0, val);
+ context.event_sink().write(sizeof(ev), &ev);
+ }
+
}
diff --git a/src/engine/PortImpl.hpp b/src/engine/PortImpl.hpp
index 986e8233..7d587165 100644
--- a/src/engine/PortImpl.hpp
+++ b/src/engine/PortImpl.hpp
@@ -139,7 +139,7 @@ protected:
bool _fixed_buffers;
bool _broadcast;
bool _set_by_user;
- Sample _last_broadcasted_value;
+ Raul::Atom _last_broadcasted_value;
Context::ID _context;
Raul::Array<Buffer*>* _buffers;
diff --git a/src/engine/StringBuffer.cpp b/src/engine/StringBuffer.cpp
new file mode 100644
index 00000000..a6cec9f1
--- /dev/null
+++ b/src/engine/StringBuffer.cpp
@@ -0,0 +1,121 @@
+/* This file is part of Ingen.
+ * Copyright (C) 2009 Dave Robillard <http://drobilla.net>
+ *
+ * Ingen is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define __STDC_LIMIT_MACROS 1
+#include <string.h>
+#include <stdint.h>
+#include <iostream>
+#include "ingen-config.h"
+#include "StringBuffer.hpp"
+
+using namespace std;
+
+namespace Ingen {
+
+using namespace Shared;
+
+/** Allocate a new string buffer.
+ * \a capacity is in bytes.
+ */
+StringBuffer::StringBuffer(size_t capacity)
+ : Buffer(DataType(DataType::EVENT), capacity)
+{
+ memset(&_local_buf, '\0', sizeof(LV2_String_Data));
+ _local_buf.data = (char*)malloc(capacity);
+ _local_buf.storage = capacity;
+
+ _buf = &_local_buf;
+ clear();
+
+ cerr << "Creating String Buffer " << _buf << ", capacity = " << capacity << endl;
+}
+
+
+void
+StringBuffer::clear()
+{
+ static const string default_val("2\n0 1\n1 1\n");
+ if (_buf && _buf->data && _buf->storage > default_val.length())
+ strncpy(_buf->data, default_val.c_str(), default_val.length());
+}
+
+
+/** Use another buffer's data instead of the local one.
+ *
+ * This buffer will essentially be identical to @a buf after this call.
+ */
+bool
+StringBuffer::join(Buffer* buf)
+{
+ assert(buf != this);
+ StringBuffer* sbuf = dynamic_cast<StringBuffer*>(buf);
+ if (!sbuf)
+ return false;
+
+ _buf = &sbuf->_local_buf;
+ _joined_buf = sbuf;
+
+ return true;
+}
+
+
+void
+StringBuffer::unjoin()
+{
+ _joined_buf = NULL;
+ _buf = &_local_buf;
+}
+
+
+void
+StringBuffer::prepare_read(FrameTime start, SampleCount nframes)
+{
+ _this_nframes = nframes;
+}
+
+
+void
+StringBuffer::prepare_write(FrameTime start, SampleCount nframes)
+{
+}
+
+
+void
+StringBuffer::copy(const Buffer* src_buf, size_t start_sample, size_t end_sample)
+{
+ const StringBuffer* src = dynamic_cast<const StringBuffer*>(src_buf);
+ assert(src);
+ assert(src != this);
+ assert(src->_buf != _buf);
+ assert(src->_buf->data != _buf->data);
+
+ strncpy(_buf->data, src->_buf->data, std::min(_buf->len, src->_buf->len));
+ _this_nframes = end_sample - start_sample;
+}
+
+
+void
+StringBuffer::resize(size_t size)
+{
+ _buf->data = (char*)realloc(_buf->data, size);
+ _buf->storage = size;
+ _size = size;
+}
+
+
+} // namespace Ingen
+
diff --git a/src/engine/StringBuffer.hpp b/src/engine/StringBuffer.hpp
new file mode 100644
index 00000000..79d83f7a
--- /dev/null
+++ b/src/engine/StringBuffer.hpp
@@ -0,0 +1,59 @@
+/* This file is part of Ingen.
+ * Copyright (C) 2009 Dave Robillard <http://drobilla.net>
+ *
+ * Ingen is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * Ingen is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef STRINGBUFFER_H
+#define STRINGBUFFER_H
+
+#include "string-port.lv2/string-port.h"
+#include "interface/DataType.hpp"
+#include "Buffer.hpp"
+
+namespace Ingen {
+
+
+class StringBuffer : public Buffer {
+public:
+ StringBuffer(size_t capacity);
+
+ void clear();
+
+ void* raw_data() { return (void*)&_buf; }
+ const void* raw_data() const { return (void*)&_buf; }
+
+ char* data() { return _buf->data; }
+ const char* data() const { return _buf->data; }
+
+ void prepare_read(FrameTime start, SampleCount nframes);
+ void prepare_write(FrameTime start, SampleCount nframes);
+
+ bool join(Buffer* buf);
+ void unjoin();
+
+ void copy(const Buffer* src, size_t start_sample, size_t end_sample);
+
+ void resize(size_t size);
+
+private:
+ LV2_String_Data* _buf; ///< Contents (_local_buf or belongs to _joined_buf)
+ LV2_String_Data _local_buf; ///< Local contents
+ uint32_t _this_nframes; ///< Current cycle nframes
+};
+
+
+} // namespace Ingen
+
+#endif // STRINGBUFFER_H
diff --git a/src/engine/events/RequestMetadata.cpp b/src/engine/events/RequestMetadata.cpp
index 145260ef..e633ca10 100644
--- a/src/engine/events/RequestMetadata.cpp
+++ b/src/engine/events/RequestMetadata.cpp
@@ -25,6 +25,7 @@
#include "PortImpl.hpp"
#include "PluginImpl.hpp"
#include "AudioBuffer.hpp"
+#include "StringBuffer.hpp"
using namespace std;
using namespace Raul;
@@ -36,11 +37,11 @@ using namespace Shared;
RequestMetadata::RequestMetadata(Engine& engine,
- SharedPtr<Responder> responder,
- SampleCount timestamp,
- bool is_meta,
- const URI& subject,
- const URI& key)
+ SharedPtr<Responder> responder,
+ SampleCount timestamp,
+ bool is_meta,
+ const URI& subject,
+ const URI& key)
: QueuedEvent(engine, responder, timestamp)
, _error(NO_ERROR)
, _special_type(NONE)
@@ -93,6 +94,8 @@ RequestMetadata::execute(ProcessContext& context)
if (port) {
if (port->type() == DataType::CONTROL || port->type() == DataType::AUDIO)
_value = ((AudioBuffer*)port->buffer(0))->value_at(0); // TODO: offset
+ else if (port->type() == DataType::STRING)
+ _value = (char*)((StringBuffer*)port->buffer(0))->data();
} else {
_resource = 0;
}
diff --git a/src/engine/events/RequestMetadata.hpp b/src/engine/events/RequestMetadata.hpp
index ba860aaf..0777c79a 100644
--- a/src/engine/events/RequestMetadata.hpp
+++ b/src/engine/events/RequestMetadata.hpp
@@ -45,11 +45,11 @@ class RequestMetadata : public QueuedEvent
{
public:
RequestMetadata(Engine& engine,
- SharedPtr<Responder> responder,
- SampleCount timestamp,
- bool meta,
- const Raul::URI& subject,
- const Raul::URI& key);
+ SharedPtr<Responder> responder,
+ SampleCount timestamp,
+ bool meta,
+ const Raul::URI& subject,
+ const Raul::URI& key);
void pre_process();
void execute(ProcessContext& context);
diff --git a/src/engine/events/SendPortValue.hpp b/src/engine/events/SendPortValue.hpp
index d3ac61f7..b942398c 100644
--- a/src/engine/events/SendPortValue.hpp
+++ b/src/engine/events/SendPortValue.hpp
@@ -18,6 +18,7 @@
#ifndef SENDPORTVALUEEVENT_H
#define SENDPORTVALUEEVENT_H
+#include "raul/Atom.hpp"
#include "engine/Event.hpp"
#include "engine/types.hpp"
@@ -43,12 +44,12 @@ class SendPortValue : public Event
{
public:
inline SendPortValue(
- Engine& engine,
- SampleCount timestamp,
- PortImpl* port,
- bool omni,
- uint32_t voice_num,
- Sample value)
+ Engine& engine,
+ SampleCount timestamp,
+ PortImpl* port,
+ bool omni,
+ uint32_t voice_num,
+ const Raul::Atom& value)
: Event(engine, SharedPtr<Responder>(), timestamp)
, _port(port)
, _omni(omni)
@@ -67,10 +68,10 @@ public:
void post_process();
private:
- PortImpl* _port;
- bool _omni;
- uint32_t _voice_num;
- Sample _value;
+ PortImpl* _port;
+ bool _omni;
+ uint32_t _voice_num;
+ Raul::Atom _value;
};
diff --git a/src/engine/events/SetPortValue.cpp b/src/engine/events/SetPortValue.cpp
index eacf172b..1964880d 100644
--- a/src/engine/events/SetPortValue.cpp
+++ b/src/engine/events/SetPortValue.cpp
@@ -31,6 +31,7 @@
#include "ProcessContext.hpp"
#include "Responder.hpp"
#include "SetPortValue.hpp"
+#include "StringBuffer.hpp"
using namespace std;
using namespace Raul;
@@ -169,21 +170,18 @@ SetPortValue::apply(uint32_t start, uint32_t nframes)
return;
}
- EventBuffer* const ebuf = dynamic_cast<EventBuffer*>(buf);
-
const LV2Features::Feature* f = _engine.world()->lv2_features->feature(LV2_URI_MAP_URI);
LV2URIMap* map = (LV2URIMap*)f->controller;
- // FIXME: eliminate lookups
- // FIXME: need a proper prefix system
- if (ebuf && _value.type() == Atom::BLOB) {
+ // TODO: eliminate lookups
+ EventBuffer* const ebuf = dynamic_cast<EventBuffer*>(buf);
+ if (ebuf) {
const uint32_t frames = std::max(
- (uint32_t)(_time - start),
+ uint32_t(_time - start),
ebuf->latest_frames());
// Size 0 event, pass it along to the plugin as a typed but empty event
if (_value.data_size() == 0) {
- cout << "BANG!" << endl;
const uint32_t type_id = map->uri_to_id(NULL, _value.get_blob_type());
ebuf->append(frames, 0, type_id, 0, NULL);
_port->raise_set_by_user_flag();
@@ -202,6 +200,18 @@ SetPortValue::apply(uint32_t start, uint32_t nframes)
}
}
+ StringBuffer* const sbuf = dynamic_cast<StringBuffer*>(buf);
+ if (sbuf) {
+ if (_value.type() != Atom::STRING) {
+ _error = TYPE_MISMATCH;
+ return;
+ }
+ strncpy(sbuf->data(), _value.get_string(),
+ std::min(sbuf->size(), strlen(_value.get_string())));
+ return;
+ }
+
+
if (_value.type() == Atom::BLOB)
cerr << "WARNING: Unknown value blob type " << _value.get_blob_type() << endl;
else
diff --git a/src/engine/internals/Note.cpp b/src/engine/internals/Note.cpp
index 4b42807b..1a7d3f5e 100644
--- a/src/engine/internals/Note.cpp
+++ b/src/engine/internals/Note.cpp
@@ -131,7 +131,8 @@ NoteNode::process(ProcessContext& context)
midi_in->rewind();
if (midi_in->event_count() > 0)
- while (midi_in->get_event(&frames, &subframes, &type, &size, &buf)) {
+ for (midi_in->rewind(); midi_in->get_event(&frames, &subframes, &type, &size, &buf);
+ midi_in->increment()) {
/*cout << "EVENT TYPE " << type << " @ " << frames << "." << subframes << ": ";
for (uint16_t i = 0; i < size; ++i)
@@ -178,9 +179,6 @@ NoteNode::process(ProcessContext& context)
} else {
//fprintf(stderr, "Unknown (size %d) MIDI event %X\n", size, buf[0]);
}
-
- if (midi_in->increment() == midi_in->this_nframes())
- break;
}
NodeBase::post_process(context);
diff --git a/src/engine/wscript b/src/engine/wscript
index b4d0dc7a..0b3888f0 100644
--- a/src/engine/wscript
+++ b/src/engine/wscript
@@ -28,6 +28,7 @@ def build(bld):
PostProcessor.cpp
ProcessSlave.cpp
QueuedEvent.cpp
+ StringBuffer.cpp
events/SendPortActivity.cpp
events/SendPortValue.cpp
ingen_engine.cpp