summaryrefslogtreecommitdiffstats
path: root/src/engine/AudioBuffer.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-11-16 00:30:35 +0000
committerDavid Robillard <d@drobilla.net>2009-11-16 00:30:35 +0000
commit3d89115a67a9c947a28539ffdd2399808a53279b (patch)
tree826b900de3979eed9c31aae0d3ac560d39b53460 /src/engine/AudioBuffer.cpp
parent597fa9212f27d2448c0cdd20fbf616928c662cc1 (diff)
downloadingen-3d89115a67a9c947a28539ffdd2399808a53279b.tar.gz
ingen-3d89115a67a9c947a28539ffdd2399808a53279b.tar.bz2
ingen-3d89115a67a9c947a28539ffdd2399808a53279b.zip
Rework objects extension to have "value ports" and "message ports".
Make audio and control buffers in ingen actually object buffers (towards interop). Overhaul the hell out of ingen buffer and mixing stuff. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2266 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine/AudioBuffer.cpp')
-rw-r--r--src/engine/AudioBuffer.cpp229
1 files changed, 72 insertions, 157 deletions
diff --git a/src/engine/AudioBuffer.cpp b/src/engine/AudioBuffer.cpp
index 53924ae4..1b5a582e 100644
--- a/src/engine/AudioBuffer.cpp
+++ b/src/engine/AudioBuffer.cpp
@@ -18,9 +18,13 @@
#include <iostream>
#include <cassert>
#include <stdlib.h>
+#include "raul/SharedPtr.hpp"
+#include "object.lv2/object.h"
#include "ingen-config.h"
#include "AudioBuffer.hpp"
#include "ProcessContext.hpp"
+#include "LV2Features.hpp"
+#include "LV2URIMap.hpp"
using namespace std;
@@ -32,96 +36,61 @@ namespace Ingen {
using namespace Shared;
-AudioBuffer::AudioBuffer(size_t size)
- : Buffer((size == 1) ? DataType::CONTROL : DataType::AUDIO, size)
- , _data(NULL)
- , _local_data(NULL)
- , _filled_size(0)
+AudioBuffer::AudioBuffer(Shared::DataType type, size_t size)
+ : ObjectBuffer(size + sizeof(LV2_Object)
+ + (type == DataType::AUDIO ? sizeof(LV2_Vector_Body) : 0))
+ , _port_type(type)
, _state(OK)
, _set_value(0)
, _set_time(0)
{
- assert(_size > 0);
- allocate();
+ assert(size >= sizeof(Sample));
+ assert(this->size() > size);
assert(data());
-}
-
-
-void
-AudioBuffer::alloc_local_data(size_t size)
-{
-#ifdef HAVE_POSIX_MEMALIGN
- const int ret = posix_memalign((void**)&_local_data, 16, size * sizeof(Sample));
-#else
- _local_data = (Sample*)malloc(size * sizeof(Sample));
- int ret = (_local_data != NULL) ? 0 : -1;
-#endif
- if (ret != 0) {
- cerr << "[Buffer] Failed to allocate buffer. Aborting." << endl;
- exit(EXIT_FAILURE);
+ _type = type;
+
+ // Control port / Single float object
+ if (type == DataType::CONTROL) {
+ object()->type = 0;//map->float_type;
+
+ // Audio port / Vector of float
+ } else {
+ assert(type == DataType::AUDIO);
+ object()->type = 0;//map->vector_type;
+ LV2_Vector_Body* body = (LV2_Vector_Body*)object()->body;
+ body->elem_count = size / sizeof(Sample);
+ body->elem_type = 0;//map->float_type;
}
-}
-void
-AudioBuffer::resize(size_t size)
-{
- _size = size;
-
- Sample* const old_data = _data;
-
- const bool using_local_data = (_data == _local_data);
-
- deallocate();
- alloc_local_data(_size * sizeof(Sample));
- assert(_local_data);
-
- if (using_local_data)
- _data = _local_data;
- else
- _data = old_data;
-
- set_block(0, 0, _size - 1);
+ /*cout << "Created Audio Buffer" << endl
+ << "\tobject @ " << (void*)object() << endl
+ << "\tbody @ " << (void*)object()->body
+ << "\t(offset " << (char*)object()->body - (char*)object() << ")" << endl
+ << "\tdata @ " << (void*)data()
+ << "\t(offset " << (char*)data() - (char*)object() << ")"
+ << endl;*/
}
-/** Allocate and use a locally managed buffer (data).
- */
void
-AudioBuffer::allocate()
+AudioBuffer::resize(size_t size)
{
- assert(!_joined_buf);
- assert(_local_data == NULL);
- assert(_size > 0);
-
- alloc_local_data(_size * sizeof(Sample));
- assert(_local_data);
-
- _data = _local_data;
-
+ if (_port_type == DataType::AUDIO) {
+ ObjectBuffer::resize(size + sizeof(LV2_Vector_Body));
+ vector()->elem_count = size / sizeof(Sample);
+ }
clear();
}
-/** Free locally allocated buffer.
- */
-void
-AudioBuffer::deallocate()
-{
- assert(!_joined_buf);
- free(_local_data);
- _local_data = NULL;
- _data = NULL;
-}
-
-
/** Empty (ie zero) the buffer.
*/
void
AudioBuffer::clear()
{
- set_block(0, 0, _size - 1);
+ assert(nframes() != 0);
+ set_block(0, 0, nframes() - 1);
_state = OK;
- _filled_size = 0;
}
@@ -134,14 +103,15 @@ AudioBuffer::clear()
void
AudioBuffer::set_value(Sample val, FrameTime cycle_start, FrameTime time)
{
- if (_size == 1)
+ if (_port_type == DataType::CONTROL)
time = cycle_start;
- FrameTime offset = time - cycle_start;
- assert(offset <= _size);
+ const FrameTime offset = time - cycle_start;
+ assert(nframes() != 0);
+ assert(offset <= nframes());
- if (offset < _size) {
- set_block(val, offset, _size - 1);
+ if (offset < nframes()) {
+ set_block(val, offset, nframes() - 1);
if (offset > 0)
_state = HALF_SET_CYCLE_1;
@@ -160,7 +130,7 @@ void
AudioBuffer::set_block(Sample val, size_t start_offset, size_t end_offset)
{
assert(end_offset >= start_offset);
- assert(end_offset < _size);
+ assert(end_offset < nframes());
Sample* const buf = data();
assert(buf);
@@ -170,52 +140,34 @@ AudioBuffer::set_block(Sample val, size_t start_offset, size_t end_offset)
}
-/** Scale a block of buffer by @a val.
- *
- * @a start_sample and @a end_sample define the inclusive range to be set.
- */
-void
-AudioBuffer::scale(Sample val, size_t start_sample, size_t end_sample)
-{
- assert(end_sample >= start_sample);
- assert(end_sample < _size);
-
- Sample* const buf = data();
- assert(buf);
-
- for (size_t i=start_sample; i <= end_sample; ++i)
- buf[i] *= val;
-}
-
-
/** Copy a block of @a src into buffer.
*
* @a start_sample and @a end_sample define the inclusive range to be set.
* This function only copies the same range in one buffer to another.
*/
void
-AudioBuffer::copy(const Buffer* src, size_t start_sample, size_t end_sample)
+AudioBuffer::copy(const Sample* src, size_t start_sample, size_t end_sample)
{
assert(end_sample >= start_sample);
- assert(src);
- assert(src->type() == DataType::CONTROL || DataType::AUDIO);
+ assert(nframes() != 0);
Sample* const buf = data();
assert(buf);
- const Sample* const src_buf = ((AudioBuffer*)src)->data();
- assert(src_buf);
-
- const size_t to_copy = std::min(end_sample, _size - 1);
- for (size_t i = start_sample; i <= to_copy; ++i)
- buf[i] = src_buf[i];
+ const size_t copy_end = std::min(end_sample, (size_t)nframes() - 1);
+ for (size_t i = start_sample; i <= copy_end; ++i)
+ buf[i] = src[i];
}
void
AudioBuffer::copy(Context& context, const Buffer* src)
{
- copy(src, context.start(), std::min(size(), src->size()));
+ if (_type == src->type()) {
+ ObjectBuffer::copy(context, src);
+ } else if (_type == DataType::AUDIO && src->type() == DataType::CONTROL) {
+ set_block(((AudioBuffer*)src)->data()[0], 0, nframes());
+ }
}
@@ -225,66 +177,42 @@ AudioBuffer::copy(Context& context, const Buffer* src)
* This function only adds the same range in one buffer to another.
*/
void
-AudioBuffer::accumulate(const AudioBuffer* const src, size_t start_sample, size_t end_sample)
-{
- assert(end_sample >= start_sample);
- assert(src);
- assert(src->type() == DataType::CONTROL || DataType::AUDIO);
-
- Sample* const buf = data();
- assert(buf);
-
- const Sample* const src_buf = src->data();
- assert(src_buf);
-
- const size_t to_copy = std::min(end_sample, _size - 1);
- for (size_t i = start_sample; i <= to_copy; ++i)
- buf[i] += src_buf[i];
-
-}
-
-
-/** Use another buffer's data instead of the local one.
- *
- * This buffer will essentially be identical to @a buf after this call.
- */
-bool
-AudioBuffer::join(Buffer* buf)
+AudioBuffer::mix(Context& context, const Buffer* const src)
{
- assert(buf != this);
- AudioBuffer* abuf = dynamic_cast<AudioBuffer*>(buf);
- if (!abuf)
- return false;
+ if (src->type() != DataType::CONTROL && src->type() != DataType::AUDIO)
+ return;
- assert(abuf->size() >= _size);
+ AudioBuffer* src_abuf = (AudioBuffer*)src;
- _joined_buf = abuf;
- _filled_size = abuf->filled_size();
+ Sample* const buf = data();
+ const Sample* const src_buf = src_abuf->data();
- assert(_filled_size <= _size);
-
- return true;
-}
+ const size_t frames = std::min(nframes(), src_abuf->nframes());
+ assert(frames != 0);
+ // Mix initial portions
+ SampleCount i = 0;
+ for (; i < frames; ++i)
+ buf[i] += src_buf[i];
-void
-AudioBuffer::unjoin()
-{
- _joined_buf = NULL;
- _data = _local_data;
+ // Extend/Mix the final sample of src if it is shorter
+ const Sample last = src_buf[i - 1];
+ while (i < frames)
+ buf[i++] = last;
}
void
AudioBuffer::prepare_read(Context& context)
{
+ assert(nframes() != 0);
switch (_state) {
case HALF_SET_CYCLE_1:
if (context.start() > _set_time)
_state = HALF_SET_CYCLE_2;
break;
case HALF_SET_CYCLE_2:
- set_block(_set_value, 0, _size - 1);
+ set_block(_set_value, 0, nframes() - 1);
_state = OK;
break;
default:
@@ -293,17 +221,4 @@ AudioBuffer::prepare_read(Context& context)
}
-/** Set the buffer (data) used.
- *
- * This is only to be used by Drivers (to provide zero-copy processing).
- */
-void
-AudioBuffer::set_data(Sample* buf)
-{
- assert(buf);
- assert(!_joined_buf);
- _data = buf;
-}
-
-
} // namespace Ingen