summaryrefslogtreecommitdiffstats
path: root/src/server/ObjectBuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/ObjectBuffer.cpp')
-rw-r--r--src/server/ObjectBuffer.cpp147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/server/ObjectBuffer.cpp b/src/server/ObjectBuffer.cpp
new file mode 100644
index 00000000..d09fbb96
--- /dev/null
+++ b/src/server/ObjectBuffer.cpp
@@ -0,0 +1,147 @@
+/* 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 "shared/LV2Features.hpp"
+#include "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::AUDIO:
+ switch (_type.symbol()) {
+ case PortType::CONTROL:
+ return (float*)atom()->body;
+ case PortType::AUDIO:
+ return (float*)((LV2_Atom_Vector*)atom()->body)->elems + 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::AUDIO:
+ switch (_type.symbol()) {
+ case PortType::CONTROL:
+ return (float*)atom()->body;
+ case PortType::AUDIO:
+ return (float*)((LV2_Atom_Vector*)atom()->body)->elems + 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
+