summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/AudioBuffer.cpp37
-rw-r--r--src/server/AudioBuffer.hpp15
-rw-r--r--src/server/Buffer.cpp164
-rw-r--r--src/server/Buffer.hpp46
-rw-r--r--src/server/BufferFactory.cpp77
-rw-r--r--src/server/BufferFactory.hpp35
-rw-r--r--src/server/ConnectionImpl.cpp56
-rw-r--r--src/server/ControlBindings.cpp110
-rw-r--r--src/server/ControlBindings.hpp9
-rw-r--r--src/server/DuplexPort.cpp9
-rw-r--r--src/server/DuplexPort.hpp1
-rw-r--r--src/server/Engine.cpp17
-rw-r--r--src/server/EventBuffer.cpp217
-rw-r--r--src/server/EventBuffer.hpp86
-rw-r--r--src/server/InputPort.cpp10
-rw-r--r--src/server/InputPort.hpp1
-rw-r--r--src/server/JackDriver.cpp64
-rw-r--r--src/server/LV2Info.cpp2
-rw-r--r--src/server/LV2Info.hpp1
-rw-r--r--src/server/LV2Node.cpp64
-rw-r--r--src/server/NodeImpl.cpp4
-rw-r--r--src/server/NodeImpl.hpp4
-rw-r--r--src/server/Notification.cpp2
-rw-r--r--src/server/ObjectBuffer.cpp151
-rw-r--r--src/server/ObjectBuffer.hpp56
-rw-r--r--src/server/OutputPort.cpp3
-rw-r--r--src/server/OutputPort.hpp1
-rw-r--r--src/server/PatchImpl.cpp9
-rw-r--r--src/server/PatchImpl.hpp7
-rw-r--r--src/server/PortImpl.cpp74
-rw-r--r--src/server/PortImpl.hpp5
-rw-r--r--src/server/PortType.hpp9
-rw-r--r--src/server/ServerInterfaceImpl.cpp2
-rw-r--r--src/server/ServerInterfaceImpl.hpp2
-rw-r--r--src/server/events/CreateNode.cpp2
-rw-r--r--src/server/events/CreatePort.cpp40
-rw-r--r--src/server/events/CreatePort.hpp9
-rw-r--r--src/server/events/SetMetadata.cpp14
-rw-r--r--src/server/events/SetPortValue.cpp45
-rw-r--r--src/server/ingen_jack.cpp7
-rw-r--r--src/server/ingen_lv2.cpp129
-rw-r--r--src/server/internals/Controller.cpp52
-rw-r--r--src/server/internals/Controller.hpp3
-rw-r--r--src/server/internals/Delay.cpp13
-rw-r--r--src/server/internals/Note.cpp75
-rw-r--r--src/server/internals/Trigger.cpp60
-rw-r--r--src/server/mix.hpp40
-rw-r--r--src/server/wscript3
48 files changed, 751 insertions, 1091 deletions
diff --git a/src/server/AudioBuffer.cpp b/src/server/AudioBuffer.cpp
index fc73f9d7..2b837d0b 100644
--- a/src/server/AudioBuffer.cpp
+++ b/src/server/AudioBuffer.cpp
@@ -35,46 +35,31 @@ using namespace Raul;
namespace Ingen {
namespace Server {
-AudioBuffer::AudioBuffer(BufferFactory& bufs, PortType type, size_t size)
- : ObjectBuffer(bufs, size)
+AudioBuffer::AudioBuffer(BufferFactory& bufs, LV2_URID type, uint32_t size)
+ : Buffer(bufs, type, size)
, _state(OK)
, _set_value(0)
, _set_time(0)
{
assert(size >= sizeof(LV2_Atom) + sizeof(Sample));
- assert(this->size() >= size);
+ assert(this->capacity() >= size);
assert(data());
- _type = type;
- // Control port / Single float object
- if (type == PortType::CONTROL) {
- atom()->type = 0;//map->float_type;
-
- // Audio port / Vector of float
- } else {
- assert(type == PortType::AUDIO || type == PortType::CV);
- atom()->type = 0;//map->vector_type;
+ if (type == bufs.uris().atom_Sound) {
+ // Audio port (Vector of float)
LV2_Atom_Vector* body = (LV2_Atom_Vector*)atom();
- body->body.child_size = sizeof(Sample);
- body->body.child_type = 0;//map->float_type;
+ body->body.child_size = sizeof(float);
+ body->body.child_type = bufs.uris().atom_Float;
}
- /*debug << "Created Audio Buffer" << endl
- << "\tobject @ " << (void*)atom() << endl
- << "\tbody @ " << (void*)atom()->body
- << "\t(offset " << (char*)atom()->body - (char*)atom() << ")" << endl
- << "\tdata @ " << (void*)data()
- << "\t(offset " << (char*)data() - (char*)atom() << ")"
- << endl;*/
+ _atom->type = type;
clear();
}
void
-AudioBuffer::resize(size_t size)
+AudioBuffer::resize(uint32_t size)
{
- if (_type == PortType::AUDIO) {
- ObjectBuffer::resize(size + sizeof(LV2_Atom_Vector));
- }
+ Buffer::resize(size);
clear();
}
@@ -164,7 +149,7 @@ AudioBuffer::copy(Context& context, const Buffer* src)
// Control => Control
if (src_abuf->is_control() == is_control()) {
- ObjectBuffer::copy(context, src);
+ Buffer::copy(context, src);
// Audio => Audio
} else if (!src_abuf->is_control() && !is_control()) {
diff --git a/src/server/AudioBuffer.hpp b/src/server/AudioBuffer.hpp
index 262b03c1..eda5c3a3 100644
--- a/src/server/AudioBuffer.hpp
+++ b/src/server/AudioBuffer.hpp
@@ -24,8 +24,11 @@
#include <boost/utility.hpp>
+#include "ingen/shared/URIs.hpp"
+
+#include "Buffer.hpp"
+#include "BufferFactory.hpp"
#include "Context.hpp"
-#include "ObjectBuffer.hpp"
#include "types.hpp"
using namespace std;
@@ -33,10 +36,10 @@ using namespace std;
namespace Ingen {
namespace Server {
-class AudioBuffer : public ObjectBuffer
+class AudioBuffer : public Buffer
{
public:
- AudioBuffer(BufferFactory& bufs, PortType type, size_t capacity);
+ AudioBuffer(BufferFactory& bufs, LV2_URID type, uint32_t size);
void clear();
@@ -48,7 +51,7 @@ public:
float peak(Context& context) const;
- inline bool is_control() const { return _type.symbol() == PortType::CONTROL; }
+ inline bool is_control() const { return _type == _factory.uris().atom_Float; }
inline Sample* data() const {
return (is_control())
@@ -59,7 +62,7 @@ public:
inline SampleCount nframes() const {
return (is_control())
? 1
- : (_size - sizeof(LV2_Atom_Vector)) / sizeof(Sample);
+ : (_capacity - sizeof(LV2_Atom_Vector)) / sizeof(Sample);
}
inline Sample& value_at(size_t offset) const
@@ -68,7 +71,7 @@ public:
void prepare_read(Context& context);
void prepare_write(Context& context) {}
- void resize(size_t size);
+ void resize(uint32_t size);
private:
enum State { OK, HALF_SET_CYCLE_1, HALF_SET_CYCLE_2 };
diff --git a/src/server/Buffer.cpp b/src/server/Buffer.cpp
new file mode 100644
index 00000000..a52b62eb
--- /dev/null
+++ b/src/server/Buffer.cpp
@@ -0,0 +1,164 @@
+/* This file is part of Ingen.
+ * Copyright 2009-2012 David 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 <stdint.h>
+#include <string.h>
+
+#include <algorithm>
+
+#include "ingen/shared/LV2Features.hpp"
+#include "ingen/shared/LV2URIMap.hpp"
+#include "ingen/shared/URIs.hpp"
+#include "ingen/shared/World.hpp"
+#include "ingen_config.h"
+#include "lv2/lv2plug.in/ns/ext/atom/util.h"
+#include "raul/log.hpp"
+
+#include "Buffer.hpp"
+#include "Engine.hpp"
+
+namespace Ingen {
+namespace Server {
+
+Buffer::Buffer(BufferFactory& bufs, LV2_URID type, uint32_t capacity)
+ : _factory(bufs)
+ , _type(type)
+ , _capacity(capacity)
+ , _next(NULL)
+ , _refs(0)
+{
+ if (capacity > UINT32_MAX) {
+ Raul::error << "Event buffer size " << capacity << " too large, aborting."
+ << std::endl;
+ throw std::bad_alloc();
+ }
+
+#ifdef HAVE_POSIX_MEMALIGN
+ int ret = posix_memalign((void**)&_atom, 16, capacity);
+#else
+ _atom = (LV2_Atom_Sequence*)malloc(capacity);
+ int ret = (_atom != NULL) ? 0 : -1;
+#endif
+
+ if (ret != 0) {
+ Raul::error << "Failed to allocate event buffer." << std::endl;
+ throw std::bad_alloc();
+ }
+
+ memset(_atom, 0, capacity);
+ _atom->type = type;
+ assert(_atom->type != 1);
+
+ clear();
+}
+
+Buffer::~Buffer()
+{
+ free(_atom);
+}
+
+void
+Buffer::clear()
+{
+ _atom->size = 0;
+}
+
+void
+Buffer::copy(Context& context, const Buffer* src)
+{
+ // Copy only if src is a POD object that fits
+ if (src->_atom->type != 0 && sizeof(LV2_Atom) + src->_atom->size <= capacity()) {
+ memcpy(_atom, src->_atom, sizeof(LV2_Atom) + src->_atom->size);
+ }
+ assert(_atom->type != 1);
+}
+
+void
+Buffer::resize(uint32_t capacity)
+{
+ _atom = (LV2_Atom*)realloc(_atom, capacity);
+ _capacity = capacity;
+ clear();
+}
+
+void*
+Buffer::port_data(PortType port_type, SampleCount offset)
+{
+ switch (port_type.symbol()) {
+ case PortType::CONTROL:
+ case PortType::CV:
+ case PortType::AUDIO:
+ assert(_atom->type == _type);
+ if (_atom->type == _factory.uris().atom_Float) {
+ return (float*)LV2_ATOM_BODY(_atom);
+ } else if (_atom->type == _factory.uris().atom_Sound) {
+ return (float*)LV2_ATOM_CONTENTS(LV2_Atom_Vector, _atom) + offset;
+ } else {
+ Raul::warn << "Audio data requested from non-audio buffer " << this << " :: "
+ << _atom->type << " - "
+ << _factory.engine().world()->lv2_uri_map()->unmap_uri(_atom->type)
+ << std::endl;
+ assert(false);
+ return NULL;
+ }
+ break;
+ default:
+ return _atom;
+ }
+}
+
+const void*
+Buffer::port_data(PortType port_type, SampleCount offset) const
+{
+ return const_cast<void*>(
+ const_cast<Buffer*>(this)->port_data(port_type, offset));
+}
+
+void
+Buffer::prepare_write(Context& context)
+{
+ _atom->size = 0;
+}
+
+bool
+Buffer::append_event(int64_t frames,
+ uint32_t size,
+ uint32_t type,
+ const uint8_t* data)
+{
+ if (sizeof(LV2_Atom) + _atom->size + lv2_atom_pad_size(size) > _capacity) {
+ return false;
+ }
+
+ LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)_atom;
+ LV2_Atom_Event* ev = (LV2_Atom_Event*)(
+ (uint8_t*)seq + sizeof(LV2_Atom) + lv2_atom_pad_size(seq->atom.size));
+
+ ev->time.frames = frames;
+ ev->body.size = size;
+ ev->body.type = type;
+ memcpy(LV2_ATOM_BODY(&ev->body), data, size);
+
+ _atom->size += lv2_atom_pad_size(size);
+
+ return true;
+}
+
+} // namespace Server
+} // namespace Ingen
diff --git a/src/server/Buffer.hpp b/src/server/Buffer.hpp
index 0b3c9348..c2d5ac05 100644
--- a/src/server/Buffer.hpp
+++ b/src/server/Buffer.hpp
@@ -24,6 +24,7 @@
#include <boost/intrusive_ptr.hpp>
#include <boost/utility.hpp>
+#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
#include "raul/AtomicInt.hpp"
#include "raul/Deletable.hpp"
#include "raul/SharedPtr.hpp"
@@ -42,32 +43,28 @@ class BufferFactory;
class Buffer : public boost::noncopyable, public Raul::Deletable
{
public:
- Buffer(BufferFactory& bufs, PortType type, size_t size)
- : _factory(bufs)
- , _type(type)
- , _size(size)
- , _next(NULL)
- , _refs(0)
- {}
+ Buffer(BufferFactory& bufs, LV2_URID type, uint32_t capacity);
- /** Clear contents and reset state */
- virtual void clear() = 0;
-
- virtual void resize(size_t size) { _size = size; }
-
- virtual void* port_data(PortType port_type, SampleCount offset=0) = 0;
- virtual const void* port_data(PortType port_type, SampleCount offset=0) const = 0;
+ virtual void clear();
+ virtual void resize(uint32_t size);
+ virtual void copy(Context& context, const Buffer* src);
+ virtual void prepare_read(Context& context) {}
+ virtual void prepare_write(Context& context);
- /** Rewind (ie reset read pointer), but leave contents unchanged */
- virtual void rewind() const {}
+ void* port_data(PortType port_type, SampleCount offset);
+ const void* port_data(PortType port_type, SampleCount offset) const;
- virtual void copy(Context& context, const Buffer* src) = 0;
+ LV2_URID type() const { return _type; }
+ uint32_t capacity() const { return _capacity; }
- virtual void prepare_read(Context& context) {}
- virtual void prepare_write(Context& context) {}
+ /// Sequence buffers only
+ bool append_event(int64_t frames,
+ uint32_t size,
+ uint32_t type,
+ const uint8_t* data);
- PortType type() const { return _type; }
- size_t size() const { return _size; }
+ LV2_Atom* atom() { return _atom; }
+ const LV2_Atom* atom() const { return _atom; }
inline void ref() { ++_refs; }
@@ -78,11 +75,12 @@ public:
protected:
BufferFactory& _factory;
- PortType _type;
- size_t _size;
+ LV2_Atom* _atom;
+ LV2_URID _type;
+ uint32_t _capacity;
friend class BufferFactory;
- virtual ~Buffer() {}
+ virtual ~Buffer();
private:
Buffer* _next; ///< Intrusive linked list for BufferFactory
diff --git a/src/server/BufferFactory.cpp b/src/server/BufferFactory.cpp
index f24f7270..6be8b2ea 100644
--- a/src/server/BufferFactory.cpp
+++ b/src/server/BufferFactory.cpp
@@ -16,15 +16,15 @@
*/
#include <algorithm>
-#include "raul/log.hpp"
+
#include "ingen/shared/LV2URIMap.hpp"
#include "ingen/shared/URIs.hpp"
+#include "raul/log.hpp"
+
#include "AudioBuffer.hpp"
-#include "EventBuffer.hpp"
-#include "ObjectBuffer.hpp"
#include "BufferFactory.hpp"
-#include "Engine.hpp"
#include "Driver.hpp"
+#include "Engine.hpp"
#include "ThreadManager.hpp"
using namespace Raul;
@@ -48,11 +48,10 @@ BufferFactory::~BufferFactory()
_silent_buffer.reset();
free_list(_free_audio.get());
free_list(_free_control.get());
- free_list(_free_event.get());
free_list(_free_object.get());
}
-Raul::Forge&
+Ingen::Forge&
BufferFactory::forge()
{
return _engine.world()->forge();
@@ -71,33 +70,31 @@ BufferFactory::free_list(Buffer* head)
void
BufferFactory::set_block_length(SampleCount block_length)
{
- _silent_buffer = create(PortType::AUDIO, audio_buffer_size(block_length));
+ _silent_buffer = create(_uris->atom_Sound, audio_buffer_size(block_length));
}
-size_t
+uint32_t
BufferFactory::audio_buffer_size(SampleCount nframes)
{
return sizeof(LV2_Atom_Vector) + (nframes * sizeof(float));
}
-size_t
-BufferFactory::default_buffer_size(PortType type)
+uint32_t
+BufferFactory::default_buffer_size(LV2_URID type)
{
- switch (type.symbol()) {
- case PortType::AUDIO:
- case PortType::CV:
- return audio_buffer_size(_engine.driver()->block_length());
- case PortType::CONTROL:
- return sizeof(LV2_Atom) + sizeof(float);
- case PortType::EVENTS:
- return _engine.driver()->block_length() * EVENT_BYTES_PER_FRAME;
- default:
- return 1024; // Who knows
+ if (type == _uris->atom_Float) {
+ return sizeof(LV2_Atom_Float);
+ } else if (type == _uris->atom_Sound) {
+ return audio_buffer_size(_engine.driver()->block_length());
+ } else if (type == _uris->atom_Sequence) {
+ return _engine.driver()->block_length() * EVENT_BYTES_PER_FRAME;
+ } else {
+ return 0;
}
}
BufferFactory::Ref
-BufferFactory::get(PortType type, size_t size, bool force_create)
+BufferFactory::get(LV2_URID type, uint32_t capacity, bool force_create)
{
Raul::AtomicPtr<Buffer>& head_ptr = free_list(type);
Buffer* try_head = NULL;
@@ -114,7 +111,7 @@ BufferFactory::get(PortType type, size_t size, bool force_create)
if (!try_head) {
if (!ThreadManager::thread_is(THREAD_PROCESS)) {
- return create(type, size);
+ return create(type, capacity);
} else {
assert(false);
error << "Failed to obtain buffer" << endl;
@@ -133,33 +130,31 @@ BufferFactory::silent_buffer()
}
BufferFactory::Ref
-BufferFactory::create(PortType type, size_t size)
+BufferFactory::create(LV2_URID type, uint32_t capacity)
{
ThreadManager::assert_not_thread(THREAD_PROCESS);
Buffer* buffer = NULL;
- if (size == 0)
- size = default_buffer_size(type);
-
- if (type.is_control()) {
- AudioBuffer* ret = new AudioBuffer(*this, type, audio_buffer_size(size));
- ret->atom()->type = _uris->atom_Float.id;
- buffer = ret;
- } else if (type.is_audio() || type.is_cv()) {
- AudioBuffer* ret = new AudioBuffer(*this, type, audio_buffer_size(size));
- ret->atom()->type = _uris->atom_Vector.id;
- ((LV2_Atom_Vector*)ret->atom())->body.child_type = _uris->atom_Float.id;
- buffer = ret;
- } else if (type.is_events()) {
- buffer = new EventBuffer(*this, size);
- } else if (type.is_value() || type.is_message()) {
- buffer = new ObjectBuffer(*this, std::max(size, sizeof(LV2_Atom) + sizeof(void*)));
+ if (capacity == 0) {
+ capacity = default_buffer_size(type);
+ }
+
+ if (type == _uris->atom_Float) {
+ assert(capacity >= sizeof(LV2_Atom_Float));
+ buffer = new AudioBuffer(*this, type, capacity);
+ info << "NEW FLOAT BUFFER " << buffer << " :: " << type << std::endl;
+ } else if (type == _uris->atom_Sound) {
+ assert(capacity >= default_buffer_size(_uris->atom_Sound));
+ buffer = new AudioBuffer(*this, type, capacity);
+ info << "NEW AUDIO BUFFER " << buffer << " :: " << type << std::endl;
} else {
- error << "Failed to create buffer of unknown type" << endl;
- return Ref();
+ buffer = new Buffer(*this, type, capacity);
+ info << "NEW ATOM BUFFER " << buffer << " :: " << type << std::endl;
}
+ buffer->atom()->type = type;
+
assert(buffer);
return Ref(buffer);
}
diff --git a/src/server/BufferFactory.hpp b/src/server/BufferFactory.hpp
index 15d5ebb8..6f700fce 100644
--- a/src/server/BufferFactory.hpp
+++ b/src/server/BufferFactory.hpp
@@ -25,9 +25,12 @@
#undef nil
#include <glibmm/thread.h>
+#include "raul/Atom.hpp"
#include "raul/AtomicPtr.hpp"
#include "raul/RingBuffer.hpp"
#include "raul/SharedPtr.hpp"
+#include "ingen/shared/Forge.hpp"
+#include "ingen/shared/URIs.hpp"
#include "PortType.hpp"
#include "types.hpp"
@@ -50,33 +53,32 @@ public:
typedef boost::intrusive_ptr<Buffer> Ref;
- static size_t audio_buffer_size(SampleCount nframes);
- size_t default_buffer_size(PortType type);
+ static uint32_t audio_buffer_size(SampleCount nframes);
+ uint32_t default_buffer_size(LV2_URID type);
- Ref get(PortType type, size_t size=0, bool force_create=false);
+ Ref get(LV2_URID type, uint32_t capacity, bool force_create=false);
Ref silent_buffer();
void set_block_length(SampleCount block_length);
- Raul::Forge& forge();
- Ingen::Shared::URIs& uris() { assert(_uris); return *_uris.get(); }
+ Ingen::Forge& forge();
+ Ingen::Shared::URIs& uris() { assert(_uris); return *_uris.get(); }
+ Engine& engine() { return _engine; }
private:
friend class Buffer;
void recycle(Buffer* buf);
- Ref create(PortType type, size_t size=0);
-
- inline Raul::AtomicPtr<Buffer>& free_list(PortType type) {
- switch (type.symbol()) {
- case PortType::AUDIO:
- case PortType::CV: return _free_audio;
- case PortType::CONTROL: return _free_control;
- case PortType::EVENTS: return _free_event;
- case PortType::VALUE:
- case PortType::MESSAGE: return _free_object;
- default: throw;
+ Ref create(LV2_URID type, uint32_t capacity=0);
+
+ inline Raul::AtomicPtr<Buffer>& free_list(LV2_URID type) {
+ if (type == _uris->atom_Float) {
+ return _free_control;
+ } else if (type == _uris->atom_Sound) {
+ return _free_audio;
+ } else {
+ return _free_object;
}
}
@@ -84,7 +86,6 @@ private:
Raul::AtomicPtr<Buffer> _free_audio;
Raul::AtomicPtr<Buffer> _free_control;
- Raul::AtomicPtr<Buffer> _free_event;
Raul::AtomicPtr<Buffer> _free_object;
Glib::Mutex _mutex;
diff --git a/src/server/ConnectionImpl.cpp b/src/server/ConnectionImpl.cpp
index bc0a5c53..7a4d7dda 100644
--- a/src/server/ConnectionImpl.cpp
+++ b/src/server/ConnectionImpl.cpp
@@ -17,15 +17,17 @@
#include <algorithm>
#include <boost/intrusive_ptr.hpp>
-#include "raul/log.hpp"
-#include "raul/Maid.hpp"
+
#include "ingen/shared/LV2URIMap.hpp"
#include "ingen/shared/URIs.hpp"
+#include "lv2/lv2plug.in/ns/ext/atom/util.h"
+#include "raul/Maid.hpp"
+#include "raul/log.hpp"
+
#include "AudioBuffer.hpp"
#include "BufferFactory.hpp"
#include "ConnectionImpl.hpp"
#include "Engine.hpp"
-#include "EventBuffer.hpp"
#include "InputPort.hpp"
#include "MessageContext.hpp"
#include "OutputPort.hpp"
@@ -109,27 +111,21 @@ ConnectionImpl::queue(Context& context)
if (!must_queue())
return;
- boost::intrusive_ptr<EventBuffer> src_buf =
- boost::dynamic_pointer_cast<EventBuffer>(_src_port->buffer(0));
- if (!src_buf) {
- error << "Queued connection but source is not an EventBuffer" << endl;
+ const Ingen::Shared::URIs& uris = _src_port->bufs().uris();
+
+ boost::intrusive_ptr<Buffer> src_buf = _src_port->buffer(0);
+ if (src_buf->atom()->type != uris.atom_Sequence) {
+ error << "Queued connection but source is not a Sequence" << endl;
return;
}
- for (src_buf->rewind(); src_buf->is_valid(); src_buf->increment()) {
- error << "Queued connections currently unsupported" << endl;
- #if 0
- LV2_Event* ev = src_buf->get_event();
- LV2_Atom* obj = LV2_ATOM_FROM_EVENT(ev);
- /*debug << _src_port->path() << " -> " << _dst_port->path()
- << " QUEUE OBJECT TYPE " << obj->type << ":";
- for (size_t i = 0; i < obj->size; ++i)
- debug << " " << std::hex << (int)obj->body[i];
- debug << endl;*/
-
- _queue->write(sizeof(LV2_Atom) + obj->size, obj);
- context.engine().message_context()->run(_dst_port->parent_node(), context.start() + ev->frames);
- #endif
+ LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)src_buf->atom();
+ LV2_SEQUENCE_FOREACH(seq, i) {
+ LV2_Atom_Event* const ev = lv2_sequence_iter_get(i);
+ _queue->write(sizeof(LV2_Atom) + ev->body.size, &ev->body);
+ context.engine().message_context()->run(
+ _dst_port->parent_node(), context.start() + ev->time.frames);
+
}
}
@@ -171,25 +167,21 @@ ConnectionImpl::can_connect(const OutputPort* src, const InputPort* dst)
|| dst->is_a(PortType::AUDIO)
|| dst->is_a(PortType::CV)))
- // (Events | Message) => (Events | Message)
- || ( (src->is_a(PortType::EVENTS) || src->is_a(PortType::MESSAGE))
- && (dst->is_a(PortType::EVENTS) || dst->is_a(PortType::MESSAGE)))
-
- // (Message | Value) => (Message | Value)
- || ( (src->is_a(PortType::MESSAGE) || src->is_a(PortType::VALUE))
- && (dst->is_a(PortType::MESSAGE) || dst->is_a(PortType::VALUE)))
+ // Equal types
+ || (src->type() == dst->type() &&
+ src->buffer_type() == dst->buffer_type())
// Control => atom:Float Value
|| (src->is_a(PortType::CONTROL) && dst->supports(uris.atom_Float))
- // Audio => atom:Vector Value
- || (src->is_a(PortType::AUDIO) && dst->supports(uris.atom_Vector))
+ // Audio => atom:Sound Value
+ || (src->is_a(PortType::AUDIO) && dst->supports(uris.atom_Sound))
// atom:Float Value => Control
|| (src->supports(uris.atom_Float) && dst->is_a(PortType::CONTROL))
- // atom:Vector Value => Audio
- || (src->supports(uris.atom_Vector) && dst->is_a(PortType::AUDIO)));
+ // atom:Sound Value => Audio
+ || (src->supports(uris.atom_Sound) && dst->is_a(PortType::AUDIO)));
}
} // namespace Server
diff --git a/src/server/ControlBindings.cpp b/src/server/ControlBindings.cpp
index d8d0ec07..0394226f 100644
--- a/src/server/ControlBindings.cpp
+++ b/src/server/ControlBindings.cpp
@@ -16,16 +16,17 @@
*/
#include <math.h>
-#include "raul/log.hpp"
-#include "raul/midi_events.h"
-#include "ingen/shared/URIs.hpp"
+
#include "ingen/shared/LV2URIMap.hpp"
+#include "ingen/shared/URIs.hpp"
#include "ingen/shared/World.hpp"
+#include "lv2/lv2plug.in/ns/ext/atom/util.h"
+#include "raul/log.hpp"
+#include "raul/midi_events.h"
#include "AudioBuffer.hpp"
#include "ControlBindings.hpp"
#include "Engine.hpp"
-#include "EventBuffer.hpp"
#include "Notification.hpp"
#include "PortImpl.hpp"
#include "ProcessContext.hpp"
@@ -43,13 +44,15 @@ ControlBindings::ControlBindings(Engine& engine)
: _engine(engine)
, _learn_port(NULL)
, _bindings(new Bindings())
- , _feedback(new EventBuffer(*_engine.buffer_factory(), 1024)) // FIXME: size
+ , _feedback(new Buffer(*_engine.buffer_factory(),
+ engine.world()->uris()->atom_Sequence,
+ 4096)) // FIXME: capacity?
{
}
ControlBindings::~ControlBindings()
{
- delete _feedback;
+ _feedback.reset();
}
ControlBindings::Key
@@ -66,7 +69,7 @@ ControlBindings::binding_key(const Raul::Atom& binding) const
{
const Ingen::Shared::URIs& uris = *_engine.world()->uris().get();
Key key;
- if (binding.type() == Atom::DICT) {
+ if (binding.type() == _engine.world()->forge().Dict) {
const Atom::DictValue& dict = binding.get_dict();
Atom::DictValue::const_iterator t = dict.find(uris.rdf_type);
Atom::DictValue::const_iterator n;
@@ -88,7 +91,7 @@ ControlBindings::binding_key(const Raul::Atom& binding) const
}
ControlBindings::Key
-ControlBindings::midi_event_key(uint16_t size, uint8_t* buf, uint16_t& value)
+ControlBindings::midi_event_key(uint16_t size, const uint8_t* buf, uint16_t& value)
{
switch (buf[0] & 0xF0) {
case MIDI_CMD_CONTROL:
@@ -125,9 +128,8 @@ ControlBindings::port_value_changed(ProcessContext& context,
Key key,
const Raul::Atom& value_atom)
{
- Ingen::Shared::World* world = context.engine().world();
- const Ingen::Shared::URIs& uris = *world->uris().get();
- const Ingen::Shared::LV2URIMap& uri_map = *world->lv2_uri_map().get();
+ Ingen::Shared::World* world = context.engine().world();
+ const Ingen::Shared::URIs& uris = *world->uris().get();
if (key) {
int16_t value = port_value_to_control(
port, key.type, value_atom, port->minimum(), port->maximum());
@@ -164,9 +166,7 @@ ControlBindings::port_value_changed(ProcessContext& context,
break;
}
if (size > 0) {
- _feedback->append(0, 0,
- uri_map.global_to_event(uris.midi_MidiEvent.id).second,
- size, buf);
+ _feedback->append_event(0, size, uris.midi_MidiEvent.id, buf);
}
}
}
@@ -218,7 +218,7 @@ ControlBindings::port_value_to_control(PortImpl* port,
const Raul::Atom& min_atom,
const Raul::Atom& max_atom) const
{
- if (value_atom.type() != Atom::FLOAT)
+ if (value_atom.type() != port->bufs().forge().Float)
return 0;
const float min = min_atom.get_float();
@@ -262,7 +262,7 @@ ControlBindings::set_port_value(ProcessContext& context,
port->set_value(port_value);
- assert(port_value.type() == Atom::FLOAT);
+ assert(port_value.type() == port->bufs().forge().Float);
assert(dynamic_cast<AudioBuffer*>(port->buffer(0).get()));
for (uint32_t v = 0; v < port->poly(); ++v)
@@ -341,71 +341,43 @@ ControlBindings::remove(PortImpl* port)
}
void
-ControlBindings::pre_process(ProcessContext& context, EventBuffer* buffer)
+ControlBindings::pre_process(ProcessContext& context, Buffer* buffer)
{
- uint32_t frames = 0;
- uint32_t subframes = 0;
- uint16_t type = 0;
- uint16_t size = 0;
- uint8_t* buf = NULL;
- uint16_t value = 0;
-
+ uint16_t value = 0;
SharedPtr<Bindings> bindings = _bindings;
_feedback->clear();
- Ingen::Shared::World* world = context.engine().world();
- const Ingen::Shared::URIs& uris = *world->uris().get();
- const Ingen::Shared::LV2URIMap& uri_map = *world->lv2_uri_map().get();
-
- // TODO: cache
- const uint32_t midi_event_type = uri_map.global_to_event(
- uris.midi_MidiEvent.id).second;
-
- // Learn from input if necessary
- if (_learn_port) {
- for (buffer->rewind();
- buffer->get_event(&frames, &subframes, &type, &size, &buf);
- buffer->increment()) {
- if (type != midi_event_type)
- continue;
-
- const Key key = midi_event_key(size, buf, value);
- if (key && bind(context, key))
- break;
- }
- }
+ Ingen::Shared::World* world = context.engine().world();
+ const Ingen::Shared::URIs& uris = *world->uris().get();
- // If bindings are empty, no sense reading input
- if (bindings->empty())
+ if (!_learn_port && bindings->empty()) {
+ // Don't bother reading input
return;
+ }
- // Read input and apply control values
- for (buffer->rewind();
- buffer->get_event(&frames, &subframes, &type, &size, &buf);
- buffer->increment()) {
- if (type != midi_event_type)
- continue;
-
- const Key key = midi_event_key(size, buf, value);
- if (!key)
- continue;
-
- Bindings::const_iterator i = bindings->find(key);
- if (i == bindings->end())
- continue;
-
- set_port_value(context, i->second, key.type, value);
+ LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)buffer->atom();
+ LV2_SEQUENCE_FOREACH(seq, i) {
+ LV2_Atom_Event* const ev = lv2_sequence_iter_get(i);
+ if (ev->body.type == uris.midi_MidiEvent) {
+ const uint8_t* buf = (const uint8_t*)LV2_ATOM_BODY(&ev->body);
+ const Key key = midi_event_key(ev->body.size, buf, value);
+ if (_learn_port && key) {
+ bind(context, key);
+ }
+
+ Bindings::const_iterator i = bindings->find(key);
+ if (i != bindings->end()) {
+ set_port_value(context, i->second, key.type, value);
+ }
+ }
}
}
void
-ControlBindings::post_process(ProcessContext& context, EventBuffer* buffer)
+ControlBindings::post_process(ProcessContext& context, Buffer* buffer)
{
- if (_feedback->event_count() > 0) {
- // TODO: merge buffer's existing contents (anything send to it in the patch)
- _feedback->rewind();
- buffer->copy(context, _feedback);
- }
+ // TODO: merge buffer's existing contents (anything send to it in the patch)
+ buffer->copy(context, _feedback.get());
}
} // namespace Server
diff --git a/src/server/ControlBindings.hpp b/src/server/ControlBindings.hpp
index f0858853..1e61bdcb 100644
--- a/src/server/ControlBindings.hpp
+++ b/src/server/ControlBindings.hpp
@@ -33,7 +33,6 @@ namespace Server {
class Engine;
class ProcessContext;
-class EventBuffer;
class PortImpl;
class ControlBindings {
@@ -77,8 +76,8 @@ public:
Key key,
const Raul::Atom& value);
- void pre_process(ProcessContext& context, EventBuffer* control_in);
- void post_process(ProcessContext& context, EventBuffer* control_out);
+ void pre_process(ProcessContext& context, Buffer* control_in);
+ void post_process(ProcessContext& context, Buffer* control_out);
/** Remove all bindings for @a path or children of @a path.
* The caller must safely drop the returned reference in the
@@ -93,7 +92,7 @@ public:
SharedPtr<Bindings> remove(PortImpl* port);
private:
- Key midi_event_key(uint16_t size, uint8_t* buf, uint16_t& value);
+ Key midi_event_key(uint16_t size, const uint8_t* buf, uint16_t& value);
void set_port_value(ProcessContext& context, PortImpl* port, Type type, int16_t value);
bool bind(ProcessContext& context, Key key);
@@ -113,7 +112,7 @@ private:
PortImpl* _learn_port;
SharedPtr<Bindings> _bindings;
- EventBuffer* _feedback;
+ BufferFactory::Ref _feedback;
};
} // namespace Server
diff --git a/src/server/DuplexPort.cpp b/src/server/DuplexPort.cpp
index f2c2763b..01fc43f3 100644
--- a/src/server/DuplexPort.cpp
+++ b/src/server/DuplexPort.cpp
@@ -22,9 +22,9 @@
#include "ingen/shared/LV2URIMap.hpp"
#include "ingen/shared/URIs.hpp"
+#include "Buffer.hpp"
#include "ConnectionImpl.hpp"
#include "DuplexPort.hpp"
-#include "EventBuffer.hpp"
#include "NodeImpl.hpp"
#include "OutputPort.hpp"
#include "ProcessContext.hpp"
@@ -43,12 +43,13 @@ DuplexPort::DuplexPort(
bool polyphonic,
uint32_t poly,
PortType type,
+ LV2_URID buffer_type,
const Raul::Atom& value,
size_t buffer_size,
bool is_output)
- : PortImpl(bufs, parent, name, index, poly, type, value, buffer_size)
- , InputPort(bufs, parent, name, index, poly, type, value, buffer_size)
- , OutputPort(bufs, parent, name, index, poly, type, value, buffer_size)
+ : PortImpl(bufs, parent, name, index, poly, type, buffer_type, value, buffer_size)
+ , InputPort(bufs, parent, name, index, poly, type, buffer_type, value, buffer_size)
+ , OutputPort(bufs, parent, name, index, poly, type, buffer_type, value, buffer_size)
, _is_output(is_output)
{
assert(PortImpl::_parent == parent);
diff --git a/src/server/DuplexPort.hpp b/src/server/DuplexPort.hpp
index 3b715130..1c543608 100644
--- a/src/server/DuplexPort.hpp
+++ b/src/server/DuplexPort.hpp
@@ -46,6 +46,7 @@ public:
bool polyphonic,
uint32_t poly,
PortType type,
+ LV2_URID buffer_type,
const Raul::Atom& value,
size_t buffer_size,
bool is_output);
diff --git a/src/server/Engine.cpp b/src/server/Engine.cpp
index 3d5e981b..d4904f0c 100644
--- a/src/server/Engine.cpp
+++ b/src/server/Engine.cpp
@@ -22,7 +22,6 @@
#include "raul/Deletable.hpp"
#include "raul/Maid.hpp"
#include "raul/SharedPtr.hpp"
-#include "lv2/lv2plug.in/ns/ext/uri-map/uri-map.h"
#include "events/CreatePatch.hpp"
#include "events/CreatePort.hpp"
#include "ingen/shared/World.hpp"
@@ -57,7 +56,7 @@ bool ThreadManager::single_threaded = true;
Engine::Engine(Ingen::Shared::World* a_world)
: _world(a_world)
, _broadcaster(new ClientBroadcaster())
- , _control_bindings(new ControlBindings(*this))
+ , _control_bindings(NULL)
, _maid(new Raul::Maid(event_queue_size()))
, _message_context(new MessageContext(*this))
, _node_factory(new NodeFactory(a_world))
@@ -73,6 +72,8 @@ Engine::Engine(Ingen::Shared::World* a_world)
SharedPtr<Ingen::Shared::Store>(
new EngineStore(SharedPtr<BufferFactory>(_buffer_factory))));
}
+
+ _control_bindings = new ControlBindings(*this);
}
Engine::~Engine()
@@ -104,7 +105,7 @@ Engine::engine_store() const
size_t
Engine::event_queue_size() const
{
- return world()->conf()->option("queue-size").get_int32();
+ return world()->conf()->option("queue-size").get_int();
}
void
@@ -153,7 +154,7 @@ Engine::activate()
_message_context->Thread::start();
const Ingen::Shared::URIs& uris = *world()->uris().get();
- Raul::Forge& forge = world()->forge();
+ Ingen::Forge& forge = world()->forge();
// Create root patch
PatchImpl* root_patch = _driver->root_patch();
@@ -173,14 +174,15 @@ Engine::activate()
Resource::Properties control_properties;
control_properties.insert(make_pair(uris.lv2_name,
- forge.make("Control")));
+ forge.alloc("Control")));
control_properties.insert(make_pair(uris.rdf_type,
- uris.ev_EventPort));
+ uris.atom_MessagePort));
+ control_properties.insert(make_pair(uris.atom_bufferType,
+ uris.atom_Sequence));
// Add control input
Resource::Properties in_properties(control_properties);
in_properties.insert(make_pair(uris.rdf_type, uris.lv2_InputPort));
- in_properties.insert(make_pair(uris.rdf_type, uris.ev_EventPort));
in_properties.insert(make_pair(uris.lv2_index, forge.make(0)));
in_properties.insert(make_pair(uris.lv2_portProperty,
uris.lv2_connectionOptional));
@@ -198,7 +200,6 @@ Engine::activate()
// Add control out
Resource::Properties out_properties(control_properties);
out_properties.insert(make_pair(uris.rdf_type, uris.lv2_OutputPort));
- out_properties.insert(make_pair(uris.rdf_type, uris.ev_EventPort));
out_properties.insert(make_pair(uris.lv2_index, forge.make(1)));
in_properties.insert(make_pair(uris.lv2_portProperty,
uris.lv2_connectionOptional));
diff --git a/src/server/EventBuffer.cpp b/src/server/EventBuffer.cpp
deleted file mode 100644
index 7f3c2b37..00000000
--- a/src/server/EventBuffer.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/* This file is part of Ingen.
- * Copyright 2007-2011 David 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 <stdint.h>
-#include "raul/log.hpp"
-#include "lv2/lv2plug.in/ns/ext/event/event.h"
-#include "lv2/lv2plug.in/ns/ext/event/event-helpers.h"
-#include "ingen_config.h"
-#include "EventBuffer.hpp"
-#include "ProcessContext.hpp"
-
-using namespace std;
-using namespace Raul;
-
-namespace Ingen {
-namespace Server {
-
-/** Allocate a new event buffer.
- * \a capacity is in bytes (not number of events).
- */
-EventBuffer::EventBuffer(BufferFactory& bufs, size_t capacity)
- : Buffer(bufs, PortType(PortType::EVENTS), capacity)
- , _latest_frames(0)
- , _latest_subframes(0)
-{
- if (capacity > UINT32_MAX) {
- error << "Event buffer size " << capacity << " too large, aborting." << endl;
- throw std::bad_alloc();
- }
-
-#ifdef HAVE_POSIX_MEMALIGN
- int ret = posix_memalign((void**)&_data, 16, sizeof(LV2_Event_Buffer) + capacity);
-#else
- _data = (LV2_Event_Buffer*)malloc(sizeof(LV2_Event_Buffer) + capacity);
- int ret = (_data != NULL) ? 0 : -1;
-#endif
-
- if (ret != 0) {
- error << "Failed to allocate event buffer. Aborting." << endl;
- exit(EXIT_FAILURE);
- }
-
- _data->header_size = sizeof(LV2_Event_Buffer);
- _data->data = reinterpret_cast<uint8_t*>(_data + _data->header_size);
- _data->stamp_type = 0;
- _data->event_count = 0;
- _data->capacity = (uint32_t)capacity;
- _data->size = 0;
-
- clear();
-}
-
-EventBuffer::~EventBuffer()
-{
- free(_data);
-}
-
-void
-EventBuffer::prepare_read(Context& context)
-{
- rewind();
-}
-
-void
-EventBuffer::prepare_write(Context& context)
-{
- if (context.offset() == 0)
- clear();
-}
-
-void
-EventBuffer::copy(Context& context, const Buffer* src_buf)
-{
- const EventBuffer* src = dynamic_cast<const EventBuffer*>(src_buf);
- if (src->_data == _data)
- return;
-
- assert(src->_data->header_size == _data->header_size);
- assert(capacity() >= _data->header_size + src->_data->size);
-
- rewind();
-
- memcpy(_data, src->_data, _data->header_size + src->_data->size);
-
- _iter = src->_iter;
- _iter.buf = _data;
-
- _latest_frames = src->_latest_frames;
- _latest_subframes = src->_latest_subframes;
-
- assert(event_count() == src->event_count());
-}
-
-/** Increment the read position by one event.
- *
- * \return true if increment was successful, or false if end of buffer reached.
- */
-bool
-EventBuffer::increment() const
-{
- if (lv2_event_is_valid(&_iter)) {
- lv2_event_increment(&_iter);
- return true;
- } else {
- return false;
- }
-}
-
-/** \return true iff the cursor is valid (ie get_event is safe)
- */
-bool
-EventBuffer::is_valid() const
-{
- return lv2_event_is_valid(&_iter);
-}
-
-/** Read an event from the current position in the buffer
- *
- * \return true if read was successful, or false if end of buffer reached
- */
-bool
-EventBuffer::get_event(uint32_t* frames,
- uint32_t* subframes,
- uint16_t* type,
- uint16_t* size,
- uint8_t** data) const
-{
- if (lv2_event_is_valid(&_iter)) {
- LV2_Event* ev = lv2_event_get(&_iter, data);
- *frames = ev->frames;
- *subframes = ev->subframes;
- *type = ev->type;
- *size = ev->size;
- return true;
- } else {
- return false;
- }
-}
-
-#if 0
-/** Get the object currently pointed to, or NULL if invalid.
- */
-LV2_Atom*
-EventBuffer::get_atom() const
-{
- if (lv2_event_is_valid(&_iter)) {
- uint8_t* data;
- LV2_Event* ev = lv2_event_get(&_iter, &data);
- return LV2_ATOM_FROM_EVENT(ev);
- }
- return NULL;
-}
-#endif
-
-/** Get the event currently pointed to, or NULL if invalid.
- */
-LV2_Event*
-EventBuffer::get_event() const
-{
- if (lv2_event_is_valid(&_iter)) {
- uint8_t* data;
- return lv2_event_get(&_iter, &data);
- }
- return NULL;
-}
-
-/** Append an event to the buffer.
- *
- * \a timestamp must be >= the latest event in the buffer.
- *
- * \return true on success
- */
-bool
-EventBuffer::append(uint32_t frames,
- uint32_t subframes,
- uint16_t type,
- uint16_t size,
- const uint8_t* data)
-{
-#ifndef NDEBUG
- if (lv2_event_is_valid(&_iter)) {
- LV2_Event* last_event = lv2_event_get(&_iter, NULL);
- assert(last_event->frames < frames
- || (last_event->frames == frames && last_event->subframes <= subframes));
- }
-#endif
-
- /*debug << "Appending event type " << type << ", size " << size
- << " @ " << frames << "." << subframes << endl;*/
-
- if (!lv2_event_write(&_iter, frames, subframes, type, size, data)) {
- error << "Failed to write event." << endl;
- return false;
- } else {
- _latest_frames = frames;
- _latest_subframes = subframes;
- return true;
- }
-}
-
-} // namespace Server
-} // namespace Ingen
diff --git a/src/server/EventBuffer.hpp b/src/server/EventBuffer.hpp
deleted file mode 100644
index 52125ffd..00000000
--- a/src/server/EventBuffer.hpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/* This file is part of Ingen.
- * Copyright 2007-2011 David 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 INGEN_ENGINE_EVENTBUFFER_HPP
-#define INGEN_ENGINE_EVENTBUFFER_HPP
-
-#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
-#include "lv2/lv2plug.in/ns/ext/event/event.h"
-#include "lv2/lv2plug.in/ns/ext/event/event-helpers.h"
-
-#include "Buffer.hpp"
-
-namespace Ingen {
-namespace Server {
-
-class EventBuffer : public Buffer {
-public:
- EventBuffer(BufferFactory& bufs, size_t capacity);
- ~EventBuffer();
-
- void* port_data(PortType port_type, SampleCount offset=0) { return _data; }
- const void* port_data(PortType port_type, SampleCount offset=0) const { return _data; }
-
- inline void rewind() const { lv2_event_begin(&_iter, _data); }
-
- inline void clear() {
- _latest_frames = 0;
- _latest_subframes = 0;
- _data->event_count = 0;
- _data->size = 0;
- rewind();
- }
-
- void prepare_read(Context& context);
- void prepare_write(Context& context);
-
- void copy(Context& context, const Buffer* src);
-
- inline size_t event_count() const { return _data->event_count; }
- inline uint32_t capacity() const { return _data->capacity; }
- inline uint32_t latest_frames() const { return _latest_frames; }
- inline uint32_t latest_subframes() const { return _latest_subframes; }
-
- bool increment() const;
- bool is_valid() const;
-
- bool get_event(uint32_t* frames,
- uint32_t* subframes,
- uint16_t* type,
- uint16_t* size,
- uint8_t** data) const;
-
- //LV2_Atom* get_atom() const;
- LV2_Event* get_event() const;
-
- bool append(uint32_t frames,
- uint32_t subframes,
- uint16_t type,
- uint16_t size,
- const uint8_t* data);
-
-private:
- LV2_Event_Buffer* _data; ///< Contents
- mutable LV2_Event_Iterator _iter; ///< Iterator into _data
- uint32_t _latest_frames; ///< Latest time of all events (frames)
- uint32_t _latest_subframes; ///< Latest time of all events (subframes)
-};
-
-} // namespace Server
-} // namespace Ingen
-
-#endif // INGEN_ENGINE_EVENTBUFFER_HPP
diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp
index a07ef183..42d6c83d 100644
--- a/src/server/InputPort.cpp
+++ b/src/server/InputPort.cpp
@@ -23,16 +23,15 @@
#include "AudioBuffer.hpp"
#include "BufferFactory.hpp"
#include "ConnectionImpl.hpp"
-#include "EventBuffer.hpp"
#include "InputPort.hpp"
#include "NodeImpl.hpp"
#include "Notification.hpp"
#include "OutputPort.hpp"
#include "ProcessContext.hpp"
#include "ThreadManager.hpp"
-#include "mix.hpp"
#include "ingen/shared/LV2URIMap.hpp"
#include "ingen/shared/URIs.hpp"
+#include "mix.hpp"
#include "util.hpp"
using namespace std;
@@ -46,9 +45,10 @@ InputPort::InputPort(BufferFactory& bufs,
uint32_t index,
uint32_t poly,
PortType type,
+ LV2_URID buffer_type,
const Raul::Atom& value,
size_t buffer_size)
- : PortImpl(bufs, parent, symbol, index, poly, type, value, buffer_size)
+ : PortImpl(bufs, parent, symbol, index, poly, type, buffer_type, value, buffer_size)
, _num_connections(0)
{
const Ingen::Shared::URIs& uris = bufs.uris();
@@ -203,7 +203,7 @@ InputPort::pre_process(Context& context)
c->get_sources(context, v, srcs, max_num_srcs, num_srcs);
}
- mix(context, buffer(v).get(), srcs, num_srcs);
+ mix(context, bufs().uris(), buffer(v).get(), srcs, num_srcs);
buffer(v)->prepare_read(context);
}
}
@@ -216,7 +216,7 @@ void
InputPort::post_process(Context& context)
{
if (_set_by_user) {
- if (is_a(PortType::EVENTS)) {
+ if (_buffer_type == _bufs.uris().atom_Sequence) {
// Clear events received via a SetPortValue
for (uint32_t v = 0; v < _poly; ++v) {
buffer(v)->clear();
diff --git a/src/server/InputPort.hpp b/src/server/InputPort.hpp
index 542c3dd1..6c790c9f 100644
--- a/src/server/InputPort.hpp
+++ b/src/server/InputPort.hpp
@@ -58,6 +58,7 @@ public:
uint32_t index,
uint32_t poly,
PortType type,
+ LV2_URID buffer_type,
const Raul::Atom& value,
size_t buffer_size=0);
diff --git a/src/server/JackDriver.cpp b/src/server/JackDriver.cpp
index 2979a449..b81a25a6 100644
--- a/src/server/JackDriver.cpp
+++ b/src/server/JackDriver.cpp
@@ -27,17 +27,16 @@
#include "ingen/serialisation/Serialiser.hpp"
#endif
-#include "raul/log.hpp"
+#include "lv2/lv2plug.in/ns/ext/atom/util.h"
#include "raul/List.hpp"
-
-#include "lv2/lv2plug.in/ns/ext/event/event.h"
+#include "raul/log.hpp"
#include "AudioBuffer.hpp"
#include "ControlBindings.hpp"
#include "DuplexPort.hpp"
#include "Engine.hpp"
#include "Event.hpp"
-#include "EventBuffer.hpp"
+#include "Event.hpp"
#include "EventSource.hpp"
#include "JackDriver.hpp"
#include "MessageContext.hpp"
@@ -45,11 +44,10 @@
#include "PortImpl.hpp"
#include "PostProcessor.hpp"
#include "ProcessSlave.hpp"
-#include "Event.hpp"
#include "ThreadManager.hpp"
-#include "ingen/shared/World.hpp"
#include "ingen/shared/LV2Features.hpp"
#include "ingen/shared/LV2URIMap.hpp"
+#include "ingen/shared/World.hpp"
#include "util.hpp"
#define LOG(s) s << "[JackDriver] "
@@ -126,9 +124,9 @@ JackPort::pre_process(ProcessContext& context)
patch_buf->copy(jack_buf, 0, nframes - 1);
- } else if (_patch_port->is_a(PortType::EVENTS)) {
- void* jack_buf = jack_port_get_buffer(_jack_port, nframes);
- EventBuffer* patch_buf = (EventBuffer*)_patch_port->buffer(0).get();
+ } else if (_patch_port->buffer_type() == _patch_port->bufs().uris().atom_Sequence) {
+ void* jack_buf = jack_port_get_buffer(_jack_port, nframes);
+ Buffer* patch_buf = (Buffer*)_patch_port->buffer(0).get();
const jack_nframes_t event_count = jack_midi_get_event_count(jack_buf);
@@ -139,10 +137,10 @@ JackPort::pre_process(ProcessContext& context)
jack_midi_event_t ev;
jack_midi_event_get(&ev, jack_buf, i);
- if (!patch_buf->append(ev.time, 0,
- _driver->_midi_event_type,
- ev.size, ev.buffer))
+ if (!patch_buf->append_event(
+ ev.time, ev.size, _driver->_midi_event_type, ev.buffer)) {
LOG(warn) << "Failed to write MIDI to port buffer, event(s) lost!" << endl;
+ }
}
}
}
@@ -161,23 +159,20 @@ JackPort::post_process(ProcessContext& context)
memcpy(jack_buf, patch_buf->data(), nframes * sizeof(Sample));
- } else if (_patch_port->is_a(PortType::EVENTS)) {
- void* jack_buf = jack_port_get_buffer(_jack_port, context.nframes());
- EventBuffer* patch_buf = (EventBuffer*)_patch_port->buffer(0).get();
+ } else if (_patch_port->buffer_type() == _patch_port->bufs().uris().atom_Sequence) {
+ void* jack_buf = jack_port_get_buffer(_jack_port, context.nframes());
+ Buffer* patch_buf = (Buffer*)_patch_port->buffer(0).get();
patch_buf->prepare_read(context);
jack_midi_clear_buffer(jack_buf);
- uint32_t frames = 0;
- uint32_t subframes = 0;
- uint16_t type = 0;
- uint16_t size = 0;
- uint8_t* data = NULL;
-
- // Copy events from Jack port buffer into patch port buffer
- for (patch_buf->rewind(); patch_buf->is_valid(); patch_buf->increment()) {
- patch_buf->get_event(&frames, &subframes, &type, &size, &data);
- jack_midi_event_write(jack_buf, frames, data, size);
+ LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)patch_buf->atom();
+ LV2_SEQUENCE_FOREACH(seq, i) {
+ LV2_Atom_Event* const ev = lv2_sequence_iter_get(i);
+ const uint8_t* buf = (const uint8_t*)LV2_ATOM_BODY(&ev->body);
+ if (ev->body.type == _patch_port->bufs().uris().midi_MidiEvent) {
+ jack_midi_event_write(jack_buf, ev->time.frames, buf, ev->body.size);
+ }
}
}
}
@@ -195,8 +190,7 @@ JackDriver::JackDriver(Engine& engine)
, _process_context(engine)
, _root_patch(NULL)
{
- _midi_event_type = _engine.world()->lv2_uri_map()->uri_to_id(
- LV2_EVENT_URI, "http://lv2plug.in/ns/ext/midi#MidiEvent");
+ _midi_event_type = _engine.world()->uris()->midi_MidiEvent;
}
JackDriver::~JackDriver()
@@ -286,7 +280,7 @@ JackDriver::activate()
_is_activated = true;
- _process_context.activate(world->conf()->option("parallelism").get_int32(),
+ _process_context.activate(world->conf()->option("parallelism").get_int(),
is_realtime());
if (jack_activate(_client)) {
@@ -376,10 +370,12 @@ JackDriver::create_port(DuplexPort* patch_port)
{
try {
if (patch_port->is_a(PortType::AUDIO)
- || patch_port->is_a(PortType::EVENTS))
+ || (patch_port->is_a(PortType::MESSAGE) &&
+ patch_port->buffer_type() == patch_port->bufs().uris().atom_Sequence)) {
return new JackPort(this, patch_port);
- else
+ } else {
return NULL;
+ }
} catch (...) {
return NULL;
}
@@ -434,8 +430,8 @@ JackDriver::_process_cb(jack_nframes_t nframes)
(*i)->pre_process(_process_context);
// Apply control bindings to input
- _engine.control_bindings()->pre_process(_process_context,
- PtrCast<EventBuffer>(_root_patch->port_impl(0)->buffer(0)).get());
+ _engine.control_bindings()->pre_process(
+ _process_context, _root_patch->port_impl(0)->buffer(0).get());
_engine.post_processor()->set_end_time(_process_context.end());
@@ -459,8 +455,8 @@ JackDriver::_process_cb(jack_nframes_t nframes)
}
// Emit control binding feedback
- _engine.control_bindings()->post_process(_process_context,
- PtrCast<EventBuffer>(_root_patch->port_impl(1)->buffer(0)).get());
+ _engine.control_bindings()->post_process(
+ _process_context, _root_patch->port_impl(1)->buffer(0).get());
// Signal message context to run if necessary
if (_engine.message_context()->has_requests())
diff --git a/src/server/LV2Info.cpp b/src/server/LV2Info.cpp
index 4fff9647..130d5dfe 100644
--- a/src/server/LV2Info.cpp
+++ b/src/server/LV2Info.cpp
@@ -42,7 +42,6 @@ LV2Info::LV2Info(Ingen::Shared::World* world)
, control_class(lilv_new_uri(world->lilv_world(), LV2_CORE__ControlPort))
, cv_class(lilv_new_uri(world->lilv_world(), "http://lv2plug.in/ns/ext/cv-port#CVPort"))
, audio_class(lilv_new_uri(world->lilv_world(), LV2_CORE__AudioPort))
- , event_class(lilv_new_uri(world->lilv_world(), LILV_URI_EVENT_PORT))
, value_port_class(lilv_new_uri(world->lilv_world(), LV2_ATOM__ValuePort))
, message_port_class(lilv_new_uri(world->lilv_world(), LV2_ATOM__MessagePort))
, _world(world)
@@ -62,7 +61,6 @@ LV2Info::~LV2Info()
lilv_node_free(control_class);
lilv_node_free(cv_class);
lilv_node_free(audio_class);
- lilv_node_free(event_class);
lilv_node_free(value_port_class);
lilv_node_free(message_port_class);
}
diff --git a/src/server/LV2Info.hpp b/src/server/LV2Info.hpp
index 297f3742..17132bcc 100644
--- a/src/server/LV2Info.hpp
+++ b/src/server/LV2Info.hpp
@@ -42,7 +42,6 @@ public:
LilvNode* control_class;
LilvNode* cv_class;
LilvNode* audio_class;
- LilvNode* event_class;
LilvNode* value_port_class;
LilvNode* message_port_class;
diff --git a/src/server/LV2Node.cpp b/src/server/LV2Node.cpp
index a22b0232..4dc9de0c 100644
--- a/src/server/LV2Node.cpp
+++ b/src/server/LV2Node.cpp
@@ -30,7 +30,6 @@
#include "ingen/shared/URIs.hpp"
#include "AudioBuffer.hpp"
-#include "EventBuffer.hpp"
#include "InputPort.hpp"
#include "LV2Node.hpp"
#include "LV2Plugin.hpp"
@@ -142,7 +141,7 @@ LV2Node::instantiate(BufferFactory& bufs)
const Ingen::Shared::URIs& uris = bufs.uris();
SharedPtr<LV2Info> info = _lv2_plugin->lv2_info();
const LilvPlugin* plug = _lv2_plugin->lilv_plugin();
- Raul::Forge& forge = bufs.forge();
+ Ingen::Forge& forge = bufs.forge();
uint32_t num_ports = lilv_plugin_get_num_ports(plug);
assert(num_ports > 0);
@@ -207,6 +206,9 @@ LV2Node::instantiate(BufferFactory& bufs)
LilvNode* supports_pred = lilv_new_uri(info->lv2_world(),
"http://lv2plug.in/ns/ext/atom#supports");
+ LilvNode* bufferType_pred = lilv_new_uri(info->lv2_world(),
+ "http://lv2plug.in/ns/ext/atom#bufferType");
+
//LilvNode as_large_as_pred = lilv_new_uri(info->lv2_world(),
// "http://lv2plug.in/ns/ext/resize-port#asLargeAs");
@@ -228,24 +230,40 @@ LV2Node::instantiate(BufferFactory& bufs)
port_path = path().child(port_name);
Raul::Atom val;
- PortType data_type = PortType::UNKNOWN;
+ PortType port_type = PortType::UNKNOWN;
+ LV2_URID buffer_type = 0;
if (lilv_port_is_a(plug, id, info->control_class)) {
- data_type = PortType::CONTROL;
+ port_type = PortType::CONTROL;
+ buffer_type = uris.atom_Float;
} else if (lilv_port_is_a(plug, id, info->cv_class)) {
- data_type = PortType::CV;
+ port_type = PortType::CV;
+ buffer_type = uris.atom_Sound;
} else if (lilv_port_is_a(plug, id, info->audio_class)) {
- data_type = PortType::AUDIO;
- } else if (lilv_port_is_a(plug, id, info->event_class)) {
- data_type = PortType::EVENTS;
+ port_type = PortType::AUDIO;
+ buffer_type = uris.atom_Sound;
} else if (lilv_port_is_a(plug, id, info->value_port_class)) {
- data_type = PortType::VALUE;
+ port_type = PortType::VALUE;
} else if (lilv_port_is_a(plug, id, info->message_port_class)) {
- data_type = PortType::MESSAGE;
+ port_type = PortType::MESSAGE;
+ }
+
+ // Get buffer type if necessary (value and message ports)
+ if (!buffer_type) {
+ LilvNodes* types = lilv_port_get_value(plug, id, bufferType_pred);
+ LILV_FOREACH(nodes, i, types) {
+ const LilvNode* type = lilv_nodes_get(types, i);
+ if (lilv_node_is_uri(type)) {
+ port->add_property(uris.atom_bufferType,
+ forge.alloc_uri(lilv_node_as_uri(type)));
+ buffer_type = bufs.engine().world()->lv2_uri_map()->map_uri(
+ lilv_node_as_uri(type));
+ }
+ }
}
- port_buffer_size = bufs.default_buffer_size(data_type);
+ port_buffer_size = bufs.default_buffer_size(buffer_type);
- if (data_type == PortType::VALUE || data_type == PortType::MESSAGE) {
+ if (port_type == PortType::VALUE || port_type == PortType::MESSAGE) {
// Get default value, and its length
LilvNodes* defaults = lilv_port_get_value(plug, id, default_pred);
LILV_FOREACH(nodes, i, defaults) {
@@ -253,7 +271,7 @@ LV2Node::instantiate(BufferFactory& bufs)
if (lilv_node_is_string(d)) {
const char* str_val = lilv_node_as_string(d);
const size_t str_val_len = strlen(str_val);
- val = forge.make(str_val);
+ val = forge.alloc(str_val);
port_buffer_size = str_val_len;
}
}
@@ -276,23 +294,23 @@ LV2Node::instantiate(BufferFactory& bufs)
direction = OUTPUT;
}
- if (data_type == PortType::UNKNOWN || direction == UNKNOWN) {
+ if (port_type == PortType::UNKNOWN || direction == UNKNOWN) {
warn << "Unknown type or direction for port `" << port_name << "'" << endl;
ret = false;
break;
}
- if (val.type() == Atom::NIL)
+ if (!val.type())
val = forge.make(isnan(def_values[j]) ? 0.0f : def_values[j]);
// TODO: set buffer size when necessary
if (direction == INPUT)
- port = new InputPort(bufs, this, port_name, j, _polyphony, data_type, val);
+ port = new InputPort(bufs, this, port_name, j, _polyphony, port_type, buffer_type, val);
else
- port = new OutputPort(bufs, this, port_name, j, _polyphony, data_type, val);
+ port = new OutputPort(bufs, this, port_name, j, _polyphony, port_type, buffer_type, val);
- if (direction == INPUT && (data_type == PortType::CONTROL
- || data_type == PortType::CV)) {
+ if (direction == INPUT && (port_type == PortType::CONTROL
+ || port_type == PortType::CV)) {
port->set_value(val);
if (!isnan(min_values[j])) {
port->set_property(uris.lv2_minimum, forge.make(min_values[j]));
@@ -309,7 +327,8 @@ LV2Node::instantiate(BufferFactory& bufs)
LILV_FOREACH(nodes, i, properties) {
const LilvNode* p = lilv_nodes_get(properties, i);
if (lilv_node_is_uri(p)) {
- port->add_property(uris.lv2_portProperty, Raul::URI(lilv_node_as_uri(p)));
+ port->add_property(uris.lv2_portProperty,
+ forge.alloc_uri(lilv_node_as_uri(p)));
}
}
@@ -318,7 +337,8 @@ LV2Node::instantiate(BufferFactory& bufs)
LILV_FOREACH(nodes, i, types) {
const LilvNode* type = lilv_nodes_get(types, i);
if (lilv_node_is_uri(type)) {
- port->add_property(uris.atom_supports, Raul::URI(lilv_node_as_uri(type)));
+ port->add_property(uris.atom_supports,
+ forge.alloc_uri(lilv_node_as_uri(type)));
}
}
@@ -411,7 +431,7 @@ LV2Node::set_port_buffer(uint32_t voice, uint32_t port_num,
{
NodeImpl::set_port_buffer(voice, port_num, buf, offset);
lilv_instance_connect_port(instance(voice), port_num,
- buf ? buf->port_data(_ports->at(port_num)->buffer_type(), offset) : NULL);
+ buf ? buf->port_data(_ports->at(port_num)->type(), offset) : NULL);
}
} // namespace Server
diff --git a/src/server/NodeImpl.cpp b/src/server/NodeImpl.cpp
index cee1cc0a..12cf2d61 100644
--- a/src/server/NodeImpl.cpp
+++ b/src/server/NodeImpl.cpp
@@ -155,8 +155,8 @@ NodeImpl::apply_poly(Raul::Maid& maid, uint32_t poly)
void
NodeImpl::set_buffer_size(Context& context,
BufferFactory& bufs,
- PortType type,
- size_t size)
+ LV2_URID type,
+ uint32_t size)
{
if (_ports) {
for (size_t i = 0; i < _ports->size(); ++i) {
diff --git a/src/server/NodeImpl.hpp b/src/server/NodeImpl.hpp
index d0d7b14e..a5c619fa 100644
--- a/src/server/NodeImpl.hpp
+++ b/src/server/NodeImpl.hpp
@@ -183,8 +183,8 @@ public:
virtual void set_buffer_size(Context& context,
BufferFactory& bufs,
- PortType type,
- size_t size);
+ LV2_URID type,
+ uint32_t size);
/** The Patch this Node belongs to. */
inline PatchImpl* parent_patch() const { return (PatchImpl*)_parent; }
diff --git a/src/server/Notification.cpp b/src/server/Notification.cpp
index 44d21a2f..f661337e 100644
--- a/src/server/Notification.cpp
+++ b/src/server/Notification.cpp
@@ -30,7 +30,7 @@ Notification::post_process(Notification& note,
Engine& engine)
{
const Ingen::Shared::URIs& uris = *engine.world()->uris().get();
- Raul::Forge& forge = engine.world()->forge();
+ Ingen::Forge& forge = engine.world()->forge();
switch (note.type) {
case PORT_VALUE:
engine.broadcaster()->set_property(note.port->path(),
diff --git a/src/server/ObjectBuffer.cpp b/src/server/ObjectBuffer.cpp
deleted file mode 100644
index 407333d3..00000000
--- a/src/server/ObjectBuffer.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/* This file is part of Ingen.
- * Copyright 2009-2011 David 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 <algorithm>
-#include "raul/log.hpp"
-#include "lv2/lv2plug.in/ns/ext/uri-map/uri-map.h"
-#include "ingen_config.h"
-#include "ingen/shared/LV2Features.hpp"
-#include "ingen/shared/LV2URIMap.hpp"
-#include "ObjectBuffer.hpp"
-#include "Engine.hpp"
-
-using namespace std;
-using namespace Raul;
-
-namespace Ingen {
-namespace Server {
-
-/** Allocate a new object buffer.
- * \a capacity is in bytes, including LV2_Atom header
- */
-ObjectBuffer::ObjectBuffer(BufferFactory& bufs, size_t capacity)
- : Buffer(bufs, PortType(PortType::VALUE), capacity)
-{
- capacity += sizeof(LV2_Atom);
-
-#ifdef HAVE_POSIX_MEMALIGN
- const int ret = posix_memalign((void**)&_buf, 16, capacity);
-#else
- _buf = (LV2_Atom*)malloc(capacity);
- const int ret = (_buf != NULL) ? 0 : -1;
-#endif
-
- if (ret != 0) {
- error << "Failed to allocate object buffer. Aborting." << endl;
- exit(EXIT_FAILURE);
- }
-
- clear();
-}
-
-ObjectBuffer::~ObjectBuffer()
-{
- free(_buf);
-}
-
-void
-ObjectBuffer::clear()
-{
- // null
- _buf->type = 0;
- _buf->size = 0;
-}
-
-void
-ObjectBuffer::copy(Context& context, const Buffer* src_buf)
-{
- const ObjectBuffer* src = dynamic_cast<const ObjectBuffer*>(src_buf);
- if (!src || src == this || src->_buf == _buf)
- return;
-
- // Copy only if src is a POD object that fits
- if (src->_buf->type != 0 && src_buf->size() <= size())
- memcpy(_buf, src->_buf, sizeof(LV2_Atom) + src_buf->size());
-}
-
-void
-ObjectBuffer::resize(size_t size)
-{
- const uint32_t contents_size = sizeof(LV2_Atom) + _buf->size;
-
- _buf = (LV2_Atom*)realloc(_buf, sizeof(LV2_Atom) + size);
- _size = size + sizeof(LV2_Atom);
-
- // If we shrunk and chopped the current contents, clear corrupt data
- if (size < contents_size)
- clear();
-}
-
-void*
-ObjectBuffer::port_data(PortType port_type, SampleCount offset)
-{
- switch (port_type.symbol()) {
- case PortType::CONTROL:
- case PortType::CV:
- case PortType::AUDIO:
- switch (_type.symbol()) {
- case PortType::CONTROL:
- return (float*)LV2_ATOM_BODY(atom());
- case PortType::CV:
- case PortType::AUDIO:
- return (float*)LV2_ATOM_CONTENTS(LV2_Atom_Vector, atom()) + offset;
- default:
- warn << "Audio data requested from non-audio buffer" << endl;
- return NULL;
- }
- break;
- default:
- return _buf;
- }
-}
-
-const void*
-ObjectBuffer::port_data(PortType port_type, SampleCount offset) const
-{
- switch (port_type.symbol()) {
- case PortType::CONTROL:
- case PortType::CV:
- case PortType::AUDIO:
- switch (_type.symbol()) {
- case PortType::CONTROL:
- return (float*)LV2_ATOM_BODY(atom());
- case PortType::CV:
- case PortType::AUDIO:
- return (float*)LV2_ATOM_CONTENTS(LV2_Atom_Vector, atom()) + offset;
- default:
- warn << "Audio data requested from non-audio buffer" << endl;
- return NULL;
- }
- break;
- default:
- return _buf;
- }
-}
-
-void
-ObjectBuffer::prepare_write(Context& context)
-{
- _buf->size = _size - sizeof(LV2_Atom);
-}
-
-} // namespace Server
-} // namespace Ingen
-
diff --git a/src/server/ObjectBuffer.hpp b/src/server/ObjectBuffer.hpp
deleted file mode 100644
index 93dc746b..00000000
--- a/src/server/ObjectBuffer.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/* This file is part of Ingen.
- * Copyright 2009-2011 David 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 INGEN_ENGINE_OBJECTBUFFER_HPP
-#define INGEN_ENGINE_OBJECTBUFFER_HPP
-
-#include "lv2/lv2plug.in/ns/ext/atom/atom.h"
-
-#include "Buffer.hpp"
-
-namespace Ingen {
-namespace Server {
-
-class Context;
-
-class ObjectBuffer : public Buffer {
-public:
- ObjectBuffer(BufferFactory& bufs, size_t capacity);
- ~ObjectBuffer();
-
- void clear();
-
- void* port_data(PortType port_type, SampleCount offset);
- const void* port_data(PortType port_type, SampleCount offset) const;
-
- void prepare_write(Context& context);
-
- void copy(Context& context, const Buffer* src);
-
- void resize(size_t size);
-
- LV2_Atom* atom() { return _buf; }
- const LV2_Atom* atom() const { return _buf; }
-
-private:
- LV2_Atom* _buf; ///< Contents
-};
-
-} // namespace Server
-} // namespace Ingen
-
-#endif // INGEN_ENGINE_OBJECTBUFFER_HPP
diff --git a/src/server/OutputPort.cpp b/src/server/OutputPort.cpp
index 11f637b3..8d454201 100644
--- a/src/server/OutputPort.cpp
+++ b/src/server/OutputPort.cpp
@@ -35,9 +35,10 @@ OutputPort::OutputPort(BufferFactory& bufs,
uint32_t index,
uint32_t poly,
PortType type,
+ LV2_URID buffer_type,
const Raul::Atom& value,
size_t buffer_size)
- : PortImpl(bufs, parent, symbol, index, poly, type, value, buffer_size)
+ : PortImpl(bufs, parent, symbol, index, poly, type, buffer_type, value, buffer_size)
{
if (!dynamic_cast<Patch*>(parent))
add_property(bufs.uris().rdf_type, bufs.uris().lv2_OutputPort);
diff --git a/src/server/OutputPort.hpp b/src/server/OutputPort.hpp
index 168ab7c4..906c9c64 100644
--- a/src/server/OutputPort.hpp
+++ b/src/server/OutputPort.hpp
@@ -46,6 +46,7 @@ public:
uint32_t index,
uint32_t poly,
PortType type,
+ LV2_URID buffer_type,
const Raul::Atom& value,
size_t buffer_size=0);
diff --git a/src/server/PatchImpl.cpp b/src/server/PatchImpl.cpp
index c2d97d41..dca7f2ae 100644
--- a/src/server/PatchImpl.cpp
+++ b/src/server/PatchImpl.cpp
@@ -258,8 +258,8 @@ PatchImpl::process_single(ProcessContext& context)
void
PatchImpl::set_buffer_size(Context& context,
BufferFactory& bufs,
- PortType type,
- size_t size)
+ LV2_URID type,
+ uint32_t size)
{
NodeImpl::set_buffer_size(context, bufs, type, size);
@@ -346,7 +346,8 @@ PortImpl*
PatchImpl::create_port(BufferFactory& bufs,
const string& name,
PortType type,
- size_t buffer_size,
+ LV2_URID buffer_type,
+ uint32_t buffer_size,
bool is_output,
bool polyphonic)
{
@@ -360,7 +361,7 @@ PatchImpl::create_port(BufferFactory& bufs,
value = bufs.forge().make(0.0f);
return new DuplexPort(bufs, this, name, num_ports(), polyphonic, _polyphony,
- type, value, buffer_size, is_output);
+ type, buffer_type, value, buffer_size, is_output);
}
/** Remove port from ports list used in pre-processing thread.
diff --git a/src/server/PatchImpl.hpp b/src/server/PatchImpl.hpp
index 004eb0cb..5704fad0 100644
--- a/src/server/PatchImpl.hpp
+++ b/src/server/PatchImpl.hpp
@@ -69,8 +69,8 @@ public:
void set_buffer_size(Context& context,
BufferFactory& bufs,
- PortType type,
- size_t size);
+ LV2_URID type,
+ uint32_t size);
/** Prepare for a new (internal) polyphony value.
*
@@ -111,7 +111,8 @@ public:
PortImpl* create_port(BufferFactory& bufs,
const std::string& name,
PortType type,
- size_t buffer_size,
+ LV2_URID buffer_type,
+ uint32_t buffer_size,
bool is_output,
bool polyphonic);
diff --git a/src/server/PortImpl.cpp b/src/server/PortImpl.cpp
index 67255e5f..3cc8082c 100644
--- a/src/server/PortImpl.cpp
+++ b/src/server/PortImpl.cpp
@@ -27,10 +27,8 @@
#include "AudioBuffer.hpp"
#include "BufferFactory.hpp"
#include "Engine.hpp"
-#include "EventBuffer.hpp"
#include "NodeImpl.hpp"
#include "Notification.hpp"
-#include "ObjectBuffer.hpp"
#include "PortImpl.hpp"
#include "PortType.hpp"
#include "ThreadManager.hpp"
@@ -47,6 +45,7 @@ PortImpl::PortImpl(BufferFactory& bufs,
uint32_t index,
uint32_t poly,
PortType type,
+ LV2_URID buffer_type,
const Atom& value,
size_t buffer_size)
: GraphObjectImpl(bufs.uris(), node, name)
@@ -55,6 +54,7 @@ PortImpl::PortImpl(BufferFactory& bufs,
, _poly(poly)
, _buffer_size(buffer_size)
, _type(type)
+ , _buffer_type(buffer_type)
, _value(value)
, _min(bufs.forge().make(0.0f))
, _max(bufs.forge().make(1.0f))
@@ -68,11 +68,27 @@ PortImpl::PortImpl(BufferFactory& bufs,
assert(node != NULL);
assert(_poly > 0);
- if (_buffer_size == 0)
- _buffer_size = bufs.default_buffer_size(type);
-
const Ingen::Shared::URIs& uris = bufs.uris();
- add_property(uris.rdf_type, type.uri());
+
+ if (_buffer_size == 0) {
+ _buffer_size = bufs.default_buffer_size(buffer_type);
+ }
+
+ if (_buffer_type == 0) {
+ switch (_type.symbol()) {
+ case PortType::CONTROL:
+ _buffer_type = uris.atom_Float;
+ break;
+ case PortType::AUDIO:
+ case PortType::CV:
+ _buffer_type = uris.atom_Sound;
+ break;
+ default:
+ break;
+ }
+ }
+
+ add_property(uris.rdf_type, bufs.forge().alloc_uri(type.uri().str()));
set_property(uris.lv2_index, bufs.forge().make((int32_t)index));
set_context(_context);
}
@@ -85,7 +101,8 @@ PortImpl::~PortImpl()
bool
PortImpl::supports(const Raul::URI& value_type) const
{
- return has_property(_bufs.uris().atom_supports, value_type);
+ return has_property(_bufs.uris().atom_supports,
+ _bufs.forge().alloc_uri(value_type.str()));
}
Raul::Array<BufferFactory::Ref>*
@@ -108,9 +125,9 @@ bool
PortImpl::prepare_poly(BufferFactory& bufs, uint32_t poly)
{
ThreadManager::assert_thread(THREAD_PRE_PROCESS);
- if (buffer_type() != PortType::CONTROL &&
- buffer_type() != PortType::CV &&
- buffer_type() != PortType::AUDIO) {
+ if (_type != PortType::CONTROL &&
+ _type != PortType::CV &&
+ _type != PortType::AUDIO) {
return false;
}
@@ -140,9 +157,9 @@ bool
PortImpl::apply_poly(Maid& maid, uint32_t poly)
{
ThreadManager::assert_thread(THREAD_PROCESS);
- if (buffer_type() != PortType::CONTROL &&
- buffer_type() != PortType::CV &&
- buffer_type() != PortType::AUDIO) {
+ if (_type != PortType::CONTROL &&
+ _type != PortType::CV &&
+ _type != PortType::AUDIO) {
return false;
}
@@ -207,8 +224,8 @@ PortImpl::clear_buffers()
void
PortImpl::broadcast_value(Context& context, bool force)
{
- Raul::Forge& forge = context.engine().world()->forge();
- Raul::Atom val;
+ Ingen::Forge& forge = context.engine().world()->forge();
+ Raul::Atom val;
switch (_type.symbol()) {
case PortType::UNKNOWN:
break;
@@ -224,21 +241,16 @@ PortImpl::broadcast_value(Context& context, bool force)
case PortType::CV:
val = forge.make(((AudioBuffer*)buffer(0).get())->value_at(0));
break;
- case PortType::EVENTS:
- if (((EventBuffer*)buffer(0).get())->event_count() > 0) {
- const Notification note = Notification::make(
- Notification::PORT_ACTIVITY, context.start(), this, forge.make(true));
- context.event_sink().write(sizeof(note), &note);
- }
- break;
case PortType::VALUE:
case PortType::MESSAGE:
- std::cerr << "FIXME: Atom value" << std::endl;
- /*
- Ingen::Shared::LV2Atom::to_atom(_bufs.uris(),
- ((ObjectBuffer*)buffer(0).get())->atom(),
- val);
- */
+ if (_buffer_type == _bufs.uris().atom_Sequence) {
+ LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)buffer(0)->atom();
+ if (seq->atom.size > sizeof(LV2_Atom_Sequence_Body)) {
+ const Notification note = Notification::make(
+ Notification::PORT_ACTIVITY, context.start(), this, forge.make(true));
+ context.event_sink().write(sizeof(note), &note);
+ }
+ }
break;
}
@@ -265,11 +277,5 @@ PortImpl::set_context(Context::ID c)
}
}
-PortType
-PortImpl::buffer_type() const
-{
- return _type;
-}
-
} // namespace Server
} // namespace Ingen
diff --git a/src/server/PortImpl.hpp b/src/server/PortImpl.hpp
index 2316a1d9..c67be49b 100644
--- a/src/server/PortImpl.hpp
+++ b/src/server/PortImpl.hpp
@@ -124,7 +124,8 @@ public:
inline bool is_a(PortType type) const { return _type == type; }
- PortType buffer_type() const;
+ PortType type() const { return _type; }
+ LV2_URID buffer_type() const { return _buffer_type; }
bool supports(const Raul::URI& value_type) const;
@@ -158,6 +159,7 @@ protected:
uint32_t index,
uint32_t poly,
PortType type,
+ LV2_URID buffer_type,
const Raul::Atom& value,
size_t buffer_size);
@@ -166,6 +168,7 @@ protected:
uint32_t _poly;
uint32_t _buffer_size;
PortType _type;
+ LV2_URID _buffer_type;
Raul::Atom _value;
Raul::Atom _min;
Raul::Atom _max;
diff --git a/src/server/PortType.hpp b/src/server/PortType.hpp
index b8fd747e..a2eac676 100644
--- a/src/server/PortType.hpp
+++ b/src/server/PortType.hpp
@@ -35,9 +35,8 @@ public:
AUDIO = 1,
CONTROL = 2,
CV = 3,
- EVENTS = 4,
- VALUE = 5,
- MESSAGE = 6,
+ VALUE = 4,
+ MESSAGE = 5,
};
PortType(const Raul::URI& uri)
@@ -49,8 +48,6 @@ public:
_symbol = CONTROL;
} else if (uri == type_uri(CV)) {
_symbol = CV;
- } else if (uri == type_uri(EVENTS)) {
- _symbol = EVENTS;
} else if (uri == type_uri(VALUE)) {
_symbol = VALUE;
} else if (uri == type_uri(MESSAGE)) {
@@ -74,7 +71,6 @@ public:
inline bool is_audio() { return _symbol == AUDIO; }
inline bool is_control() { return _symbol == CONTROL; }
inline bool is_cv() { return _symbol == CV; }
- inline bool is_events() { return _symbol == EVENTS; }
inline bool is_value() { return _symbol == VALUE; }
inline bool is_message() { return _symbol == MESSAGE; }
@@ -86,7 +82,6 @@ private:
"http://lv2plug.in/ns/lv2core#AudioPort",
"http://lv2plug.in/ns/lv2core#ControlPort",
"http://lv2plug.in/ns/ext/cv-port#CVPort",
- "http://lv2plug.in/ns/ext/event#EventPort",
"http://lv2plug.in/ns/ext/atom#ValuePort",
"http://lv2plug.in/ns/ext/atom#MessagePort"
};
diff --git a/src/server/ServerInterfaceImpl.cpp b/src/server/ServerInterfaceImpl.cpp
index f03294b2..69b26141 100644
--- a/src/server/ServerInterfaceImpl.cpp
+++ b/src/server/ServerInterfaceImpl.cpp
@@ -161,7 +161,7 @@ ServerInterfaceImpl::set_property(const URI& uri,
const Atom& value)
{
if (uri == "ingen:engine" && predicate == "ingen:enabled"
- && value.type() == Atom::BOOL) {
+ && value.type() == _engine.world()->forge().Bool) {
if (value.get_bool()) {
_engine.activate();
push_queued(new Events::Ping(_engine, _request_client, _request_id, now()));
diff --git a/src/server/ServerInterfaceImpl.hpp b/src/server/ServerInterfaceImpl.hpp
index 0ba3a1b9..21100222 100644
--- a/src/server/ServerInterfaceImpl.hpp
+++ b/src/server/ServerInterfaceImpl.hpp
@@ -51,6 +51,8 @@ public:
Raul::URI uri() const { return "http://drobilla.net/ns/ingen#internal"; }
+ void set_response_interface(Interface* iface) { _request_client = iface; }
+
virtual void set_response_id(int32_t id);
virtual void bundle_begin();
diff --git a/src/server/events/CreateNode.cpp b/src/server/events/CreateNode.cpp
index d74b0b6c..7098196a 100644
--- a/src/server/events/CreateNode.cpp
+++ b/src/server/events/CreateNode.cpp
@@ -61,7 +61,7 @@ CreateNode::CreateNode(Engine& engine,
{
const Resource::Properties::const_iterator p = properties.find(
engine.world()->uris()->ingen_polyphonic);
- if (p != properties.end() && p->second.type() == Raul::Atom::BOOL
+ if (p != properties.end() && p->second.type() == engine.world()->forge().Bool
&& p->second.get_bool())
_polyphonic = true;
}
diff --git a/src/server/events/CreatePort.cpp b/src/server/events/CreatePort.cpp
index 6fa4a6bf..cc6f7e93 100644
--- a/src/server/events/CreatePort.cpp
+++ b/src/server/events/CreatePort.cpp
@@ -49,7 +49,8 @@ CreatePort::CreatePort(Engine& engine,
const Resource::Properties& properties)
: Event(engine, client, id, timestamp)
, _path(path)
- , _data_type(PortType::UNKNOWN)
+ , _port_type(PortType::UNKNOWN)
+ , _buffer_type(0)
, _patch(NULL)
, _patch_port(NULL)
, _ports_array(NULL)
@@ -61,30 +62,31 @@ CreatePort::CreatePort(Engine& engine,
typedef Resource::Properties::const_iterator Iterator;
typedef std::pair<Iterator, Iterator> Range;
+
const Range types = properties.equal_range(uris.rdf_type);
for (Iterator i = types.first; i != types.second; ++i) {
const Raul::Atom& type = i->second;
- if (type.type() != Atom::URI) {
- warn << "Non-URI port type " << type << endl;
- continue;
- }
-
if (type == uris.lv2_AudioPort) {
- _data_type = PortType::AUDIO;
+ _port_type = PortType::AUDIO;
} else if (type == uris.lv2_ControlPort) {
- _data_type = PortType::CONTROL;
+ _port_type = PortType::CONTROL;
} else if (type == uris.cv_CVPort) {
- _data_type = PortType::CV;
- } else if (type == uris.ev_EventPort) {
- _data_type = PortType::EVENTS;
+ _port_type = PortType::CV;
} else if (type == uris.atom_ValuePort) {
- _data_type = PortType::VALUE;
+ _port_type = PortType::VALUE;
} else if (type == uris.atom_MessagePort) {
- _data_type = PortType::MESSAGE;
+ _port_type = PortType::MESSAGE;
+ }
+ }
+
+ const Range buffer_types = properties.equal_range(uris.atom_bufferType);
+ for (Iterator i = buffer_types.first; i != buffer_types.second; ++i) {
+ if (i->second.type() == _engine.world()->forge().URI) {
+ _buffer_type = _engine.world()->lv2_uri_map()->map_uri(i->second.get_uri());
}
}
- if (_data_type == PortType::UNKNOWN) {
+ if (_port_type == PortType::UNKNOWN) {
_status = UNKNOWN_TYPE;
}
}
@@ -104,7 +106,7 @@ CreatePort::pre_process()
if (_patch != NULL) {
assert(_patch->path() == _path.parent());
- size_t buffer_size = _engine.buffer_factory()->default_buffer_size(_data_type);
+ size_t buffer_size = _engine.buffer_factory()->default_buffer_size(_buffer_type);
const uint32_t old_num_ports = (_patch->external_ports())
? _patch->external_ports()->size()
@@ -115,7 +117,7 @@ CreatePort::pre_process()
index_i = _properties.insert(
make_pair(uris.lv2_index,
_engine.world()->forge().make(int32_t(old_num_ports))));
- } else if (index_i->second.type() != Atom::INT
+ } else if (index_i->second.type() != uris.forge.Int
|| index_i->second.get_int32() != static_cast<int32_t>(old_num_ports)) {
Event::pre_process();
_status = BAD_INDEX;
@@ -123,10 +125,12 @@ CreatePort::pre_process()
}
Resource::Properties::const_iterator poly_i = _properties.find(uris.ingen_polyphonic);
- bool polyphonic = (poly_i != _properties.end() && poly_i->second.type() == Atom::BOOL
+ bool polyphonic = (poly_i != _properties.end() && poly_i->second.type() == uris.forge.Bool
&& poly_i->second.get_bool());
- _patch_port = _patch->create_port(*_engine.buffer_factory(), _path.symbol(), _data_type, buffer_size, _is_output, polyphonic);
+ _patch_port = _patch->create_port(*_engine.buffer_factory(), _path.symbol(),
+ _port_type, _buffer_type, buffer_size,
+ _is_output, polyphonic);
_patch_port->properties().insert(_properties.begin(), _properties.end());
diff --git a/src/server/events/CreatePort.hpp b/src/server/events/CreatePort.hpp
index 331a1252..45fedebc 100644
--- a/src/server/events/CreatePort.hpp
+++ b/src/server/events/CreatePort.hpp
@@ -18,13 +18,13 @@
#ifndef INGEN_EVENTS_CREATEPORT_HPP
#define INGEN_EVENTS_CREATEPORT_HPP
+#include "ingen/Resource.hpp"
+#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
#include "raul/Array.hpp"
#include "raul/Path.hpp"
-#include "ingen/Resource.hpp"
-
-#include "PortType.hpp"
#include "Event.hpp"
+#include "PortType.hpp"
namespace Ingen {
namespace Server {
@@ -57,7 +57,8 @@ public:
private:
Raul::Path _path;
Raul::URI _type;
- PortType _data_type;
+ PortType _port_type;
+ LV2_URID _buffer_type;
PatchImpl* _patch;
PortImpl* _patch_port;
Raul::Array<PortImpl*>* _ports_array; ///< New (external) ports array for Patch
diff --git a/src/server/events/SetMetadata.cpp b/src/server/events/SetMetadata.cpp
index e2621fae..1c4ac0e6 100644
--- a/src/server/events/SetMetadata.cpp
+++ b/src/server/events/SetMetadata.cpp
@@ -129,7 +129,7 @@ SetMetadata::pre_process()
if (is_patch) {
uint32_t poly = 1;
iterator p = _properties.find(uris.ingen_polyphony);
- if (p != _properties.end() && p->second.is_valid() && p->second.type() == Atom::INT)
+ if (p != _properties.end() && p->second.is_valid() && p->second.type() == uris.forge.Int)
poly = p->second.get_int32();
_create_event = new CreatePatch(_engine, _request_client, _request_id, _time,
path, poly, _properties);
@@ -186,7 +186,7 @@ SetMetadata::pre_process()
PortImpl* port = dynamic_cast<PortImpl*>(_object);
if (port) {
if (key == uris.ingen_broadcast) {
- if (value.type() == Atom::BOOL) {
+ if (value.type() == uris.forge.Bool) {
op = ENABLE_BROADCAST;
} else {
_status = BAD_VALUE_TYPE;
@@ -200,7 +200,7 @@ SetMetadata::pre_process()
if (port->is_a(PortType::CONTROL) || port->is_a(PortType::CV)) {
if (value == uris.wildcard) {
_engine.control_bindings()->learn(port);
- } else if (value.type() == Atom::DICT) {
+ } else if (value.type() == uris.forge.Dict) {
op = CONTROL_BINDING;
} else {
_status = BAD_VALUE_TYPE;
@@ -211,7 +211,7 @@ SetMetadata::pre_process()
}
} else if ((_patch = dynamic_cast<PatchImpl*>(_object))) {
if (key == uris.ingen_enabled) {
- if (value.type() == Atom::BOOL) {
+ if (value.type() == uris.forge.Bool) {
op = ENABLE;
// FIXME: defer this until all other metadata has been processed
if (value.get_bool() && !_patch->enabled())
@@ -220,7 +220,7 @@ SetMetadata::pre_process()
_status = BAD_VALUE_TYPE;
}
} else if (key == uris.ingen_polyphony) {
- if (value.type() == Atom::INT) {
+ if (value.type() == uris.forge.Int) {
op = POLYPHONY;
_patch->prepare_internal_poly(*_engine.buffer_factory(), value.get_int32());
} else {
@@ -230,7 +230,7 @@ SetMetadata::pre_process()
} else if (key == uris.ingen_polyphonic) {
PatchImpl* parent = dynamic_cast<PatchImpl*>(obj->parent());
if (parent) {
- if (value.type() == Atom::BOOL) {
+ if (value.type() == uris.forge.Bool) {
op = POLYPHONIC;
obj->set_property(key, value, value.context());
NodeImpl* node = dynamic_cast<NodeImpl*>(obj);
@@ -288,7 +288,7 @@ SetMetadata::execute(ProcessContext& context)
std::vector<SpecialType>::const_iterator t = _types.begin();
for (Properties::const_iterator p = _properties.begin(); p != _properties.end(); ++p, ++t) {
- const Raul::Atom& key = p->first;
+ const Raul::URI& key = p->first;
const Raul::Atom& value = p->second;
switch (*t) {
case ENABLE_BROADCAST:
diff --git a/src/server/events/SetPortValue.cpp b/src/server/events/SetPortValue.cpp
index ecf9416e..00f72a51 100644
--- a/src/server/events/SetPortValue.cpp
+++ b/src/server/events/SetPortValue.cpp
@@ -22,7 +22,6 @@
#include "ingen/shared/LV2URIMap.hpp"
#include "ingen/shared/URIs.hpp"
#include "ingen/shared/World.hpp"
-#include "lv2/lv2plug.in/ns/ext/event/event.h"
#include "raul/log.hpp"
#include "AudioBuffer.hpp"
@@ -31,10 +30,8 @@
#include "Driver.hpp"
#include "Engine.hpp"
#include "EngineStore.hpp"
-#include "EventBuffer.hpp"
#include "MessageContext.hpp"
#include "NodeImpl.hpp"
-#include "ObjectBuffer.hpp"
#include "PortImpl.hpp"
#include "ProcessContext.hpp"
#include "SetPortValue.hpp"
@@ -129,6 +126,8 @@ SetPortValue::apply(Context& context)
if (_status == SUCCESS && !_port)
_port = _engine.engine_store()->find_port(_port_path);
+ Ingen::Shared::URIs& uris = *_engine.world()->uris().get();
+
if (!_port) {
if (_status == SUCCESS)
_status = PORT_NOT_FOUND;
@@ -138,7 +137,7 @@ SetPortValue::apply(Context& context)
Buffer* const buf = _port->buffer(0).get();
AudioBuffer* const abuf = dynamic_cast<AudioBuffer*>(buf);
if (abuf) {
- if (_value.type() != Atom::FLOAT) {
+ if (_value.type() != uris.forge.Float) {
_status = TYPE_MISMATCH;
return;
}
@@ -150,44 +149,6 @@ SetPortValue::apply(Context& context)
return;
}
- Ingen::Shared::URIs& uris = *_engine.world()->uris().get();
- Ingen::Shared::LV2URIMap& uri_map = *_engine.world()->lv2_uri_map().get();
-
- EventBuffer* const ebuf = dynamic_cast<EventBuffer*>(buf);
- if (ebuf && _value.type() == Atom::BLOB) {
- const uint32_t frames = std::max(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) {
- const uint32_t type_id = uri_map.uri_to_id(NULL, _value.get_blob_type());
- ebuf->append(frames, 0, type_id, 0, NULL);
- _port->raise_set_by_user_flag();
- return;
-
- } else if (!strcmp(_value.get_blob_type(),
- "http://lv2plug.in/ns/ext/midi#MidiEvent")) {
- ebuf->prepare_write(context);
- ebuf->append(frames, 0,
- uri_map.global_to_event(uris.midi_MidiEvent.id).second,
- _value.data_size(),
- (const uint8_t*)_value.get_blob());
- _port->raise_set_by_user_flag();
- return;
- }
- }
-
- ObjectBuffer* const obuf = dynamic_cast<ObjectBuffer*>(buf);
- if (obuf) {
- obuf->atom()->size = obuf->size() - sizeof(LV2_Atom);
- if (Ingen::Shared::LV2Atom::from_atom(uris, _value, obuf->atom())) {
- debug << "Converted atom " << _value << " :: " << obuf->atom()->type
- << " * " << obuf->atom()->size << " @ " << obuf->atom() << endl;
- return;
- } else {
- warn << "Failed to convert atom to LV2 object" << endl;
- }
- }
-
warn << "Unknown value type " << (int)_value.type() << endl;
}
}
diff --git a/src/server/ingen_jack.cpp b/src/server/ingen_jack.cpp
index 267b13aa..fd80d804 100644
--- a/src/server/ingen_jack.cpp
+++ b/src/server/ingen_jack.cpp
@@ -34,8 +34,11 @@ struct IngenJackModule : public Ingen::Shared::Module {
Server::JackDriver* driver = new Server::JackDriver(
*(Server::Engine*)world->local_engine().get());
- driver->attach(world->conf()->option("jack-server").get_string(),
- world->conf()->option("jack-client").get_string(), NULL);
+ const Raul::Configuration::Value& s = world->conf()->option("jack-server");
+ const std::string server_name = s.is_valid() ? s.get_string() : "";
+ driver->attach(server_name,
+ world->conf()->option("jack-client").get_string(),
+ NULL);
((Server::Engine*)world->local_engine().get())->set_driver(
SharedPtr<Server::Driver>(driver));
}
diff --git a/src/server/ingen_lv2.cpp b/src/server/ingen_lv2.cpp
index 3e9366ae..e6552e69 100644
--- a/src/server/ingen_lv2.cpp
+++ b/src/server/ingen_lv2.cpp
@@ -29,10 +29,13 @@
#include "lv2/lv2plug.in/ns/lv2core/lv2.h"
#include "lv2/lv2plug.in/ns/ext/state/state.h"
#include "lv2/lv2plug.in/ns/ext/urid/urid.h"
+#include "lv2/lv2plug.in/ns/ext/atom/util.h"
#include "ingen/Interface.hpp"
#include "ingen/serialisation/Parser.hpp"
#include "ingen/serialisation/Serialiser.hpp"
+#include "ingen/shared/AtomReader.hpp"
+#include "ingen/shared/AtomWriter.hpp"
#include "ingen/shared/Configuration.hpp"
#include "ingen/shared/Store.hpp"
#include "ingen/shared/World.hpp"
@@ -54,7 +57,7 @@
#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
#define NS_RDFS "http://www.w3.org/2000/01/rdf-schema#"
-/** Record of a patch in this Ingen LV2 bundle */
+/** Record of a patch in this bundle. */
struct LV2Patch {
LV2Patch(const std::string& u, const std::string& f);
@@ -63,6 +66,7 @@ struct LV2Patch {
LV2_Descriptor descriptor;
};
+/** Ingen LV2 library. */
class Lib {
public:
Lib(const char* bundle_path);
@@ -77,6 +81,8 @@ namespace Server {
class LV2Driver;
+void handle_message(LV2Driver* driver, const LV2_Atom* msg);
+
class LV2Port : public DriverPort
{
public:
@@ -92,26 +98,31 @@ public:
void move(const Raul::Path& path) {}
void pre_process(ProcessContext& context) {
- if (!is_input() || !_buffer)
+ if (!is_input() || !_buffer) {
return;
+ }
if (_patch_port->is_a(PortType::AUDIO)) {
AudioBuffer* patch_buf = (AudioBuffer*)_patch_port->buffer(0).get();
patch_buf->copy((Sample*)_buffer, 0, context.nframes() - 1);
- } else if (_patch_port->is_a(PortType::EVENTS)) {
- //Raul::warn << "TODO: LV2 event I/O" << std::endl;
+ } else {
+ LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)_buffer;
+ LV2_SEQUENCE_FOREACH(seq, i) {
+ LV2_Atom_Event* ev = lv2_sequence_iter_get(i);
+ // FIXME: Not RT safe, need to send these through a ring
+ handle_message(_driver, &ev->body);
+ }
}
}
void post_process(ProcessContext& context) {
- if (is_input() || !_buffer)
+ if (is_input() || !_buffer) {
return;
+ }
if (_patch_port->is_a(PortType::AUDIO)) {
AudioBuffer* patch_buf = (AudioBuffer*)_patch_port->buffer(0).get();
memcpy((Sample*)_buffer, patch_buf->data(), context.nframes() * sizeof(Sample));
- } else if (_patch_port->is_a(PortType::EVENTS)) {
- //Raul::warn << "TODO: LV2 event I/O" << std::endl;
}
}
@@ -123,13 +134,23 @@ private:
void* _buffer;
};
-class LV2Driver : public Ingen::Server::Driver {
+class LV2Driver : public Ingen::Server::Driver
+ , public Ingen::Shared::AtomSink
+{
private:
typedef std::vector<LV2Port*> Ports;
public:
LV2Driver(Engine& engine, SampleCount buffer_size, SampleCount sample_rate)
: _context(engine)
+ , _reader(*engine.world()->lv2_uri_map().get(),
+ *engine.world()->uris().get(),
+ engine.world()->forge(),
+ *engine.world()->engine().get())
+ , _writer(*engine.world()->lv2_uri_map().get(),
+ *engine.world()->uris().get(),
+ *this)
+ , _to_ui(8192) // FIXME: size
, _root_patch(NULL)
, _buffer_size(buffer_size)
, _sample_rate(sample_rate)
@@ -147,6 +168,8 @@ public:
if (_root_patch)
_root_patch->process(_context);
+ flush_to_ui();
+
for (Ports::iterator i = _ports.begin(); i != _ports.end(); ++i)
(*i)->post_process(_context);
@@ -194,24 +217,88 @@ public:
return NULL;
}
+ void write(const LV2_Atom* atom) {
+ // Called from post-processor in main thread
+ if (_to_ui.write(lv2_atom_total_size(atom), atom) == 0) {
+ Raul::error << "To-UI ring overflow" << std::endl;
+ }
+ }
+
+ void flush_to_ui() {
+ assert(ThreadManager::thread_is(THREAD_PROCESS));
+ assert(_ports.size() >= 2);
+
+ LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)_ports[1]->buffer();
+ if (!seq) {
+ Raul::warn << "Control out port not connected" << std::endl;
+ return;
+ }
+
+ // Output port buffer is a Chunk with size set to the available space
+ const uint32_t capacity = seq->atom.size;
+
+ // Initialise output port buffer to an empty Sequence
+ seq->atom.type = _context.engine().world()->uris()->atom_Sequence;
+ seq->atom.size = sizeof(LV2_Atom_Sequence_Body);
+
+ const uint32_t read_space = _to_ui.read_space();
+ for (uint32_t read = 0; read < read_space;) {
+ LV2_Atom atom;
+ if (!_to_ui.peek(sizeof(LV2_Atom), &atom)) {
+ Raul::error << "Error reading head from to-UI ring" << std::endl;
+ break;
+ }
+
+ if (seq->atom.size + sizeof(LV2_Atom) + atom.size > capacity) {
+ break; // Output port buffer full, resume next time
+ }
+
+ LV2_Atom_Event* ev = (LV2_Atom_Event*)(
+ (uint8_t*)seq + lv2_atom_total_size(&seq->atom));
+
+ ev->time.frames = 0; // TODO: Time?
+ ev->body = atom;
+
+ _to_ui.skip(sizeof(LV2_Atom));
+ if (!_to_ui.read(ev->body.size, LV2_ATOM_BODY(&ev->body))) {
+ Raul::error << "Error reading body from to-UI ring" << std::endl;
+ break;
+ }
+
+ read += lv2_atom_total_size(&ev->body);
+ seq->atom.size += sizeof(LV2_Atom_Event) + ev->body.size;
+ }
+ }
+
virtual SampleCount block_length() const { return _buffer_size; }
virtual SampleCount sample_rate() const { return _sample_rate; }
virtual SampleCount frame_time() const { return _frame_time;}
virtual bool is_realtime() const { return true; }
virtual ProcessContext& context() { return _context; }
+ Shared::AtomReader& reader() { return _reader; }
+ Shared::AtomWriter& writer() { return _writer; }
Ports& ports() { return _ports; }
private:
- ProcessContext _context;
- PatchImpl* _root_patch;
- SampleCount _buffer_size;
- SampleCount _sample_rate;
- SampleCount _frame_time;
- Ports _ports;
+ ProcessContext _context;
+ Shared::AtomReader _reader;
+ Shared::AtomWriter _writer;
+ Raul::RingBuffer _to_ui;
+ PatchImpl* _root_patch;
+ SampleCount _buffer_size;
+ SampleCount _sample_rate;
+ SampleCount _frame_time;
+ Ports _ports;
};
+void
+handle_message(LV2Driver* driver, const LV2_Atom* msg)
+{
+ driver->reader().write(msg);
+}
+
} // namespace Server
} // namespace Ingen
@@ -236,7 +323,7 @@ private:
};
struct IngenPlugin {
- Raul::Forge forge;
+ Ingen::Forge forge;
Ingen::Shared::Configuration* conf;
Ingen::Shared::World* world;
MainThread* main;
@@ -304,7 +391,7 @@ ingen_instantiate(const LV2_Descriptor* descriptor,
}
IngenPlugin* plugin = (IngenPlugin*)malloc(sizeof(IngenPlugin));
- plugin->conf = new Ingen::Shared::Configuration(&plugin->forge);
+ plugin->conf = new Ingen::Shared::Configuration();
plugin->main = NULL;
plugin->map = NULL;
LV2_URID_Unmap* unmap = NULL;
@@ -341,6 +428,10 @@ ingen_instantiate(const LV2_Descriptor* descriptor,
LV2Driver* driver = new LV2Driver(*engine.get(), rate, 4096);
engine->set_driver(SharedPtr<Ingen::Server::Driver>(driver));
+ interface->set_response_interface(&driver->writer());
+ engine->register_client("http://drobilla.net/ns/ingen#internal",
+ &driver->writer());
+
engine->activate();
Server::ThreadManager::single_threaded = true;
@@ -350,7 +441,7 @@ ingen_instantiate(const LV2_Descriptor* descriptor,
engine->post_processor()->set_end_time(UINT_MAX);
// TODO: Load only necessary plugins
- plugin->world->engine()->get("ingen:plugins");
+ //plugin->world->engine()->get("ingen:plugins");
interface->process(*engine->post_processor(), context, false);
engine->post_processor()->process();
@@ -365,7 +456,7 @@ ingen_instantiate(const LV2_Descriptor* descriptor,
engine->deactivate();
- plugin->world->load_module("osc_server");
+ //plugin->world->load_module("osc_server");
return (LV2_Handle)plugin;
}
@@ -381,6 +472,7 @@ ingen_connect_port(LV2_Handle instance, uint32_t port, void* data)
if (port < driver->ports().size()) {
driver->ports().at(port)->set_buffer(data);
assert(driver->ports().at(port)->patch_port()->index() == port);
+ assert(driver->ports().at(port)->buffer() == data);
} else {
Raul::warn << "Connect to non-existent port " << port << std::endl;
}
@@ -391,6 +483,7 @@ ingen_activate(LV2_Handle instance)
{
IngenPlugin* me = (IngenPlugin*)instance;
me->world->local_engine()->activate();
+ ((ServerInterfaceImpl*)me->world->engine().get())->start();
me->main->start();
}
diff --git a/src/server/internals/Controller.cpp b/src/server/internals/Controller.cpp
index e93d5f27..3c29edd3 100644
--- a/src/server/internals/Controller.cpp
+++ b/src/server/internals/Controller.cpp
@@ -20,10 +20,10 @@
#include "ingen/shared/LV2URIMap.hpp"
#include "ingen/shared/URIs.hpp"
#include "internals/Controller.hpp"
+#include "lv2/lv2plug.in/ns/ext/atom/util.h"
#include "raul/midi_events.h"
#include "AudioBuffer.hpp"
-#include "EventBuffer.hpp"
#include "InputPort.hpp"
#include "InternalPlugin.hpp"
#include "Notification.hpp"
@@ -54,37 +54,38 @@ ControllerNode::ControllerNode(InternalPlugin* plugin,
const Ingen::Shared::URIs& uris = bufs.uris();
_ports = new Raul::Array<PortImpl*>(6);
- _midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom());
- _midi_in_port->set_property(uris.lv2_name, bufs.forge().make("Input"));
+ _midi_in_port = new InputPort(bufs, this, "input", 0, 1,
+ PortType::MESSAGE, uris.atom_Sequence, Raul::Atom());
+ _midi_in_port->set_property(uris.lv2_name, bufs.forge().alloc("Input"));
_ports->at(0) = _midi_in_port;
_param_port = new InputPort(bufs, this, "controller", 1, 1,
- PortType::CONTROL, bufs.forge().make(0.0f));
+ PortType::CONTROL, 0, bufs.forge().make(0.0f));
_param_port->set_property(uris.lv2_minimum, bufs.forge().make(0.0f));
_param_port->set_property(uris.lv2_maximum, bufs.forge().make(127.0f));
_param_port->set_property(uris.lv2_integer, bufs.forge().make(true));
- _param_port->set_property(uris.lv2_name, bufs.forge().make("Controller"));
+ _param_port->set_property(uris.lv2_name, bufs.forge().alloc("Controller"));
_ports->at(1) = _param_port;
_log_port = new InputPort(bufs, this, "logarithmic", 2, 1,
- PortType::CONTROL, bufs.forge().make(0.0f));
+ PortType::CONTROL, 0, bufs.forge().make(0.0f));
_log_port->set_property(uris.lv2_portProperty, uris.lv2_toggled);
- _log_port->set_property(uris.lv2_name, bufs.forge().make("Logarithmic"));
+ _log_port->set_property(uris.lv2_name, bufs.forge().alloc("Logarithmic"));
_ports->at(2) = _log_port;
_min_port = new InputPort(bufs, this, "minimum", 3, 1,
- PortType::CONTROL, bufs.forge().make(0.0f));
- _min_port->set_property(uris.lv2_name, bufs.forge().make("Minimum"));
+ PortType::CONTROL, 0, bufs.forge().make(0.0f));
+ _min_port->set_property(uris.lv2_name, bufs.forge().alloc("Minimum"));
_ports->at(3) = _min_port;
_max_port = new InputPort(bufs, this, "maximum", 4, 1,
- PortType::CONTROL, bufs.forge().make(1.0f));
- _max_port->set_property(uris.lv2_name, bufs.forge().make("Maximum"));
+ PortType::CONTROL, 0, bufs.forge().make(1.0f));
+ _max_port->set_property(uris.lv2_name, bufs.forge().alloc("Maximum"));
_ports->at(4) = _max_port;
_audio_port = new OutputPort(bufs, this, "ar_output", 5, 1,
- PortType::AUDIO, bufs.forge().make(0.0f));
- _audio_port->set_property(uris.lv2_name, bufs.forge().make("Output"));
+ PortType::AUDIO, 0, bufs.forge().make(0.0f));
+ _audio_port->set_property(uris.lv2_name, bufs.forge().alloc("Output"));
_ports->at(5) = _audio_port;
}
@@ -93,22 +94,15 @@ ControllerNode::process(ProcessContext& context)
{
NodeImpl::pre_process(context);
- uint32_t frames = 0;
- uint32_t subframes = 0;
- uint16_t type = 0;
- uint16_t size = 0;
- uint8_t* buf = NULL;
-
- EventBuffer* const midi_in = (EventBuffer*)_midi_in_port->buffer(0).get();
-
- midi_in->rewind();
-
- while (midi_in->get_event(&frames, &subframes, &type, &size, &buf)) {
- // FIXME: type
- if (size >= 3 && (buf[0] & 0xF0) == MIDI_CMD_CONTROL)
- control(context, buf[1], buf[2], frames + context.start());
-
- midi_in->increment();
+ Buffer* const midi_in = _midi_in_port->buffer(0).get();
+ LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)midi_in->atom();
+ LV2_SEQUENCE_FOREACH(seq, i) {
+ LV2_Atom_Event* const ev = lv2_sequence_iter_get(i);
+ const uint8_t* buf = (const uint8_t*)LV2_ATOM_BODY(&ev->body);
+ if (ev->body.type == _midi_in_port->bufs().uris().midi_MidiEvent &&
+ ev->body.size >= 3 && (buf[0] & 0xF0) == MIDI_CMD_CONTROL) {
+ control(context, buf[1], buf[2], ev->time.frames + context.start());
+ }
}
NodeImpl::post_process(context);
diff --git a/src/server/internals/Controller.hpp b/src/server/internals/Controller.hpp
index d664bf55..ac412c10 100644
--- a/src/server/internals/Controller.hpp
+++ b/src/server/internals/Controller.hpp
@@ -57,14 +57,13 @@ public:
static InternalPlugin* internal_plugin(Shared::URIs& uris);
private:
- bool _learning;
-
InputPort* _midi_in_port;
InputPort* _param_port;
InputPort* _log_port;
InputPort* _min_port;
InputPort* _max_port;
OutputPort* _audio_port;
+ bool _learning;
};
} // namespace Server
diff --git a/src/server/internals/Delay.cpp b/src/server/internals/Delay.cpp
index 21cc23d5..dc55355e 100644
--- a/src/server/internals/Delay.cpp
+++ b/src/server/internals/Delay.cpp
@@ -28,7 +28,6 @@
#include "internals/Delay.hpp"
#include "AudioBuffer.hpp"
#include "Driver.hpp"
-#include "EventBuffer.hpp"
#include "InputPort.hpp"
#include "InternalPlugin.hpp"
#include "OutputPort.hpp"
@@ -75,22 +74,22 @@ DelayNode::DelayNode(
_delay_samples = default_delay;
_delay_port = new InputPort(bufs, this, "delay", 1, _polyphony,
- PortType::CONTROL, bufs.forge().make(default_delay));
- _delay_port->set_property(uris.lv2_name, bufs.forge().make("Delay"));
+ PortType::CONTROL, 0, bufs.forge().make(default_delay));
+ _delay_port->set_property(uris.lv2_name, bufs.forge().alloc("Delay"));
_delay_port->set_property(uris.lv2_default, bufs.forge().make(default_delay));
_delay_port->set_property(uris.lv2_minimum, bufs.forge().make((float)(1.0/(double)srate)));
_delay_port->set_property(uris.lv2_maximum, bufs.forge().make(MAX_DELAY_SECONDS));
_ports->at(0) = _delay_port;
_in_port = new InputPort(bufs, this, "in", 0, 1,
- PortType::AUDIO, bufs.forge().make(0.0f));
- _in_port->set_property(uris.lv2_name, bufs.forge().make("Input"));
+ PortType::AUDIO, 0, bufs.forge().make(0.0f));
+ _in_port->set_property(uris.lv2_name, bufs.forge().alloc("Input"));
_ports->at(1) = _in_port;
_out_port = new OutputPort(bufs, this, "out", 0, 1,
- PortType::AUDIO, bufs.forge().make(0.0f));
+ PortType::AUDIO, 0, bufs.forge().make(0.0f));
_out_port->set_property(uris.lv2_name,
- bufs.forge().make("Output"));
+ bufs.forge().alloc("Output"));
_ports->at(2) = _out_port;
//_buffer = bufs.get(PortType::AUDIO, bufs.audio_buffer_size(buffer_length_frames), true);
diff --git a/src/server/internals/Note.cpp b/src/server/internals/Note.cpp
index a44c0c36..e591bfd8 100644
--- a/src/server/internals/Note.cpp
+++ b/src/server/internals/Note.cpp
@@ -19,22 +19,22 @@
#include "ingen/shared/LV2URIMap.hpp"
#include "ingen/shared/URIs.hpp"
+#include "lv2/lv2plug.in/ns/ext/atom/util.h"
#include "raul/Array.hpp"
#include "raul/Maid.hpp"
#include "raul/log.hpp"
#include "raul/midi_events.h"
-#include "internals/Note.hpp"
#include "AudioBuffer.hpp"
#include "Driver.hpp"
-#include "EventBuffer.hpp"
#include "InputPort.hpp"
#include "InternalPlugin.hpp"
#include "OutputPort.hpp"
#include "PatchImpl.hpp"
#include "ProcessContext.hpp"
-#include "util.hpp"
#include "ingen_config.h"
+#include "internals/Note.hpp"
+#include "util.hpp"
#define LOG(s) s << "[NoteNode] "
@@ -65,32 +65,32 @@ NoteNode::NoteNode(
_ports = new Raul::Array<PortImpl*>(5);
_midi_in_port = new InputPort(bufs, this, "input", 0, 1,
- PortType::EVENTS, Raul::Atom());
- _midi_in_port->set_property(uris.lv2_name, bufs.forge().make("Input"));
+ PortType::MESSAGE, uris.atom_Sequence, Raul::Atom());
+ _midi_in_port->set_property(uris.lv2_name, bufs.forge().alloc("Input"));
_ports->at(0) = _midi_in_port;
_freq_port = new OutputPort(bufs, this, "frequency", 1, _polyphony,
- PortType::AUDIO, bufs.forge().make(440.0f));
- _freq_port->set_property(uris.lv2_name, bufs.forge().make("Frequency"));
+ PortType::AUDIO, 0, bufs.forge().make(440.0f));
+ _freq_port->set_property(uris.lv2_name, bufs.forge().alloc("Frequency"));
_ports->at(1) = _freq_port;
_vel_port = new OutputPort(bufs, this, "velocity", 2, _polyphony,
- PortType::AUDIO, bufs.forge().make(0.0f));
+ PortType::AUDIO, 0, bufs.forge().make(0.0f));
_vel_port->set_property(uris.lv2_minimum, bufs.forge().make(0.0f));
_vel_port->set_property(uris.lv2_maximum, bufs.forge().make(1.0f));
- _vel_port->set_property(uris.lv2_name, bufs.forge().make("Velocity"));
+ _vel_port->set_property(uris.lv2_name, bufs.forge().alloc("Velocity"));
_ports->at(2) = _vel_port;
_gate_port = new OutputPort(bufs, this, "gate", 3, _polyphony,
- PortType::AUDIO, bufs.forge().make(0.0f));
+ PortType::AUDIO, 0, bufs.forge().make(0.0f));
_gate_port->set_property(uris.lv2_portProperty, uris.lv2_toggled);
- _gate_port->set_property(uris.lv2_name, bufs.forge().make("Gate"));
+ _gate_port->set_property(uris.lv2_name, bufs.forge().alloc("Gate"));
_ports->at(3) = _gate_port;
_trig_port = new OutputPort(bufs, this, "trigger", 4, _polyphony,
- PortType::AUDIO, bufs.forge().make(0.0f));
+ PortType::AUDIO, 0, bufs.forge().make(0.0f));
_trig_port->set_property(uris.lv2_portProperty, uris.lv2_toggled);
- _trig_port->set_property(uris.lv2_name, bufs.forge().make("Trigger"));
+ _trig_port->set_property(uris.lv2_name, bufs.forge().alloc("Trigger"));
_ports->at(4) = _trig_port;
}
@@ -135,42 +135,24 @@ NoteNode::apply_poly(Raul::Maid& maid, uint32_t poly)
void
NoteNode::process(ProcessContext& context)
{
- EventBuffer* const midi_in = (EventBuffer*)_midi_in_port->buffer(0).get();
NodeImpl::pre_process(context);
-
- uint32_t frames = 0;
- uint32_t subframes = 0;
- uint16_t type = 0;
- uint16_t size = 0;
- uint8_t* buf = NULL;
-
- midi_in->rewind();
-
- if (midi_in->event_count() > 0)
- for (midi_in->rewind(); midi_in->get_event(&frames, &subframes, &type, &size, &buf);
- midi_in->increment()) {
-
-#ifdef RAUL_LOG_DEBUG
- LOG(debug) << "EVENT TYPE " << type << " @ " << frames << "." << subframes << ": ";
- for (uint16_t i = 0; i < size; ++i)
- debug << (int)((char)buf[i]) << " ";
- debug << endl;
-#endif
-
- if (frames < context.offset())
- continue;
- if (frames > context.nframes())
- break;
-
- const FrameTime time = context.start() + (FrameTime)frames;
-
- if (size >= 3) {
+
+ Buffer* const midi_in = _midi_in_port->buffer(0).get();
+ LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)midi_in->atom();
+ LV2_SEQUENCE_FOREACH(seq, i) {
+ LV2_Atom_Event* const ev = lv2_sequence_iter_get(i);
+ const uint8_t* buf = (const uint8_t*)LV2_ATOM_BODY(&ev->body);
+ const FrameTime time = context.start() + (FrameTime)ev->time.frames;
+
+ if (ev->body.type == _midi_in_port->bufs().uris().midi_MidiEvent &&
+ ev->body.size >= 3) {
switch (buf[0] & 0xF0) {
case MIDI_CMD_NOTE_ON:
- if (buf[2] == 0)
+ if (buf[2] == 0) {
note_off(context, buf[1], time);
- else
+ } else {
note_on(context, buf[1], buf[2], time);
+ }
break;
case MIDI_CMD_NOTE_OFF:
note_off(context, buf[1], time);
@@ -182,10 +164,11 @@ NoteNode::process(ProcessContext& context)
all_notes_off(context, time);
break;
case MIDI_CTL_SUSTAIN:
- if (buf[2] > 63)
+ if (buf[2] > 63) {
sustain_on(context, time);
- else
+ } else {
sustain_off(context, time);
+ }
break;
case MIDI_CMD_BENDER:
// ?
diff --git a/src/server/internals/Trigger.cpp b/src/server/internals/Trigger.cpp
index 885144fe..3ccc44d7 100644
--- a/src/server/internals/Trigger.cpp
+++ b/src/server/internals/Trigger.cpp
@@ -19,11 +19,11 @@
#include "ingen/shared/LV2URIMap.hpp"
#include "ingen/shared/URIs.hpp"
+#include "lv2/lv2plug.in/ns/ext/atom/util.h"
#include "raul/log.hpp"
#include "raul/midi_events.h"
#include "AudioBuffer.hpp"
-#include "EventBuffer.hpp"
#include "InputPort.hpp"
#include "InternalPlugin.hpp"
#include "OutputPort.hpp"
@@ -58,35 +58,36 @@ TriggerNode::TriggerNode(
const Ingen::Shared::URIs& uris = bufs.uris();
_ports = new Raul::Array<PortImpl*>(5);
- _midi_in_port = new InputPort(bufs, this, "input", 0, 1, PortType::EVENTS, Raul::Atom());
- _midi_in_port->set_property(uris.lv2_name, bufs.forge().make("Input"));
+ _midi_in_port = new InputPort(bufs, this, "input", 0, 1,
+ PortType::MESSAGE, uris.atom_Sequence, Raul::Atom());
+ _midi_in_port->set_property(uris.lv2_name, bufs.forge().alloc("Input"));
_ports->at(0) = _midi_in_port;
_note_port = new InputPort(bufs, this, "note", 1, 1,
- PortType::CONTROL, bufs.forge().make(60.0f));
+ PortType::CONTROL, 0, bufs.forge().make(60.0f));
_note_port->set_property(uris.lv2_minimum, bufs.forge().make(0.0f));
_note_port->set_property(uris.lv2_maximum, bufs.forge().make(127.0f));
_note_port->set_property(uris.lv2_integer, bufs.forge().make(true));
- _note_port->set_property(uris.lv2_name, bufs.forge().make("Note"));
+ _note_port->set_property(uris.lv2_name, bufs.forge().alloc("Note"));
_ports->at(1) = _note_port;
_gate_port = new OutputPort(bufs, this, "gate", 2, 1,
- PortType::AUDIO, bufs.forge().make(0.0f));
+ PortType::AUDIO, 0, bufs.forge().make(0.0f));
_gate_port->set_property(uris.lv2_portProperty, uris.lv2_toggled);
- _gate_port->set_property(uris.lv2_name, bufs.forge().make("Gate"));
+ _gate_port->set_property(uris.lv2_name, bufs.forge().alloc("Gate"));
_ports->at(2) = _gate_port;
_trig_port = new OutputPort(bufs, this, "trigger", 3, 1,
- PortType::AUDIO, bufs.forge().make(0.0f));
+ PortType::AUDIO, 0, bufs.forge().make(0.0f));
_trig_port->set_property(uris.lv2_portProperty, uris.lv2_toggled);
- _trig_port->set_property(uris.lv2_name, bufs.forge().make("Trigger"));
+ _trig_port->set_property(uris.lv2_name, bufs.forge().alloc("Trigger"));
_ports->at(3) = _trig_port;
_vel_port = new OutputPort(bufs, this, "velocity", 4, 1,
- PortType::AUDIO, bufs.forge().make(0.0f));
+ PortType::AUDIO, 0, bufs.forge().make(0.0f));
_vel_port->set_property(uris.lv2_minimum, bufs.forge().make(0.0f));
_vel_port->set_property(uris.lv2_maximum, bufs.forge().make(1.0f));
- _vel_port->set_property(uris.lv2_name, bufs.forge().make("Velocity"));
+ _vel_port->set_property(uris.lv2_name, bufs.forge().alloc("Velocity"));
_ports->at(4) = _vel_port;
}
@@ -95,40 +96,35 @@ TriggerNode::process(ProcessContext& context)
{
NodeImpl::pre_process(context);
- uint32_t frames = 0;
- uint32_t subframes = 0;
- uint16_t type = 0;
- uint16_t size = 0;
- uint8_t* buf = NULL;
-
- EventBuffer* const midi_in = (EventBuffer*)_midi_in_port->buffer(0).get();
-
- midi_in->rewind();
-
- while (midi_in->get_event(&frames, &subframes, &type, &size, &buf)) {
- const FrameTime time = context.start() + (FrameTime)frames;
-
- if (size >= 3) {
+ Buffer* const midi_in = _midi_in_port->buffer(0).get();
+ LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)midi_in->atom();
+ LV2_SEQUENCE_FOREACH(seq, i) {
+ LV2_Atom_Event* const ev = lv2_sequence_iter_get(i);
+ const uint8_t* buf = (const uint8_t*)LV2_ATOM_BODY(&ev->body);
+ if (ev->body.type == _midi_in_port->bufs().uris().midi_MidiEvent &&
+ ev->body.size >= 3) {
+ const FrameTime time = context.start() + ev->time.frames;
switch (buf[0] & 0xF0) {
case MIDI_CMD_NOTE_ON:
- if (buf[2] == 0)
+ if (buf[2] == 0) {
note_off(context, buf[1], time);
- else
+ } else {
note_on(context, buf[1], buf[2], time);
+ }
break;
case MIDI_CMD_NOTE_OFF:
note_off(context, buf[1], time);
break;
case MIDI_CMD_CONTROL:
- if (buf[1] == MIDI_CTL_ALL_NOTES_OFF
- || buf[1] == MIDI_CTL_ALL_SOUNDS_OFF)
- ((AudioBuffer*)_gate_port->buffer(0).get())->set_value(0.0f, context.start(), time);
+ if (buf[1] == MIDI_CTL_ALL_NOTES_OFF ||
+ buf[1] == MIDI_CTL_ALL_SOUNDS_OFF) {
+ ((AudioBuffer*)_gate_port->buffer(0).get())->set_value(
+ 0.0f, context.start(), time);
+ }
default:
break;
}
}
-
- midi_in->increment();
}
NodeImpl::post_process(context);
diff --git a/src/server/mix.hpp b/src/server/mix.hpp
index 21040c52..54f80dfc 100644
--- a/src/server/mix.hpp
+++ b/src/server/mix.hpp
@@ -20,36 +20,45 @@
#include <boost/intrusive_ptr.hpp>
+#include "ingen/shared/URIs.hpp"
#include "raul/log.hpp"
#include "Buffer.hpp"
#include "Context.hpp"
-#include "PortType.hpp"
using namespace Raul;
namespace Ingen {
namespace Server {
+inline bool
+is_audio(Shared::URIs& uris, LV2_URID type)
+{
+ return type == uris.atom_Float || type == uris.atom_Sound;
+}
+
inline void
-mix(Context& context, Buffer* dst, const boost::intrusive_ptr<Buffer>* srcs, uint32_t num_srcs)
+mix(Context& context,
+ Shared::URIs& uris,
+ Buffer* dst,
+ const boost::intrusive_ptr<Buffer>* srcs,
+ uint32_t num_srcs)
{
- using Ingen::PortType;
- switch (dst->type().symbol()) {
- case PortType::AUDIO:
- case PortType::CONTROL:
- case PortType::CV:
+ if (num_srcs == 1) {
+ dst->copy(context, srcs[0].get());
+ } else if (is_audio(uris, dst->type())) {
// Copy the first source
dst->copy(context, srcs[0].get());
// Mix in the rest
for (uint32_t i = 1; i < num_srcs; ++i) {
- assert(srcs[i]->type() == PortType::AUDIO ||
- srcs[i]->type() == PortType::CONTROL ||
- srcs[i]->type() == PortType::CV);
+ assert(is_audio(uris, srcs[i]->type()));
((AudioBuffer*)dst)->accumulate(context, (AudioBuffer*)srcs[i].get());
}
- break;
+ } else {
+ std::cerr << "FIXME: event mix" << std::endl;
+ }
+#if 0
case PortType::EVENTS:
dst->clear();
for (uint32_t i = 0; i < num_srcs; ++i) {
@@ -77,14 +86,7 @@ mix(Context& context, Buffer* dst, const boost::intrusive_ptr<Buffer>* srcs, uin
}
}
dst->rewind();
- break;
- default:
- if (num_srcs == 1)
- dst->copy(context, srcs[0].get());
- else
- error << "Mix of unsupported buffer types" << std::endl;
- return;
- }
+#endif
}
} // namespace Server
diff --git a/src/server/wscript b/src/server/wscript
index 33ffc58a..58a3918a 100644
--- a/src/server/wscript
+++ b/src/server/wscript
@@ -4,6 +4,7 @@ from waflib.extras import autowaf as autowaf
def build(bld):
core_source = '''
AudioBuffer.cpp
+ Buffer.cpp
BufferFactory.cpp
ClientBroadcaster.cpp
ConnectionImpl.cpp
@@ -12,7 +13,6 @@ def build(bld):
Engine.cpp
EngineStore.cpp
Event.cpp
- EventBuffer.cpp
EventSource.cpp
GraphObjectImpl.cpp
InputPort.cpp
@@ -24,7 +24,6 @@ def build(bld):
NodeFactory.cpp
NodeImpl.cpp
Notification.cpp
- ObjectBuffer.cpp
ObjectSender.cpp
OutputPort.cpp
PatchImpl.cpp