# HG changeset patch # User Chris Cannam # Date 1391011095 0 # Node ID b109b88bfa8509daa33859444544c06ccfd52447 # Parent 47aa3aeb687b0905956eb34800cde339f5fa11e5 Callback handler for additional models at end of processing diff -r 47aa3aeb687b -r b109b88bfa85 transform/FeatureExtractionModelTransformer.cpp --- a/transform/FeatureExtractionModelTransformer.cpp Wed Jan 29 09:31:22 2014 +0000 +++ b/transform/FeatureExtractionModelTransformer.cpp Wed Jan 29 15:58:15 2014 +0000 @@ -418,8 +418,8 @@ // descriptor to a list of models indexed by bin-1). But we // don't create the additional models yet, as this case has to // work even if the number of bins is unknown at this point -- - // we just create an additional model (copying its parameters - // from the default one) each time a new bin is encountered. + // we create an additional model (copying its parameters from + // the default one) each time a new bin is encountered. if (!haveBinCount || binCount > 1) { m_needAdditionalModels[n] = true; @@ -499,6 +499,17 @@ return mm; } +bool +FeatureExtractionModelTransformer::willHaveAdditionalOutputModels() +{ + for (std::map::const_iterator i = + m_needAdditionalModels.begin(); + i != m_needAdditionalModels.end(); ++i) { + if (i->second) return true; + } + return false; +} + SparseTimeValueModel * FeatureExtractionModelTransformer::getAdditionalModel(int n, int binNo) { @@ -558,7 +569,7 @@ Transform primaryTransform = m_transforms[0]; while (!input->isReady() && !m_abandoned) { - SVDEBUG << "FeatureExtractionModelTransformer::run: Waiting for input model to be ready..." << endl; + cerr << "FeatureExtractionModelTransformer::run: Waiting for input model to be ready..." << endl; usleep(500000); } if (m_abandoned) return; diff -r 47aa3aeb687b -r b109b88bfa85 transform/FeatureExtractionModelTransformer.h --- a/transform/FeatureExtractionModelTransformer.h Wed Jan 29 09:31:22 2014 +0000 +++ b/transform/FeatureExtractionModelTransformer.h Wed Jan 29 15:58:15 2014 +0000 @@ -44,6 +44,10 @@ virtual ~FeatureExtractionModelTransformer(); + // ModelTransformer method, retrieve the additional models + Models getAdditionalOutputModels(); + bool willHaveAdditionalOutputModels(); + protected: bool initialise(); @@ -61,9 +65,6 @@ AdditionalModelMap m_additionalModels; SparseTimeValueModel *getAdditionalModel(int transformNo, int binNo); - // ModelTransformer method, retrieve the additional models - Models getAdditionalOutputModels(); - void addFeature(int n, size_t blockFrame, const Vamp::Plugin::Feature &feature); diff -r 47aa3aeb687b -r b109b88bfa85 transform/ModelTransformer.cpp --- a/transform/ModelTransformer.cpp Wed Jan 29 09:31:22 2014 +0000 +++ b/transform/ModelTransformer.cpp Wed Jan 29 15:58:15 2014 +0000 @@ -18,6 +18,7 @@ ModelTransformer::ModelTransformer(Input input, const Transform &transform) : m_input(input), m_detached(false), + m_detachedAdd(false), m_abandoned(false) { m_transforms.push_back(transform); @@ -27,6 +28,7 @@ m_transforms(transforms), m_input(input), m_detached(false), + m_detachedAdd(false), m_abandoned(false) { } @@ -36,19 +38,12 @@ m_abandoned = true; wait(); if (!m_detached) { - Models mine = getOutputModels(); // including any additional ones - foreach (Model *m, mine) { - delete m; - } + Models mine = getOutputModels(); + foreach (Model *m, mine) delete m; + } + if (!m_detachedAdd) { + Models mine = getAdditionalOutputModels(); + foreach (Model *m, mine) delete m; } } -ModelTransformer::Models -ModelTransformer::getOutputModels() -{ - Models out(m_outputs); - Models add(getAdditionalOutputModels()); - foreach (Model *m, add) out.push_back(m); - return out; -} - diff -r 47aa3aeb687b -r b109b88bfa85 transform/ModelTransformer.h --- a/transform/ModelTransformer.h Wed Jan 29 09:31:22 2014 +0000 +++ b/transform/ModelTransformer.h Wed Jan 29 15:58:15 2014 +0000 @@ -83,14 +83,42 @@ * be initialised; an error message may be available via * getMessage() in this situation. */ - Models getOutputModels(); + Models getOutputModels() { 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() { m_detached = true; return getOutputModels(); } + Models detachOutputModels() { + m_detached = true; + return getOutputModels(); + } + + /** + * Return any additional models that were created during + * processing. This might happen if, for example, a transform was + * configured to split a multi-bin output into separate single-bin + * models as it processed. These should not be queried until after + * the transform has completed. + */ + virtual Models getAdditionalOutputModels() { return Models(); } + + /** + * Return true if the current transform is one that may produce + * additional models (to be retrieved through + * getAdditionalOutputModels above). + */ + virtual bool willHaveAdditionalOutputModels() { return false; } + + /** + * Return the set of additional models, also detaching them from + * the transformer. The caller takes ownership of the models. + */ + virtual Models detachAdditionalOutputModels() { + m_detachedAdd = true; + return getAdditionalOutputModels(); + } /** * Return a warning or error message. If getOutputModel returned @@ -104,18 +132,11 @@ ModelTransformer(Input input, const Transform &transform); ModelTransformer(Input input, const Transforms &transforms); - /** - * Return any additional models that were created during - * processing. This might happen if, for example, a transform was - * configured to split a multi-bin output into separate single-bin - * models as it processed. - */ - virtual Models getAdditionalOutputModels() { return Models(); } - Transforms m_transforms; Input m_input; // I don't own the model in this Models m_outputs; // I own this, unless... bool m_detached; // ... this is true. + bool m_detachedAdd; bool m_abandoned; QString m_message; }; diff -r 47aa3aeb687b -r b109b88bfa85 transform/ModelTransformerFactory.cpp --- a/transform/ModelTransformerFactory.cpp Wed Jan 29 09:31:22 2014 +0000 +++ b/transform/ModelTransformerFactory.cpp Wed Jan 29 15:58:15 2014 +0000 @@ -195,13 +195,14 @@ Model * ModelTransformerFactory::transform(const Transform &transform, const ModelTransformer::Input &input, - QString &message) + QString &message, + AdditionalModelHandler *handler) { SVDEBUG << "ModelTransformerFactory::transform: Constructing transformer with input model " << input.getModel() << endl; Transforms transforms; transforms.push_back(transform); - vector mm = transformMultiple(transforms, input, message); + vector mm = transformMultiple(transforms, input, message, handler); if (mm.empty()) return 0; else return mm[0]; } @@ -209,17 +210,22 @@ vector ModelTransformerFactory::transformMultiple(const Transforms &transforms, const ModelTransformer::Input &input, - QString &message) + QString &message, + AdditionalModelHandler *handler) { SVDEBUG << "ModelTransformerFactory::transformMultiple: Constructing transformer with input model " << input.getModel() << endl; ModelTransformer *t = createTransformer(transforms, input); if (!t) return vector(); - connect(t, SIGNAL(finished()), this, SLOT(transformerFinished())); + if (handler) { + m_handlers[t] = handler; + } m_runningTransformers.insert(t); + connect(t, SIGNAL(finished()), this, SLOT(transformerFinished())); + t->start(); vector models = t->detachOutputModels(); @@ -270,6 +276,14 @@ m_runningTransformers.erase(transformer); + if (m_handlers.find(transformer) != m_handlers.end()) { + if (transformer->willHaveAdditionalOutputModels()) { + vector mm = transformer->detachAdditionalOutputModels(); + m_handlers[transformer]->moreModelsAvailable(mm); + } + m_handlers.erase(transformer); + } + transformer->wait(); // unnecessary but reassuring delete transformer; } diff -r 47aa3aeb687b -r b109b88bfa85 transform/ModelTransformerFactory.h --- a/transform/ModelTransformerFactory.h Wed Jan 29 09:31:22 2014 +0000 +++ b/transform/ModelTransformerFactory.h Wed Jan 29 15:58:15 2014 +0000 @@ -70,6 +70,11 @@ size_t startFrame = 0, size_t duration = 0, UserConfigurator *configurator = 0); + + class AdditionalModelHandler { + public: + virtual void moreModelsAvailable(std::vector models) = 0; + }; /** * Return the output model resulting from applying the named @@ -82,12 +87,21 @@ * problem occurs, return 0. Set message if there is any error or * warning to report. * + * Some transforms may return additional models at the end of + * processing. (For example, a transform that splits an output + * into multiple one-per-bin models.) If an additionalModelHandler + * is provided here, its moreModelsAvailable method will be called + * when those models become available, and ownership of those + * models will be transferred to the handler. Otherwise (if the + * handler is null) any such models will be discarded. + * * The returned model is owned by the caller and must be deleted * when no longer needed. */ Model *transform(const Transform &transform, const ModelTransformer::Input &input, - QString &message); + QString &message, + AdditionalModelHandler *handler = 0); /** * Return the multiple output models resulting from applying the @@ -105,13 +119,22 @@ * for the given transform, or if some other problem occurs, * return 0. Set message if there is any error or warning to * report. - * + * + * Some transforms may return additional models at the end of + * processing. (For example, a transform that splits an output + * into multiple one-per-bin models.) If an additionalModelHandler + * is provided here, its moreModelsAvailable method will be called + * when those models become available, and ownership of those + * models will be transferred to the handler. Otherwise (if the + * handler is null) any such models will be discarded. + * * The returned models are owned by the caller and must be deleted * when no longer needed. */ std::vector transformMultiple(const Transforms &transform, const ModelTransformer::Input &input, - QString &message); + QString &message, + AdditionalModelHandler *handler = 0); protected slots: void transformerFinished(); @@ -128,6 +151,9 @@ typedef std::set TransformerSet; TransformerSet m_runningTransformers; + typedef std::map HandlerMap; + HandlerMap m_handlers; + static ModelTransformerFactory *m_instance; };