From 3893203399c1b67fb70729558e51f014b863b307 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 23 Feb 2010 03:46:44 +0000 Subject: Free plugin instances when decreasing polyphony. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2482 a436a847-0d15-0410-975c-d299462d15a1 --- src/engine/LADSPANode.cpp | 32 ++++++++++++++------------------ src/engine/LADSPANode.hpp | 22 +++++++++++++++++++--- src/engine/LV2Node.cpp | 46 ++++++++++++++++++++++------------------------ src/engine/LV2Node.hpp | 10 +++++++--- 4 files changed, 62 insertions(+), 48 deletions(-) (limited to 'src/engine') diff --git a/src/engine/LADSPANode.cpp b/src/engine/LADSPANode.cpp index abc517fa..80e69162 100644 --- a/src/engine/LADSPANode.cpp +++ b/src/engine/LADSPANode.cpp @@ -60,10 +60,6 @@ LADSPANode::LADSPANode(PluginImpl* plugin, LADSPANode::~LADSPANode() { - if (_instances) - for (uint32_t i = 0; i < _polyphony; ++i) - _descriptor->cleanup((*_instances)[i]); - delete _instances; } @@ -76,15 +72,14 @@ LADSPANode::prepare_poly(BufferFactory& bufs, uint32_t poly) NodeBase::prepare_poly(bufs, poly); - if ( (!_polyphonic) - || (_prepared_instances && poly <= _prepared_instances->size()) ) { + if (_polyphony == poly) return true; - } - _prepared_instances = new Raul::Array(poly, *_instances, NULL); + _prepared_instances = new Instances(poly, *_instances, SharedPtr()); for (uint32_t i = _polyphony; i < _prepared_instances->size(); ++i) { - _prepared_instances->at(i) = _descriptor->instantiate(_descriptor, _srate); - if (_prepared_instances->at(i) == NULL) { + _prepared_instances->at(i) = SharedPtr(new Instance(_descriptor, + _descriptor->instantiate(_descriptor, _srate))); + if (!_prepared_instances->at(i)->handle) { error << "Failed to instantiate plugin" << endl; return false; } @@ -103,7 +98,7 @@ LADSPANode::prepare_poly(BufferFactory& bufs, uint32_t poly) } if (_activated && _descriptor->activate) - _descriptor->activate(_prepared_instances->at(i)); + _descriptor->activate(_prepared_instances->at(i)->handle); } return true; @@ -142,11 +137,12 @@ LADSPANode::instantiate(BufferFactory& bufs) if (!_ports) _ports = new Raul::Array(_descriptor->PortCount); - _instances = new Raul::Array(_polyphony, NULL); + _instances = new Instances(_polyphony); for (uint32_t i = 0; i < _polyphony; ++i) { - (*_instances)[i] = _descriptor->instantiate(_descriptor, _srate); - if ((*_instances)[i] == NULL) { + (*_instances)[i] = SharedPtr(new Instance( + _descriptor, _descriptor->instantiate(_descriptor, _srate))); + if (!instance(i)) { error << "Failed to instantiate plugin" << endl; return false; } @@ -251,7 +247,7 @@ LADSPANode::activate(BufferFactory& bufs) if (_descriptor->activate != NULL) for (uint32_t i = 0; i < _polyphony; ++i) - _descriptor->activate((*_instances)[i]); + _descriptor->activate(instance(i)); } @@ -262,7 +258,7 @@ LADSPANode::deactivate() for (uint32_t i = 0; i < _polyphony; ++i) if (_descriptor->deactivate != NULL) - _descriptor->deactivate((*_instances)[i]); + _descriptor->deactivate(instance(i)); } @@ -272,7 +268,7 @@ LADSPANode::process(ProcessContext& context) NodeBase::pre_process(context); for (uint32_t i = 0; i < _polyphony; ++i) - _descriptor->run((*_instances)[i], context.nframes()); + _descriptor->run(instance(i), context.nframes()); NodeBase::post_process(context); } @@ -283,7 +279,7 @@ LADSPANode::set_port_buffer(uint32_t voice, uint32_t port_num, BufferFactory::Re { NodeBase::set_port_buffer(voice, port_num, buf); - _descriptor->connect_port((*_instances)[voice], port_num, + _descriptor->connect_port(instance(voice), port_num, buf ? (LADSPA_Data*)buf->port_data(_ports->at(port_num)->type()) : NULL); } diff --git a/src/engine/LADSPANode.hpp b/src/engine/LADSPANode.hpp index 91293699..927e6255 100644 --- a/src/engine/LADSPANode.hpp +++ b/src/engine/LADSPANode.hpp @@ -58,14 +58,30 @@ public: void set_port_buffer(uint32_t voice, uint32_t port_num, IntrusivePtr buf); protected: + inline LADSPA_Handle instance(uint32_t voice) { return (*_instances)[voice]->handle; } + void get_port_limits(unsigned long port_index, boost::optional& default_value, boost::optional& lower_bound, boost::optional& upper_bound); - const LADSPA_Descriptor* _descriptor; - Raul::Array* _instances; - Raul::Array* _prepared_instances; + struct Instance { + Instance(const LADSPA_Descriptor* d=NULL, LADSPA_Handle h=NULL) + : descriptor(d), handle(h) + {} + ~Instance() { + if (descriptor && handle) + descriptor->cleanup(handle); + } + const LADSPA_Descriptor* descriptor; + LADSPA_Handle handle; + }; + + typedef Raul::Array< SharedPtr > Instances; + + const LADSPA_Descriptor* _descriptor; + Instances* _instances; + Instances* _prepared_instances; }; diff --git a/src/engine/LV2Node.cpp b/src/engine/LV2Node.cpp index e995bec3..65da2c2c 100644 --- a/src/engine/LV2Node.cpp +++ b/src/engine/LV2Node.cpp @@ -21,6 +21,7 @@ #include #include "raul/log.hpp" #include "raul/Maid.hpp" +#include "raul/Array.hpp" #include "AudioBuffer.hpp" #include "InputPort.hpp" #include "LV2Node.hpp" @@ -60,10 +61,6 @@ LV2Node::LV2Node(LV2Plugin* plugin, LV2Node::~LV2Node() { - if (_instances) - for (uint32_t i = 0; i < _polyphony; ++i) - slv2_instance_free((*_instances)[i]); - delete _instances; } @@ -76,18 +73,18 @@ LV2Node::prepare_poly(BufferFactory& bufs, uint32_t poly) NodeBase::prepare_poly(bufs, poly); - if ( (!_polyphonic) - || (_prepared_instances && poly <= _prepared_instances->size()) ) { + if (_polyphony == poly) return true; - } SharedPtr info = _lv2_plugin->lv2_info(); - _prepared_instances = new Raul::Array(poly, *_instances, NULL); + _prepared_instances = new Instances(poly, *_instances, SharedPtr()); for (uint32_t i = _polyphony; i < _prepared_instances->size(); ++i) { - _prepared_instances->at(i) = slv2_plugin_instantiate( - _lv2_plugin->slv2_plugin(), _srate, _features->array()); + _prepared_instances->at(i) = SharedPtr( + slv2_plugin_instantiate( + _lv2_plugin->slv2_plugin(), _srate, _features->array()), + slv2_instance_free); - if (_prepared_instances->at(i) == NULL) { + if (!_prepared_instances->at(i)) { error << "Failed to instantiate plugin" << endl; return false; } @@ -106,7 +103,7 @@ LV2Node::prepare_poly(BufferFactory& bufs, uint32_t poly) } if (_activated) - slv2_instance_activate(_prepared_instances->at(i)); + slv2_instance_activate((SLV2Instance)(*_prepared_instances)[i].get()); } return true; @@ -149,7 +146,7 @@ LV2Node::instantiate(BufferFactory& bufs) assert(num_ports > 0); _ports = new Raul::Array(num_ports, NULL); - _instances = new Raul::Array(_polyphony, NULL); + _instances = new Instances(_polyphony, SharedPtr()); _features = info->world().lv2_features->lv2_features(this); @@ -157,8 +154,11 @@ LV2Node::instantiate(BufferFactory& bufs) SLV2Value ctx_ext_uri = slv2_value_new_uri(info->lv2_world(), LV2_CONTEXT_MESSAGE); for (uint32_t i = 0; i < _polyphony; ++i) { - (*_instances)[i] = slv2_plugin_instantiate(plug, _srate, _features->array()); - if ((*_instances)[i] == NULL) { + (*_instances)[i] = SharedPtr( + slv2_plugin_instantiate(plug, _srate, _features->array()), + slv2_instance_free); + + if (!instance(i)) { error << "Failed to instantiate plugin" << endl; return false; } @@ -167,7 +167,7 @@ LV2Node::instantiate(BufferFactory& bufs) continue; const void* ctx_ext = slv2_instance_get_extension_data( - (*_instances)[i], LV2_CONTEXT_MESSAGE); + instance(i), LV2_CONTEXT_MESSAGE); if (i == 0 && ctx_ext) { Raul::info << _lv2_plugin->uri() << " has message context" << endl; @@ -324,9 +324,6 @@ LV2Node::instantiate(BufferFactory& bufs) } if (!ret) { - for (uint32_t i = 0; i < _polyphony; ++i) { - slv2_instance_deactivate((*_instances)[i]); - } delete _ports; _ports = NULL; delete _instances; @@ -351,7 +348,7 @@ LV2Node::activate(BufferFactory& bufs) NodeBase::activate(bufs); for (uint32_t i = 0; i < _polyphony; ++i) - slv2_instance_activate((*_instances)[i]); + slv2_instance_activate(instance(i)); } @@ -361,7 +358,7 @@ LV2Node::deactivate() NodeBase::deactivate(); for (uint32_t i = 0; i < _polyphony; ++i) - slv2_instance_deactivate((*_instances)[i]); + slv2_instance_deactivate(instance(i)); } @@ -376,8 +373,9 @@ LV2Node::message_run(MessageContext& context) if (!_valid_ports) _valid_ports = calloc(num_ports() / 8, 1); + if (_message_funcs) - (*_message_funcs->message_run)((*_instances)[0]->lv2_handle, _valid_ports, _valid_ports); + (*_message_funcs->message_run)(instance(0)->lv2_handle, _valid_ports, _valid_ports); } @@ -387,7 +385,7 @@ LV2Node::process(ProcessContext& context) NodeBase::pre_process(context); for (uint32_t i = 0; i < _polyphony; ++i) - slv2_instance_run((*_instances)[i], context.nframes()); + slv2_instance_run(instance(i), context.nframes()); NodeBase::post_process(context); } @@ -397,7 +395,7 @@ void LV2Node::set_port_buffer(uint32_t voice, uint32_t port_num, BufferFactory::Ref buf) { NodeBase::set_port_buffer(voice, port_num, buf); - slv2_instance_connect_port((*_instances)[voice], port_num, + slv2_instance_connect_port(instance(voice), port_num, buf ? buf->port_data(_ports->at(port_num)->type()) : NULL); } diff --git a/src/engine/LV2Node.hpp b/src/engine/LV2Node.hpp index 57ad7998..4d751f32 100644 --- a/src/engine/LV2Node.hpp +++ b/src/engine/LV2Node.hpp @@ -61,9 +61,13 @@ public: void set_port_buffer(uint32_t voice, uint32_t port_num, IntrusivePtr buf); protected: - LV2Plugin* _lv2_plugin; - Raul::Array* _instances; - Raul::Array* _prepared_instances; + inline SLV2Instance instance(uint32_t voice) { return (SLV2Instance)(*_instances)[voice].get(); } + + typedef Raul::Array< SharedPtr > Instances; + + LV2Plugin* _lv2_plugin; + Instances* _instances; + Instances* _prepared_instances; LV2MessageContext* _message_funcs; -- cgit v1.2.1