diff options
author | David Robillard <d@drobilla.net> | 2009-11-16 00:30:35 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-11-16 00:30:35 +0000 |
commit | 3d89115a67a9c947a28539ffdd2399808a53279b (patch) | |
tree | 826b900de3979eed9c31aae0d3ac560d39b53460 /src/engine/AudioBuffer.cpp | |
parent | 597fa9212f27d2448c0cdd20fbf616928c662cc1 (diff) | |
download | ingen-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.cpp | 229 |
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 |