summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--src/client/PluginUI.cpp9
-rw-r--r--src/common/interface/DataType.hpp15
l---------src/common/string-port.lv21
-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
-rw-r--r--src/gui/Configuration.cpp7
-rw-r--r--src/gui/Configuration.hpp1
-rw-r--r--src/gui/ControlPanel.cpp22
-rw-r--r--src/gui/ControlPanel.hpp7
-rw-r--r--src/gui/Controls.cpp80
-rw-r--r--src/gui/Controls.hpp25
-rw-r--r--src/gui/NodeModule.cpp23
-rw-r--r--src/gui/PortMenu.cpp2
-rw-r--r--src/gui/ingen_gui.glade63
-rw-r--r--src/ingen/main.cpp29
-rw-r--r--src/serialisation/Serialiser.cpp2
-rw-r--r--src/shared/ResourceImpl.cpp3
33 files changed, 559 insertions, 123 deletions
diff --git a/src/client/PluginUI.cpp b/src/client/PluginUI.cpp
index 405dd099..3007e723 100644
--- a/src/client/PluginUI.cpp
+++ b/src/client/PluginUI.cpp
@@ -17,6 +17,7 @@
#include <iostream>
#include "event.lv2/event-helpers.h"
+#include "string-port.lv2/string-port.h"
#include "shared/LV2Features.hpp"
#include "shared/LV2URIMap.hpp"
#include "PluginUI.hpp"
@@ -67,7 +68,7 @@ lv2_ui_write(LV2UI_Controller controller,
ui->world()->engine->set_port_value(port->path(), Atom(*(float*)buffer));
- // FIXME: slow, need to cache ID
+ // FIXME: this is slow, cache ID
} else if (format == map->uri_to_id(NULL, "http://lv2plug.in/ns/extensions/ui#Events")) {
uint32_t midi_event_type = map->uri_to_id(NULL, "http://lv2plug.in/ns/ext/midi#MidiEvent");
LV2_Event_Buffer* buf = (LV2_Event_Buffer*)buffer;
@@ -87,6 +88,12 @@ lv2_ui_write(LV2UI_Controller controller,
lv2_event_increment(&iter);
}
+
+ // FIXME: this is slow, cache ID
+ } else if (format == map->uri_to_id(NULL, "http://lv2plug.in/ns/dev/string-port#StringTransfer")) {
+ LV2_String_Data* buf = (LV2_String_Data*)buffer;
+ ui->world()->engine->set_port_value(port->path(), buf->data);
+
} else {
cerr << "WARNING: Unknown value format " << format
<< ", either plugin " << ui->node()->plugin()->uri() << " is broken"
diff --git a/src/common/interface/DataType.hpp b/src/common/interface/DataType.hpp
index aae7f52a..4590a9a1 100644
--- a/src/common/interface/DataType.hpp
+++ b/src/common/interface/DataType.hpp
@@ -39,7 +39,10 @@ public:
UNKNOWN = 0,
AUDIO = 1,
CONTROL = 2,
- EVENT = 3
+ EVENT = 3,
+ //MIDI = 4,
+ //OSC = 5,
+ STRING = 6
};
DataType(const Raul::URI& uri)
@@ -49,8 +52,10 @@ public:
_symbol = AUDIO;
} else if (uri.str() == type_uri(CONTROL)) {
_symbol = CONTROL;
- } else if (uri.str() == type_uri(EVENT) || uri.str() == "lv2ev:EventPort") {
+ } else if (uri.str() == type_uri(EVENT)) {
_symbol = EVENT;
+ } else if (uri.str() == type_uri(STRING)) {
+ _symbol = STRING;
}
}
@@ -69,6 +74,7 @@ public:
inline bool is_audio() { return _symbol == AUDIO; }
inline bool is_control() { return _symbol == CONTROL; }
inline bool is_event() { return _symbol == EVENT; }
+ inline bool is_string() { return _symbol == STRING; }
private:
@@ -77,8 +83,9 @@ private:
case 1: return "lv2:AudioPort";
case 2: return "lv2:ControlPort";
case 3: return "lv2ev:EventPort";
- case 4: return "lv2ev:EventPort"; // MIDI
- case 5: return "lv2ev:EventPort"; // OSC
+ case 4: return "lv2ev:EventPort"; // MIDI (no longer used)
+ case 5: return "lv2ev:EventPort"; // OSC (no longer used)
+ case 6: return "sp:StringPort";
default: return "";
}
}
diff --git a/src/common/string-port.lv2 b/src/common/string-port.lv2
new file mode 120000
index 00000000..3615878f
--- /dev/null
+++ b/src/common/string-port.lv2
@@ -0,0 +1 @@
+../../../lv2/dev/string-port.lv2 \ No newline at end of file
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
diff --git a/src/gui/Configuration.cpp b/src/gui/Configuration.cpp
index de0a0e94..c7a5b19c 100644
--- a/src/gui/Configuration.cpp
+++ b/src/gui/Configuration.cpp
@@ -41,6 +41,7 @@ Configuration::Configuration()
, _control_port_color(0x4A8A0EC0)
, _event_port_color( 0x960909C0)
// , _osc_port_color( 0x5C3566C0)
+ , _string_port_color( 0x00000000)
{
}
@@ -91,9 +92,11 @@ Configuration::get_port_color(const PortModel* p)
return _audio_port_color;
} else if (p->type().is_event()) {
return _event_port_color;
- } /*else if (p->type().is_osc()) {
+ /*} else if (p->type().is_osc()) {
return _osc_port_color;
- }*/
+ */} else if (p->type().is_string()) {
+ return _string_port_color;
+ }
cerr << "[Configuration] Unknown port type " << p->type().uri()
<< ", port will appear black." << endl;
diff --git a/src/gui/Configuration.hpp b/src/gui/Configuration.hpp
index b3d64ff8..480ed6d1 100644
--- a/src/gui/Configuration.hpp
+++ b/src/gui/Configuration.hpp
@@ -68,6 +68,7 @@ private:
uint32_t _audio_port_color;
uint32_t _control_port_color;
uint32_t _event_port_color;
+ uint32_t _string_port_color;
};
diff --git a/src/gui/ControlPanel.cpp b/src/gui/ControlPanel.cpp
index 99b66899..1e7d177b 100644
--- a/src/gui/ControlPanel.cpp
+++ b/src/gui/ControlPanel.cpp
@@ -111,22 +111,29 @@ ControlPanel::add_port(SharedPtr<PortModel> pm)
if (find_port(pm->path()) != NULL)
return;
- // Add port
- if (pm->type().is_control() && pm->is_input()) {
- Control* control = NULL;
+ Control* control = NULL;
- if (pm->is_toggle()) {
+ // Add port
+ if (pm->is_input()) {
+ if (pm->type().is_control() && pm->is_toggle()) {
ToggleControl* tc;
Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("toggle_control");
xml->get_widget_derived("toggle_control", tc);
control = tc;
+ } else if (pm->type().is_string()) {
+ StringControl* sc;
+ Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("string_control");
+ xml->get_widget_derived("string_control", sc);
+ control = sc;
} else {
SliderControl* sc;
Glib::RefPtr<Gnome::Glade::Xml> xml = GladeFactory::new_glade_reference("control_strip");
xml->get_widget_derived("control_strip", sc);
control = sc;
}
+ }
+ if (control) {
control->init(this, pm);
if (_controls.size() > 0)
@@ -223,20 +230,21 @@ ControlPanel::disable_port(const Path& path)
/** Callback for Controls to notify this of a change.
*/
void
-ControlPanel::value_changed(SharedPtr<PortModel> port, float val)
+ControlPanel::value_changed_atom(SharedPtr<PortModel> port, const Raul::Atom& val)
{
if (_callback_enabled) {
if (_all_voices_radio->get_active()) {
- App::instance().engine()->set_port_value(port->path(), Atom(val));
+ App::instance().engine()->set_port_value(port->path(), val);
port->value(val);
} else {
int voice = _voice_spinbutton->get_value_as_int();
- App::instance().engine()->set_voice_value(port->path(), voice, Atom(val));
+ App::instance().engine()->set_voice_value(port->path(), voice, val);
port->value(val);
}
}
}
+
void
ControlPanel::all_voices_selected()
{
diff --git a/src/gui/ControlPanel.hpp b/src/gui/ControlPanel.hpp
index 146173dd..375c0a72 100644
--- a/src/gui/ControlPanel.hpp
+++ b/src/gui/ControlPanel.hpp
@@ -66,7 +66,12 @@ public:
std::pair<int,int> ideal_size() const { return _ideal_size; }
// Callback for Control
- void value_changed(SharedPtr<PortModel> port_path, float val);
+ void value_changed_atom(SharedPtr<PortModel> port, const Raul::Atom& val);
+
+ template <typename T>
+ void value_changed(SharedPtr<PortModel> port, T val) {
+ this->value_changed_atom(port, Raul::Atom(val));
+ }
private:
void all_voices_selected();
diff --git a/src/gui/Controls.cpp b/src/gui/Controls.cpp
index a6a2ead3..39c18a88 100644
--- a/src/gui/Controls.cpp
+++ b/src/gui/Controls.cpp
@@ -279,7 +279,6 @@ SliderControl::update_value_from_spinner()
_control_panel->value_changed(_port_model, value);
- //m_port_model->value(value);
_enable_signal = true;
}
}
@@ -469,5 +468,84 @@ ToggleControl::toggled()
}
+// ///////////// StringControl ////////////// //
+
+
+StringControl::StringControl(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml)
+ : Control(cobject, xml)
+{
+ xml->get_widget("string_control_name_label", _name_label);
+ xml->get_widget("string_control_entry", _entry);
+}
+
+
+void
+StringControl::init(ControlPanel* panel, SharedPtr<PortModel> pm)
+{
+ _enable_signal = false;
+
+ Control::init(panel, pm);
+
+ assert(_name_label);
+ assert(_entry);
+
+ set_name(pm->path().name());
+
+ _entry->signal_activate().connect(sigc::mem_fun(*this, &StringControl::activated));
+ set_value(pm->value());
+
+ _enable_signal = true;
+ show_all();
+}
+
+
+void
+StringControl::set_name(const string& name)
+{
+ string name_label = "<span weight=\"bold\">";
+ name_label += name + "</span>";
+ _name_label->set_markup(name_label);
+}
+
+
+void
+StringControl::set_value(const Atom& val)
+{
+ _enable_signal = false;
+ if (val.type() == Atom::STRING)
+ _entry->set_text(val.get_string());
+ else
+ cerr << "ERROR: Non-string value for string port" << endl;
+ _enable_signal = true;
+}
+
+
+void
+StringControl::enable()
+{
+ _entry->property_sensitive() = true;
+ _name_label->property_sensitive() = true;
+}
+
+
+void
+StringControl::disable()
+{
+ _entry->property_sensitive() = false;
+ _name_label->property_sensitive() = false;
+}
+
+
+void
+StringControl::activated()
+{
+ if (_enable_signal) {
+ const string& value = _entry->get_text();
+ cerr << "String control activated: " << value << endl;
+ _control_panel->value_changed(_port_model, value.c_str());
+ }
+}
+
+
} // namespace GUI
} // namespace Ingen
diff --git a/src/gui/Controls.hpp b/src/gui/Controls.hpp
index 9a6a13f5..0f0dbd79 100644
--- a/src/gui/Controls.hpp
+++ b/src/gui/Controls.hpp
@@ -157,6 +157,31 @@ private:
};
+/** A text entry for string controls.
+ *
+ * \ingroup GUI
+ */
+class StringControl : public Control
+{
+public:
+ StringControl(BaseObjectType* cobject, const Glib::RefPtr<Gnome::Glade::Xml>& xml);
+
+ void init(ControlPanel* panel, SharedPtr<Client::PortModel> pm);
+
+ void enable();
+ void disable();
+
+private:
+ void set_name(const std::string& name);
+ void set_value(const Raul::Atom& value);
+
+ void activated();
+
+ Gtk::Label* _name_label;
+ Gtk::Entry* _entry;
+};
+
+
} // namespace GUI
} // namespace Ingen
diff --git a/src/gui/NodeModule.cpp b/src/gui/NodeModule.cpp
index fbc89fc3..4df32263 100644
--- a/src/gui/NodeModule.cpp
+++ b/src/gui/NodeModule.cpp
@@ -144,20 +144,23 @@ NodeModule::show_human_names(bool b)
void
NodeModule::value_changed(uint32_t index, const Atom& value)
{
- float control = 0.0f;
+ if (!_plugin_ui)
+ return;
+
+ float float_val = 0.0f;
+ SLV2UIInstance inst = _plugin_ui->instance();
+ const LV2UI_Descriptor* ui_desc = slv2_ui_instance_get_descriptor(inst);
+ LV2UI_Handle ui = slv2_ui_instance_get_handle(inst);
+
switch (value.type()) {
case Atom::FLOAT:
- control = value.get_float();
- if (_plugin_ui) {
- SLV2UIInstance inst = _plugin_ui->instance();
- const LV2UI_Descriptor* ui_descriptor = slv2_ui_instance_get_descriptor(inst);
- LV2UI_Handle ui_handle = slv2_ui_instance_get_handle(inst);
- if (ui_descriptor->port_event)
- ui_descriptor->port_event(ui_handle, index, 4, 0, &control);
- }
+ float_val = value.get_float();
+ if (ui_desc->port_event)
+ ui_desc->port_event(ui, index, 4, 0, &float_val);
break;
case Atom::STRING:
- cout << "Port value type is a string? (\"" << value.get_string() << "\")" << endl;
+ if (ui_desc->port_event)
+ ui_desc->port_event(ui, index, strlen(value.get_string()), 0, value.get_string());
break;
default:
break;
diff --git a/src/gui/PortMenu.cpp b/src/gui/PortMenu.cpp
index 834d1a32..c6229361 100644
--- a/src/gui/PortMenu.cpp
+++ b/src/gui/PortMenu.cpp
@@ -48,7 +48,7 @@ PortMenu::init(SharedPtr<PortModel> port, bool patch_port)
_destroy_menuitem->hide();
}
- if (port->type() == DataType::EVENT)
+ if (port->type() == DataType::EVENT || port->type() == DataType::STRING)
_polyphonic_menuitem->hide();
_enable_signal = true;
diff --git a/src/gui/ingen_gui.glade b/src/gui/ingen_gui.glade
index d1054c7e..371c7bd0 100644
--- a/src/gui/ingen_gui.glade
+++ b/src/gui/ingen_gui.glade
@@ -1230,7 +1230,7 @@
<child>
<widget class="GtkTable" id="table8">
<property name="visible">True</property>
- <property name="n_rows">5</property>
+ <property name="n_rows">6</property>
<property name="n_columns">2</property>
<child>
<widget class="GtkVBox" id="toggle_control">
@@ -1244,7 +1244,6 @@
<widget class="GtkLabel" id="toggle_control_name_label">
<property name="visible">True</property>
<property name="xalign">0</property>
- <property name="yalign">1</property>
<property name="xpad">4</property>
<property name="label" translatable="yes">&lt;b&gt;Name&lt;/b&gt;</property>
<property name="use_markup">True</property>
@@ -1715,6 +1714,66 @@
</packing>
</child>
<child>
+ <widget class="GtkVBox" id="string_control">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <widget class="GtkHBox" id="hbox3">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <child>
+ <widget class="GtkLabel" id="string_control_name_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="xpad">4</property>
+ <property name="label" translatable="yes">&lt;b&gt;Name&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="single_line_mode">True</property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="scrolledwindow1">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+ <widget class="GtkEntry" id="string_control_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">&#x25CF;</property>
+ <property name="caps_lock_warning">False</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ <property name="y_padding">8</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
<placeholder/>
</child>
<child>
diff --git a/src/ingen/main.cpp b/src/ingen/main.cpp
index caf65e78..3fa1c7ce 100644
--- a/src/ingen/main.cpp
+++ b/src/ingen/main.cpp
@@ -109,16 +109,17 @@ main(int argc, char** argv)
Ingen::Shared::World* world = Ingen::Shared::get_world();
/* Set up RDF world */
- world->rdf_world->add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#");
- world->rdf_world->add_prefix("ingen", "http://drobilla.net/ns/ingen#");
+ world->rdf_world->add_prefix("dc", "http://purl.org/dc/elements/1.1/");
+ world->rdf_world->add_prefix("doap", "http://usefulinc.com/ns/doap#");
+ world->rdf_world->add_prefix("ingen", "http://drobilla.net/ns/ingen#");
world->rdf_world->add_prefix("ingenuity", "http://drobilla.net/ns/ingenuity#");
- world->rdf_world->add_prefix("lv2", "http://lv2plug.in/ns/lv2core#");
- world->rdf_world->add_prefix("lv2ev", "http://lv2plug.in/ns/ext/event#");
- world->rdf_world->add_prefix("lv2midi", "http://lv2plug.in/ns/ext/midi");
- world->rdf_world->add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
- world->rdf_world->add_prefix("owl", "http://www.w3.org/2002/07/owl#");
- world->rdf_world->add_prefix("doap", "http://usefulinc.com/ns/doap#");
- world->rdf_world->add_prefix("dc", "http://purl.org/dc/elements/1.1/");
+ world->rdf_world->add_prefix("lv2", "http://lv2plug.in/ns/lv2core#");
+ world->rdf_world->add_prefix("lv2ev", "http://lv2plug.in/ns/ext/event#");
+ world->rdf_world->add_prefix("lv2midi", "http://lv2plug.in/ns/ext/midi");
+ world->rdf_world->add_prefix("owl", "http://www.w3.org/2002/07/owl#");
+ world->rdf_world->add_prefix("rdfs", "http://www.w3.org/2000/01/rdf-schema#");
+ world->rdf_world->add_prefix("sp", "http://lv2plug.in/ns/dev/string-port#");
+ world->rdf_world->add_prefix("xsd", "http://www.w3.org/2001/XMLSchema#");
/* Run engine */
if (args.engine_flag) {
@@ -298,10 +299,10 @@ main(int argc, char** argv)
if (run_gui)
gui_run();
- /* Run a script */
- if (args.run_given) {
+ /* Run a script */
+ if (args.run_given) {
#ifdef WITH_BINDINGS
- bool (*run_script)(Ingen::Shared::World*, const char*) = NULL;
+ bool (*run_script)(Ingen::Shared::World*, const char*) = NULL;
SharedPtr<Glib::Module> bindings_module = Ingen::Shared::load_module("ingen_bindings");
if (bindings_module) {
bindings_module->make_resident();
@@ -314,14 +315,14 @@ main(int argc, char** argv)
cerr << "FAILED: " << Glib::Module::get_last_error() << endl;
}
} else {
- cerr << Glib::Module::get_last_error() << endl;
+ cerr << Glib::Module::get_last_error() << endl;
}
#else
cerr << "This build of ingen does not support scripting." << endl;
#endif
/* Listen to OSC and do our own main thing. */
- } else if (engine && !run_gui) {
+ } else if (engine && !run_gui) {
signal(SIGINT, catch_int);
signal(SIGTERM, catch_int);
engine->main();
diff --git a/src/serialisation/Serialiser.cpp b/src/serialisation/Serialiser.cpp
index a2e92454..d3583124 100644
--- a/src/serialisation/Serialiser.cpp
+++ b/src/serialisation/Serialiser.cpp
@@ -496,8 +496,6 @@ Serialiser::serialise_properties(
const Redland::Resource key(_model->world(), v->first.str());
const Redland::Node value = AtomRDF::atom_to_node(_model->world(), v->second);
if (value.is_valid()) {
- cerr << "serialise property '" << v->first << "' = " << value << " :: "
- << (int)v->second.type() << endl;
_model->add_statement(subject, key, value);
} else {
cerr << "WARNING: can not serialise variable '" << v->first << "' :: "
diff --git a/src/shared/ResourceImpl.cpp b/src/shared/ResourceImpl.cpp
index e35bb7ad..b4b40116 100644
--- a/src/shared/ResourceImpl.cpp
+++ b/src/shared/ResourceImpl.cpp
@@ -112,6 +112,9 @@ ResourceImpl::type(
} else if (!strcmp(atom.get_uri(), "lv2ev:EventPort")) {
data_type = DataType::EVENT;
port = true;
+ } else if (!strcmp(atom.get_uri(), "sp:StringPort")) {
+ data_type = DataType::STRING;
+ port = true;
}
}
}