# HG changeset patch # User Chris Cannam # Date 1476710303 -3600 # Node ID 5a1198083d9ae2fed19a54f19be4d793089b7ea1 # Parent 584b2d7d7cd936fef740fa45be911634e1cade2e Pull out model creation into the transformer thread run(), so that all communications with the plugin server happen on a single thread. Then make the model accessor wait for them to be created (which still happens right at the start of processing) before returning. diff -r 584b2d7d7cd9 -r 5a1198083d9a transform/FeatureExtractionModelTransformer.cpp --- a/transform/FeatureExtractionModelTransformer.cpp Fri Oct 14 16:23:04 2016 +0100 +++ b/transform/FeatureExtractionModelTransformer.cpp Mon Oct 17 14:18:23 2016 +0100 @@ -42,17 +42,19 @@ FeatureExtractionModelTransformer::FeatureExtractionModelTransformer(Input in, const Transform &transform) : ModelTransformer(in, transform), - m_plugin(0) + m_plugin(0), + m_haveOutputs(false) { SVDEBUG << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: plugin " << m_transforms.begin()->getPluginIdentifier() << ", outputName " << m_transforms.begin()->getOutput() << endl; - initialise(); +// initialise(); } FeatureExtractionModelTransformer::FeatureExtractionModelTransformer(Input in, const Transforms &transforms) : ModelTransformer(in, transforms), - m_plugin(0) + m_plugin(0), + m_haveOutputs(false) { if (m_transforms.empty()) { SVDEBUG << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: " << transforms.size() << " transform(s)" << endl; @@ -60,7 +62,7 @@ SVDEBUG << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: " << transforms.size() << " transform(s), first has plugin " << m_transforms.begin()->getPluginIdentifier() << ", outputName " << m_transforms.begin()->getOutput() << endl; } - initialise(); +// initialise(); } static bool @@ -104,6 +106,9 @@ return false; } + cerr << "instantiating plugin for transform in thread " + << QThread::currentThreadId() << endl; + m_plugin = factory->instantiatePlugin(pluginId, input->getSampleRate()); if (!m_plugin) { m_message = tr("Failed to instantiate plugin \"%1\"").arg(pluginId); @@ -220,6 +225,11 @@ createOutputModels(j); } + m_outputMutex.lock(); + m_haveOutputs = true; + m_outputsCondition.wakeAll(); + m_outputMutex.unlock(); + return true; } @@ -479,6 +489,16 @@ } } +void +FeatureExtractionModelTransformer::awaitOutputModels() +{ + m_outputMutex.lock(); + while (!m_haveOutputs) { + m_outputsCondition.wait(&m_outputMutex); + } + m_outputMutex.unlock(); +} + FeatureExtractionModelTransformer::~FeatureExtractionModelTransformer() { // SVDEBUG << "FeatureExtractionModelTransformer::~FeatureExtractionModelTransformer()" << endl; @@ -566,6 +586,8 @@ void FeatureExtractionModelTransformer::run() { + initialise(); + DenseTimeValueModel *input = getConformingInput(); if (!input) return; @@ -709,6 +731,9 @@ if (m_abandoned) break; + cerr << "calling process() from thread " + << QThread::currentThreadId() << endl; + Vamp::Plugin::FeatureSet features = m_plugin->process (buffers, RealTime::frame2RealTime(blockFrame, sampleRate).toVampRealTime()); diff -r 584b2d7d7cd9 -r 5a1198083d9a transform/FeatureExtractionModelTransformer.h --- a/transform/FeatureExtractionModelTransformer.h Fri Oct 14 16:23:04 2016 +0100 +++ b/transform/FeatureExtractionModelTransformer.h Mon Oct 17 14:18:23 2016 +0100 @@ -19,6 +19,8 @@ #include "ModelTransformer.h" #include +#include +#include #include @@ -74,7 +76,12 @@ void getFrames(int channelCount, sv_frame_t startFrame, sv_frame_t size, float **buffer); - // just casts + bool m_haveOutputs; + QMutex m_outputMutex; + QWaitCondition m_outputsCondition; + void awaitOutputModels(); + + // just casts: DenseTimeValueModel *getConformingInput(); diff -r 584b2d7d7cd9 -r 5a1198083d9a transform/ModelTransformer.h --- a/transform/ModelTransformer.h Fri Oct 14 16:23:04 2016 +0100 +++ b/transform/ModelTransformer.h Mon Oct 17 14:18:23 2016 +0100 @@ -89,16 +89,20 @@ * be initialised; an error message may be available via * getMessage() in this situation. */ - Models getOutputModels() { return m_outputs; } + Models getOutputModels() { + awaitOutputModels(); + return m_outputs; + } /** * Return the set of output models, also detaching them from the * transformer so that they will not be deleted when the * transformer is. The caller takes ownership of the models. */ - Models detachOutputModels() { + Models detachOutputModels() { + awaitOutputModels(); m_detached = true; - return getOutputModels(); + return m_outputs; } /** @@ -138,6 +142,8 @@ ModelTransformer(Input input, const Transform &transform); ModelTransformer(Input input, const Transforms &transforms); + virtual void awaitOutputModels() = 0; + Transforms m_transforms; Input m_input; // I don't own the model in this Models m_outputs; // I own this, unless... diff -r 584b2d7d7cd9 -r 5a1198083d9a transform/RealTimeEffectModelTransformer.h --- a/transform/RealTimeEffectModelTransformer.h Fri Oct 14 16:23:04 2016 +0100 +++ b/transform/RealTimeEffectModelTransformer.h Mon Oct 17 14:18:23 2016 +0100 @@ -31,6 +31,8 @@ protected: virtual void run(); + virtual void awaitOutputModels() { } // they're created synchronously + QString m_units; RealTimePluginInstance *m_plugin; int m_outputNo;