From 46e5de590817756b21a7a5d99bd4963df343f455 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 20 Feb 2010 21:52:36 +0000 Subject: Heavy overhaul of buffer management and polyphony. * Working polyphony when nodes are instantiated at desired polyphony level (dynamic still doesn't work) * Use shared silent buffer for disconnected audio inputs (save memory) * Eliminate redundant patch compiling on delete and disconnect-all events that have child events * Fix a ton of crash bugs and other issues I've since forgotten git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2468 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/BufferFactory.cpp | 50 +++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 15 deletions(-) (limited to 'src/engine/BufferFactory.cpp') diff --git a/src/engine/BufferFactory.cpp b/src/engine/BufferFactory.cpp index 39c644e2..83030c70 100644 --- a/src/engine/BufferFactory.cpp +++ b/src/engine/BufferFactory.cpp @@ -35,16 +35,39 @@ using namespace Shared; BufferFactory::BufferFactory(Engine& engine, SharedPtr map) : _engine(engine) , _map(map) + , _silent_buffer(NULL) { } -struct BufferDeleter { - BufferDeleter(BufferFactory& bf) : _factory(bf) {} - void operator()(void* ptr) { - _factory.recycle((Buffer*)ptr); + +void +BufferFactory::set_block_length(SampleCount block_length) +{ + _silent_buffer = create(PortType::AUDIO, audio_buffer_size(block_length)); +} + + +size_t +BufferFactory::audio_buffer_size(SampleCount nframes) +{ + return sizeof(LV2_Object) + sizeof(LV2_Vector_Body) + (nframes * sizeof(float)); +} + + +size_t +BufferFactory::default_buffer_size(PortType type) +{ + switch (type.symbol()) { + case PortType::AUDIO: + return audio_buffer_size(_engine.driver()->block_length()); + case PortType::CONTROL: + return sizeof(LV2_Object) + sizeof(float); + case PortType::EVENTS: + return _engine.driver()->block_length() * event_bytes_per_frame; + default: + return 1024; // Who knows } - BufferFactory& _factory; -}; +} BufferFactory::Ref @@ -67,6 +90,7 @@ BufferFactory::get(Shared::PortType type, size_t size, bool force_create) if (ThreadManager::current_thread_id() != THREAD_PROCESS) { return create(type, size); } else { + assert(false); error << "Failed to obtain buffer" << endl; return Ref(); } @@ -84,36 +108,32 @@ BufferFactory::create(Shared::PortType type, size_t size) Buffer* buffer = NULL; + if (size == 0) + size = default_buffer_size(type); + if (type.is_control()) { - if (size == 0) - size = sizeof(LV2_Object) + sizeof(float); AudioBuffer* ret = new AudioBuffer(*this, type, size); ret->object()->type = _map->object_class_vector.id; ((LV2_Vector_Body*)ret->object()->body)->elem_type = _map->object_class_float32.id; buffer = ret; } else if (type.is_audio()) { - if (size == 0) - size = sizeof(LV2_Object) + sizeof(LV2_Vector_Body) - + _engine.driver()->buffer_size() * sizeof(float); AudioBuffer* ret = new AudioBuffer(*this, type, size); ret->object()->type = _map->object_class_float32.id; buffer = ret; } else if (type.is_events()) { - if (size == 0) - size = _engine.driver()->buffer_size() * 4; // FIXME buffer = new EventBuffer(*this, size); } else if (type.is_value() || type.is_message()) { - if (size == 0) - size = 32; // FIXME buffer = new ObjectBuffer(*this, std::max(size, sizeof(LV2_Object) + sizeof(void*))); } else { error << "Failed to create buffer of unknown type" << endl; return Ref(); } + assert(buffer); return Ref(buffer); } + void BufferFactory::recycle(Buffer* buf) { -- cgit v1.2.1