changeset 361:399ea254afd6

* Part of #1877436 transform fails to re-run when file loaded at different rate
author Chris Cannam
date Wed, 23 Jan 2008 18:09:50 +0000
parents ac300d385ab2
children cc4eb32efc6c
files plugin/transform/FeatureExtractionModelTransformer.cpp plugin/transform/FeatureExtractionModelTransformer.h plugin/transform/ModelTransformer.h plugin/transform/ModelTransformerFactory.cpp plugin/transform/ModelTransformerFactory.h
diffstat 5 files changed, 90 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/plugin/transform/FeatureExtractionModelTransformer.cpp	Wed Jan 23 15:43:27 2008 +0000
+++ b/plugin/transform/FeatureExtractionModelTransformer.cpp	Wed Jan 23 18:09:50 2008 +0000
@@ -50,21 +50,19 @@
 	FeatureExtractionPluginFactory::instanceFor(pluginId);
 
     if (!factory) {
-	std::cerr << "FeatureExtractionModelTransformer: No factory available for plugin id \""
-		  << pluginId.toStdString() << "\"" << std::endl;
+        m_message = tr("No factory available for feature extraction plugin id \"%1\" (unknown plugin type, or internal error?)").arg(pluginId);
 	return;
     }
 
     DenseTimeValueModel *input = getConformingInput();
     if (!input) {
-        std::cerr << "FeatureExtractionModelTransformer: Input model not conformable" << std::endl;
+        m_message = tr("Input model for feature extraction plugin \"%1\" is of wrong type (internal error?)").arg(pluginId);
         return;
     }
 
     m_plugin = factory->instantiatePlugin(pluginId, input->getSampleRate());
     if (!m_plugin) {
-	std::cerr << "FeatureExtractionModelTransformer: Failed to instantiate plugin \""
-		  << pluginId.toStdString() << "\"" << std::endl;
+        m_message = tr("Failed to instantiate plugin \"%1\"").arg(pluginId);
 	return;
     }
 
@@ -79,11 +77,11 @@
 	channelCount = 1;
     }
     if (m_plugin->getMinChannelCount() > channelCount) {
-	std::cerr << "FeatureExtractionModelTransformer:: "
-		  << "Can't provide enough channels to plugin (plugin min "
-		  << m_plugin->getMinChannelCount() << ", max "
-		  << m_plugin->getMaxChannelCount() << ", input model has "
-		  << input->getChannelCount() << ")" << std::endl;
+        m_message = tr("Cannot provide enough channels to feature extraction plugin \"%1\" (plugin min is %2, max %3; input model has %4)")
+            .arg(pluginId)
+            .arg(m_plugin->getMinChannelCount())
+            .arg(m_plugin->getMaxChannelCount())
+            .arg(input->getChannelCount());
 	return;
     }
 
@@ -94,16 +92,46 @@
     if (!m_plugin->initialise(channelCount,
                               m_transform.getStepSize(),
                               m_transform.getBlockSize())) {
-        std::cerr << "FeatureExtractionModelTransformer: Plugin "
-                  << pluginId.toStdString() << " failed to initialise!" << std::endl;
-        return;
+
+        size_t pstep = m_transform.getStepSize();
+        size_t pblock = m_transform.getBlockSize();
+
+        m_transform.setStepSize(0);
+        m_transform.setBlockSize(0);
+        TransformFactory::getInstance()->makeContextConsistentWithPlugin
+            (m_transform, m_plugin);
+
+        if (m_transform.getStepSize() != pstep ||
+            m_transform.getBlockSize() != pblock) {
+            
+            if (!m_plugin->initialise(channelCount,
+                                      m_transform.getStepSize(),
+                                      m_transform.getBlockSize())) {
+
+                m_message = tr("Failed to initialise feature extraction plugin \"%1\"").arg(pluginId);
+                return;
+
+            } else {
+
+                m_message = tr("Feature extraction plugin \"%1\" rejected the given step and block sizes (%2 and %3); using plugin defaults (%4 and %5) instead")
+                    .arg(pluginId)
+                    .arg(pstep)
+                    .arg(pblock)
+                    .arg(m_transform.getStepSize())
+                    .arg(m_transform.getBlockSize());
+            }
+
+        } else {
+
+            m_message = tr("Failed to initialise feature extraction plugin \"%1\"").arg(pluginId);
+            return;
+        }
     }
 
     Vamp::Plugin::OutputList outputs = m_plugin->getOutputDescriptors();
 
     if (outputs.empty()) {
-	std::cerr << "FeatureExtractionModelTransformer: Plugin \""
-		  << pluginId.toStdString() << "\" has no outputs" << std::endl;
+        m_message = tr("Plugin \"%1\" has no outputs").arg(pluginId);
 	return;
     }
     
@@ -118,9 +146,9 @@
     }
 
     if (!m_descriptor) {
-	std::cerr << "FeatureExtractionModelTransformer: Plugin \""
-		  << pluginId.toStdString() << "\" has no output named \""
-		  << m_transform.getOutput().toStdString() << "\"" << std::endl;
+        m_message = tr("Plugin \"%1\" has no output named \"%2\"")
+            .arg(pluginId)
+            .arg(m_transform.getOutput());
 	return;
     }
 
--- a/plugin/transform/FeatureExtractionModelTransformer.h	Wed Jan 23 15:43:27 2008 +0000
+++ b/plugin/transform/FeatureExtractionModelTransformer.h	Wed Jan 23 18:09:50 2008 +0000
@@ -18,6 +18,8 @@
 
 #include "ModelTransformer.h"
 
+#include <QString>
+
 #include <vamp-sdk/Plugin.h>
 
 #include <iostream>
--- a/plugin/transform/ModelTransformer.h	Wed Jan 23 15:43:27 2008 +0000
+++ b/plugin/transform/ModelTransformer.h	Wed Jan 23 18:09:50 2008 +0000
@@ -56,17 +56,47 @@
         int m_channel;
     };
 
-    // Just a hint to the processing thread that it should give up.
-    // Caller should still wait() and/or delete the transform before
-    // assuming its input and output models are no longer required.
+    /**
+     * Hint to the processing thread that it should give up, for
+     * example because the process is going to exit or we want to get
+     * rid of the input model.  Caller should still wait() and/or
+     * delete the transform before assuming its input and output
+     * models are no longer required.
+     */
     void abandon() { m_abandoned = true; }
 
+    /**
+     * Return the input model for the transform.
+     */
     Model *getInputModel()  { return m_input.getModel(); }
+
+    /**
+     * Return the input channel spec for the transform.
+     */
     int getInputChannel() { return m_input.getChannel(); }
 
+    /**
+     * Return the output model created by the transform.  Returns a
+     * null model if the transform could not be initialised; an error
+     * message may be available via getMessage() in this situation.
+     */
     Model *getOutputModel() { return m_output; }
+
+    /**
+     * Return the output model, also detaching it from the transformer
+     * so that it will not be deleted when the transformer is.  The
+     * caller takes ownership of the model.
+     */
     Model *detachOutputModel() { m_detached = true; return m_output; }
 
+    /**
+     * Return a warning or error message.  If getOutputModel returned
+     * a null pointer, this should contain a fatal error message for
+     * the transformer; otherwise it may contain a warning to show to
+     * the user about e.g. suboptimal block size or whatever.  
+     */
+    QString getMessage() const { return m_message; }
+
 protected:
     ModelTransformer(Input input, const Transform &transform);
 
@@ -75,6 +105,7 @@
     Model *m_output; // I own this, unless...
     bool m_detached; // ... this is true.
     bool m_abandoned;
+    QString m_message;
 };
 
 #endif
--- a/plugin/transform/ModelTransformerFactory.cpp	Wed Jan 23 15:43:27 2008 +0000
+++ b/plugin/transform/ModelTransformerFactory.cpp	Wed Jan 23 18:09:50 2008 +0000
@@ -358,7 +358,8 @@
 
 Model *
 ModelTransformerFactory::transform(const Transform &transform,
-                                   const ModelTransformer::Input &input)
+                                   const ModelTransformer::Input &input,
+                                   QString &message)
 {
     ModelTransformer *t = createTransformer(transform, input);
     if (!t) return 0;
@@ -388,6 +389,8 @@
         t->wait();
     }
 
+    message = t->getMessage();
+
     return model;
 }
 
--- a/plugin/transform/ModelTransformerFactory.h	Wed Jan 23 15:43:27 2008 +0000
+++ b/plugin/transform/ModelTransformerFactory.h	Wed Jan 23 18:09:50 2008 +0000
@@ -54,14 +54,6 @@
                                  size_t duration = 0);
     
     /**
-     * Get the default execution context for the given transform
-     * and input model (if known).
-     */
-/*!!!
-    PluginTransformer::ExecutionContext getDefaultContextForTransformer(TransformId identifier,
-                                                                        Model *inputModel = 0);
-*/
-    /**
      * Return the output model resulting from applying the named
      * transform to the given input model.  The transform may still be
      * working in the background when the model is returned; check the
@@ -69,13 +61,15 @@
      *
      * If the transform is unknown or the input model is not an
      * appropriate type for the given transform, or if some other
-     * problem occurs, return 0.
+     * problem occurs, return 0.  Set message if there is any error or
+     * warning to report.
      * 
      * 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);
+                     const ModelTransformer::Input &input,
+                     QString &message);
 
 protected slots:
     void transformerFinished();