summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-02-23 03:46:44 +0000
committerDavid Robillard <d@drobilla.net>2010-02-23 03:46:44 +0000
commit3893203399c1b67fb70729558e51f014b863b307 (patch)
tree25ce8cd9847ecc3eec25396d7ae228f8e48af696 /src/engine
parent48eccb2983229c33df9d3858f34a73cb698a4e61 (diff)
downloadingen-3893203399c1b67fb70729558e51f014b863b307.tar.gz
ingen-3893203399c1b67fb70729558e51f014b863b307.tar.bz2
ingen-3893203399c1b67fb70729558e51f014b863b307.zip
Free plugin instances when decreasing polyphony.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2482 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/LADSPANode.cpp32
-rw-r--r--src/engine/LADSPANode.hpp22
-rw-r--r--src/engine/LV2Node.cpp46
-rw-r--r--src/engine/LV2Node.hpp10
4 files changed, 62 insertions, 48 deletions
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<LADSPA_Handle>(poly, *_instances, NULL);
+ _prepared_instances = new Instances(poly, *_instances, SharedPtr<Instance>());
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<Instance>(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<PortImpl*>(_descriptor->PortCount);
- _instances = new Raul::Array<LADSPA_Handle>(_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<Instance>(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<Buffer> buf);
protected:
+ inline LADSPA_Handle instance(uint32_t voice) { return (*_instances)[voice]->handle; }
+
void get_port_limits(unsigned long port_index,
boost::optional<Sample>& default_value,
boost::optional<Sample>& lower_bound,
boost::optional<Sample>& upper_bound);
- const LADSPA_Descriptor* _descriptor;
- Raul::Array<LADSPA_Handle>* _instances;
- Raul::Array<LADSPA_Handle>* _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<Instance> > 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 <cmath>
#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<LV2Info> info = _lv2_plugin->lv2_info();
- _prepared_instances = new Raul::Array<SLV2Instance>(poly, *_instances, NULL);
+ _prepared_instances = new Instances(poly, *_instances, SharedPtr<void>());
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<void>(
+ 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<PortImpl*>(num_ports, NULL);
- _instances = new Raul::Array<SLV2Instance>(_polyphony, NULL);
+ _instances = new Instances(_polyphony, SharedPtr<void>());
_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<void>(
+ 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<Buffer> buf);
protected:
- LV2Plugin* _lv2_plugin;
- Raul::Array<SLV2Instance>* _instances;
- Raul::Array<SLV2Instance>* _prepared_instances;
+ inline SLV2Instance instance(uint32_t voice) { return (SLV2Instance)(*_instances)[voice].get(); }
+
+ typedef Raul::Array< SharedPtr<void> > Instances;
+
+ LV2Plugin* _lv2_plugin;
+ Instances* _instances;
+ Instances* _prepared_instances;
LV2MessageContext* _message_funcs;