summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2010-02-17 19:40:36 +0000
committerDavid Robillard <d@drobilla.net>2010-02-17 19:40:36 +0000
commit8aacf1bd969d4aa8bdcc309b11eeface31fe9878 (patch)
tree98684f9ac7b55c0275b195e9d250f694f3fa3460
parent35369ade66f8410e828316a34de539a3c235c79d (diff)
downloadingen-8aacf1bd969d4aa8bdcc309b11eeface31fe9878.tar.gz
ingen-8aacf1bd969d4aa8bdcc309b11eeface31fe9878.tar.bz2
ingen-8aacf1bd969d4aa8bdcc309b11eeface31fe9878.zip
Fix crash when rapidly decreasing polyphony (make SetMetadataEvent blocking if polyphony is changed).
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@2461 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--src/engine/LADSPANode.cpp19
-rw-r--r--src/engine/LV2Node.cpp6
-rw-r--r--src/engine/NodeBase.cpp2
-rw-r--r--src/engine/events/SetMetadata.cpp4
4 files changed, 21 insertions, 10 deletions
diff --git a/src/engine/LADSPANode.cpp b/src/engine/LADSPANode.cpp
index 2a10042a..07920b90 100644
--- a/src/engine/LADSPANode.cpp
+++ b/src/engine/LADSPANode.cpp
@@ -43,7 +43,13 @@ using namespace Shared;
* Object is not usable until instantiate() is called with success.
* (It _will_ crash!)
*/
-LADSPANode::LADSPANode(PluginImpl* plugin, const string& path, bool polyphonic, PatchImpl* parent, const LADSPA_Descriptor* descriptor, SampleRate srate, size_t buffer_size)
+LADSPANode::LADSPANode(PluginImpl* plugin,
+ const string& path,
+ bool polyphonic,
+ PatchImpl* parent,
+ const LADSPA_Descriptor* descriptor,
+ SampleRate srate,
+ size_t buffer_size)
: NodeBase(plugin, path, polyphonic, parent, srate, buffer_size)
, _descriptor(descriptor)
, _instances(NULL)
@@ -55,8 +61,9 @@ LADSPANode::LADSPANode(PluginImpl* plugin, const string& path, bool polyphonic,
LADSPANode::~LADSPANode()
{
- for (uint32_t i=0; i < _polyphony; ++i)
- _descriptor->cleanup((*_instances)[i]);
+ if (_instances)
+ for (uint32_t i=0; i < _polyphony; ++i)
+ _descriptor->cleanup((*_instances)[i]);
delete _instances;
}
@@ -81,9 +88,9 @@ LADSPANode::prepare_poly(BufferFactory& bufs, uint32_t poly)
}
// Initialize the values of new ports
- for (unsigned long j=0; j < num_ports(); ++j) {
- PortImpl* const port = _ports->at(j);
- Buffer* buffer = port->prepared_buffer(i).get();
+ for (uint32_t j = 0; j < num_ports(); ++j) {
+ PortImpl* const port = _ports->at(j);
+ Buffer* const buffer = port->prepared_buffer(i).get();
// FIXME: Preserve individual voice values
if (port->type() == PortType::CONTROL) {
diff --git a/src/engine/LV2Node.cpp b/src/engine/LV2Node.cpp
index 956bf3af..7a8d396e 100644
--- a/src/engine/LV2Node.cpp
+++ b/src/engine/LV2Node.cpp
@@ -91,9 +91,9 @@ LV2Node::prepare_poly(BufferFactory& bufs, uint32_t poly)
}
// Initialize the values of new ports
- for (unsigned long j=0; j < num_ports(); ++j) {
- PortImpl* const port = _ports->at(j);
- Buffer* buffer = port->prepared_buffer(i).get();
+ for (uint32_t j = 0; j < num_ports(); ++j) {
+ PortImpl* const port = _ports->at(j);
+ Buffer* const buffer = port->prepared_buffer(i).get();
// FIXME: Preserve individual voice values
if (port->type() == PortType::CONTROL) {
diff --git a/src/engine/NodeBase.cpp b/src/engine/NodeBase.cpp
index 71e48354..7d07fe5a 100644
--- a/src/engine/NodeBase.cpp
+++ b/src/engine/NodeBase.cpp
@@ -110,7 +110,7 @@ NodeBase::prepare_poly(BufferFactory& bufs, uint32_t poly)
return true;
if (_ports)
- for (size_t i=0; i < _ports->size(); ++i)
+ for (size_t i = 0; i < _ports->size(); ++i)
_ports->at(i)->prepare_poly(bufs, poly);
return true;
diff --git a/src/engine/events/SetMetadata.cpp b/src/engine/events/SetMetadata.cpp
index 5e289928..8095a03c 100644
--- a/src/engine/events/SetMetadata.cpp
+++ b/src/engine/events/SetMetadata.cpp
@@ -216,6 +216,7 @@ SetMetadata::pre_process()
} else if (key == uris.ingen_polyphony) {
if (value.type() == Atom::INT) {
op = POLYPHONY;
+ _blocking = true;
_patch->prepare_internal_poly(*_engine.buffer_factory(), value.get_int32());
} else {
_error = BAD_VALUE_TYPE;
@@ -314,6 +315,9 @@ SetMetadata::execute(ProcessContext& context)
_object->remove_property(p->first, p->second);
QueuedEvent::execute(context);
+
+ if (_blocking)
+ _request->unblock();
}