diff options
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 |