[Sv1-commits] SF.net SVN: sv1: [894] sonic-visualiser/trunk
Brought to you by:
cannam
From: <ca...@us...> - 2007-12-07 16:47:34
|
Revision: 894 http://sv1.svn.sourceforge.net/sv1/?rev=894&view=rev Author: cannam Date: 2007-12-07 08:47:31 -0800 (Fri, 07 Dec 2007) Log Message: ----------- * Merge from transforms branch -- switch over to using Transform object properly Modified Paths: -------------- sonic-visualiser/trunk/base/RealTime.cpp sonic-visualiser/trunk/base/RealTime.h sonic-visualiser/trunk/base/Window.h sonic-visualiser/trunk/framework/Document.cpp sonic-visualiser/trunk/framework/Document.h sonic-visualiser/trunk/framework/SVFileReader.cpp sonic-visualiser/trunk/framework/SVFileReader.h sonic-visualiser/trunk/plugin/plugin.pro sonic-visualiser/trunk/plugin/transform/FeatureExtractionModelTransformer.cpp sonic-visualiser/trunk/plugin/transform/FeatureExtractionModelTransformer.h sonic-visualiser/trunk/plugin/transform/ModelTransformer.cpp sonic-visualiser/trunk/plugin/transform/ModelTransformer.h sonic-visualiser/trunk/plugin/transform/ModelTransformerFactory.cpp sonic-visualiser/trunk/plugin/transform/ModelTransformerFactory.h sonic-visualiser/trunk/plugin/transform/RealTimeEffectModelTransformer.cpp sonic-visualiser/trunk/plugin/transform/RealTimeEffectModelTransformer.h sonic-visualiser/trunk/plugin/transform/Transform.cpp sonic-visualiser/trunk/plugin/transform/Transform.h sonic-visualiser/trunk/plugin/transform/TransformDescription.h sonic-visualiser/trunk/plugin/transform/TransformFactory.cpp sonic-visualiser/trunk/plugin/transform/TransformFactory.h sonic-visualiser/trunk/sv/main/MainWindow.cpp sonic-visualiser/trunk/sv/main/OSCHandler.cpp sonic-visualiser/trunk/sv.prf Removed Paths: ------------- sonic-visualiser/trunk/plugin/transform/PluginTransformer.cpp sonic-visualiser/trunk/plugin/transform/PluginTransformer.h Modified: sonic-visualiser/trunk/base/RealTime.cpp =================================================================== --- sonic-visualiser/trunk/base/RealTime.cpp 2007-12-07 16:45:27 UTC (rev 893) +++ sonic-visualiser/trunk/base/RealTime.cpp 2007-12-07 16:47:31 UTC (rev 894) @@ -122,6 +122,51 @@ return s.substr(0, s.length() - 1); } +RealTime +RealTime::fromString(std::string s) +{ + bool negative = false; + bool faulty = false; + bool section = 0; + std::string ssec, snsec; + + for (size_t i = 0; i < s.length(); ++i) { + + char c = s[i]; + if (isspace(c)) continue; + + if (section == 0) { + + if (c == '-') negative = true; + else if (isdigit(c)) { section = 1; ssec += c; } + else if (c == '.') section = 2; + else break; + + } else if (section == 1) { + + if (c == '.') section = 2; + else if (isdigit(c)) ssec += c; + else break; + + } else if (section == 2) { + + if (isdigit(c)) snsec += c; + else break; + } + } + + while (snsec.length() < 8) snsec += '0'; + + int sec = atoi(ssec.c_str()); + int nsec = atoi(snsec.c_str()); + if (negative) sec = -sec; + + std::cerr << "RealTime::fromString: string " << s << " -> " + << sec << " sec, " << nsec << " nsec" << std::endl; + + return RealTime(sec, nsec); +} + std::string RealTime::toText(bool fixedDp) const { Modified: sonic-visualiser/trunk/base/RealTime.h =================================================================== --- sonic-visualiser/trunk/base/RealTime.h 2007-12-07 16:45:27 UTC (rev 893) +++ sonic-visualiser/trunk/base/RealTime.h 2007-12-07 16:47:31 UTC (rev 894) @@ -95,30 +95,45 @@ RealTime operator*(int m) const; RealTime operator/(int d) const; - // Find the fractional difference between times - // + /** + * Return the ratio of two times. + */ double operator/(const RealTime &r) const; - // Return a human-readable debug-type string to full precision - // (probably not a format to show to a user directly). If align - // is true, prepend " " to the start of positive values so that - // they line up with negative ones (which start with "-"). - // + /** + * Return a human-readable debug-type string to full precision + * (probably not a format to show to a user directly). If align + * is true, prepend " " to the start of positive values so that + * they line up with negative ones (which start with "-"). + */ std::string toString(bool align = false) const; - // Return a user-readable string to the nearest millisecond - // in a form like HH:MM:SS.mmm - // + /** + * Convert a string as obtained from toString back to a RealTime + * object. + */ + static RealTime fromString(std::string); + + /** + * Return a user-readable string to the nearest millisecond, in a + * form like HH:MM:SS.mmm + */ std::string toText(bool fixedDp = false) const; - // Return a user-readable string to the nearest second in a form - // like "6s" (for less than a minute) or "2:21" (for more). - // + /** + * Return a user-readable string to the nearest second, in a form + * like "6s" (for less than a minute) or "2:21" (for more). + */ std::string toSecText() const; - // Convenience functions for handling sample frames - // + /** + * Convert a RealTime into a sample frame at the given sample rate. + */ static long realTime2Frame(const RealTime &r, unsigned int sampleRate); + + /** + * Convert a sample frame at the given sample rate into a RealTime. + */ static RealTime frame2RealTime(long frame, unsigned int sampleRate); static const RealTime zeroTime; Modified: sonic-visualiser/trunk/base/Window.h =================================================================== --- sonic-visualiser/trunk/base/Window.h 2007-12-07 16:45:27 UTC (rev 893) +++ sonic-visualiser/trunk/base/Window.h 2007-12-07 16:47:31 UTC (rev 894) @@ -18,6 +18,7 @@ #include <cmath> #include <iostream> +#include <string> #include <map> enum WindowType { @@ -61,6 +62,12 @@ WindowType getType() const { return m_type; } size_t getSize() const { return m_size; } + // The names used by these functions are un-translated, for use in + // e.g. XML I/O. Use Preferences::getPropertyValueLabel if you + // want translated names for use in the user interface. + static std::string getNameForType(WindowType type); + static WindowType getTypeForName(std::string name); + protected: WindowType m_type; size_t m_size; @@ -159,4 +166,46 @@ } } +template <typename T> +std::string +Window<T>::getNameForType(WindowType type) +{ + switch (type) { + case RectangularWindow: return "rectangular"; + case BartlettWindow: return "bartlett"; + case HammingWindow: return "hamming"; + case HanningWindow: return "hanning"; + case BlackmanWindow: return "blackman"; + case GaussianWindow: return "gaussian"; + case ParzenWindow: return "parzen"; + case NuttallWindow: return "nuttall"; + case BlackmanHarrisWindow: return "blackman-harris"; + } + + std::cerr << "WARNING: Window::getNameForType: unknown type " + << type << std::endl; + + return "unknown"; +} + +template <typename T> +WindowType +Window<T>::getTypeForName(std::string name) +{ + if (name == "rectangular") return RectangularWindow; + if (name == "bartlett") return BartlettWindow; + if (name == "hamming") return HammingWindow; + if (name == "hanning") return HanningWindow; + if (name == "blackman") return BlackmanWindow; + if (name == "gaussian") return GaussianWindow; + if (name == "parzen") return ParzenWindow; + if (name == "nuttall") return NuttallWindow; + if (name == "blackman-harris") return BlackmanHarrisWindow; + + std::cerr << "WARNING: Window::getTypeForName: unknown name \"" + << name << "\", defaulting to \"hanning\"" << std::endl; + + return HanningWindow; +} + #endif Modified: sonic-visualiser/trunk/framework/Document.cpp =================================================================== --- sonic-visualiser/trunk/framework/Document.cpp 2007-12-07 16:45:27 UTC (rev 893) +++ sonic-visualiser/trunk/framework/Document.cpp 2007-12-07 16:47:31 UTC (rev 894) @@ -190,16 +190,13 @@ } Layer * -Document::createDerivedLayer(TransformId transform, - Model *inputModel, - const PluginTransformer::ExecutionContext &context, - QString configurationXml) +Document::createDerivedLayer(const Transform &transform, + const ModelTransformer::Input &input) { - Model *newModel = addDerivedModel(transform, inputModel, - context, configurationXml); + Model *newModel = addDerivedModel(transform, input); if (!newModel) { // error already printed to stderr by addDerivedModel - emit modelGenerationFailed(transform); + emit modelGenerationFailed(transform.getIdentifier()); return 0; } @@ -207,7 +204,7 @@ LayerFactory::getInstance()->getValidLayerTypes(newModel); if (types.empty()) { - std::cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << transform.toStdString() << std::endl; + std::cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << transform.getIdentifier().toStdString() << std::endl; delete newModel; return 0; } @@ -235,7 +232,8 @@ if (newLayer) { newLayer->setObjectName(getUniqueLayerName (TransformFactory::getInstance()-> - getTransformFriendlyName(transform))); + getTransformFriendlyName + (transform.getIdentifier()))); } emit layerAdded(newLayer); @@ -293,22 +291,26 @@ // This model was derived from the previous main // model: regenerate it. - TransformId transform = m_models[model].transform; - PluginTransformer::ExecutionContext context = m_models[model].context; + const Transform &transform = m_models[model].transform; + QString transformId = transform.getIdentifier(); + //!!! We have a problem here if the number of channels in + //the main model has changed. + Model *replacementModel = addDerivedModel(transform, - m_mainModel, - context, - m_models[model].configurationXml); + ModelTransformer::Input + (m_mainModel, + m_models[model].channel)); if (!replacementModel) { std::cerr << "WARNING: Document::setMainModel: Failed to regenerate model for transform \"" - << transform.toStdString() << "\"" << " in layer " << layer << std::endl; - if (failedTransformers.find(transform) == failedTransformers.end()) { + << transformId.toStdString() << "\"" << " in layer " << layer << std::endl; + if (failedTransformers.find(transformId) + == failedTransformers.end()) { emit modelRegenerationFailed(layer->objectName(), - transform); - failedTransformers.insert(transform); + transformId); + failedTransformers.insert(transformId); } obsoleteLayers.push_back(layer); } else { @@ -348,11 +350,9 @@ } void -Document::addDerivedModel(TransformId transform, - Model *inputModel, - const PluginTransformer::ExecutionContext &context, - Model *outputModelToAdd, - QString configurationXml) +Document::addDerivedModel(const Transform &transform, + const ModelTransformer::Input &input, + Model *outputModelToAdd) { if (m_models.find(outputModelToAdd) != m_models.end()) { std::cerr << "WARNING: Document::addDerivedModel: Model already added" @@ -363,13 +363,12 @@ // std::cerr << "Document::addDerivedModel: source is " << inputModel << " \"" << inputModel->objectName().toStdString() << "\"" << std::endl; ModelRecord rec; - rec.source = inputModel; + rec.source = input.getModel(); + rec.channel = input.getChannel(); rec.transform = transform; - rec.context = context; - rec.configurationXml = configurationXml; rec.refcount = 0; - outputModelToAdd->setSourceModel(inputModel); + outputModelToAdd->setSourceModel(input.getModel()); m_models[outputModelToAdd] = rec; @@ -388,7 +387,6 @@ ModelRecord rec; rec.source = 0; - rec.transform = ""; rec.refcount = 0; m_models[model] = rec; @@ -399,29 +397,25 @@ } Model * -Document::addDerivedModel(TransformId transform, - Model *inputModel, - const PluginTransformer::ExecutionContext &context, - QString configurationXml) +Document::addDerivedModel(const Transform &transform, + const ModelTransformer::Input &input) { Model *model = 0; for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { if (i->second.transform == transform && - i->second.source == inputModel && - i->second.context == context && - i->second.configurationXml == configurationXml) { + i->second.source == input.getModel() && + i->second.channel == input.getChannel()) { return i->first; } } - model = ModelTransformerFactory::getInstance()->transform - (transform, inputModel, context, configurationXml); + model = ModelTransformerFactory::getInstance()->transform(transform, input); if (!model) { - std::cerr << "WARNING: Document::addDerivedModel: no output model for transform " << transform.toStdString() << std::endl; + std::cerr << "WARNING: Document::addDerivedModel: no output model for transform " << transform.getIdentifier().toStdString() << std::endl; } else { - addDerivedModel(transform, inputModel, context, model, configurationXml); + addDerivedModel(transform, input, model); } return model; @@ -665,7 +659,7 @@ } std::vector<Model *> -Document::getTransformerInputModels() +Document::getTransformInputModels() { std::vector<Model *> models; @@ -737,21 +731,26 @@ Model *aggregate = new AggregateWaveModel(components); - TransformId id = "vamp:match-vamp-plugin:match:path"; + TransformId id = "vamp:match-vamp-plugin:match:path"; //!!! configure - ModelTransformerFactory *factory = ModelTransformerFactory::getInstance(); + TransformFactory *tf = TransformFactory::getInstance(); - PluginTransformer::ExecutionContext context = - factory->getDefaultContextForTransformer(id, aggregate); - context.stepSize = context.blockSize/2; + Transform transform = tf->getDefaultTransformFor + (id, aggregate->getSampleRate()); - QString args = "<plugin param-serialise=\"1\"/>"; + transform.setStepSize(transform.getBlockSize()/2); + transform.setParameter("serialise", 1); - Model *transformOutput = factory->transform(id, aggregate, context, args); +//!!! QString args = "<plugin param-serialise=\"1\"/>"; +// Model *transformOutput = factory->transform(id, aggregate, context, args); + ModelTransformerFactory *mtf = ModelTransformerFactory::getInstance(); + + Model *transformOutput = mtf->transform(transform, aggregate); + if (!transformOutput) { - context.stepSize = 0; - transformOutput = factory->transform(id, aggregate, context, args); + transform.setStepSize(0); + transformOutput = mtf->transform(transform, aggregate); } SparseTimeValueModel *path = dynamic_cast<SparseTimeValueModel *> @@ -926,7 +925,7 @@ bool writeModel = true; bool haveDerivation = false; - if (rec.source && rec.transform != "") { + if (rec.source && rec.transform.getIdentifier() != "") { haveDerivation = true; } @@ -943,33 +942,8 @@ } if (haveDerivation) { - - QString extentsAttributes; - if (rec.context.startFrame != 0 || - rec.context.duration != 0) { - extentsAttributes = QString("startFrame=\"%1\" duration=\"%2\" ") - .arg(rec.context.startFrame) - .arg(rec.context.duration); - } - - out << indent; - out << QString(" <derivation source=\"%1\" model=\"%2\" channel=\"%3\" domain=\"%4\" stepSize=\"%5\" blockSize=\"%6\" %7windowType=\"%8\" transform=\"%9\"") - .arg(XmlExportable::getObjectExportId(rec.source)) - .arg(XmlExportable::getObjectExportId(i->first)) - .arg(rec.context.channel) - .arg(rec.context.domain) - .arg(rec.context.stepSize) - .arg(rec.context.blockSize) - .arg(extentsAttributes) - .arg(int(rec.context.windowType)) - .arg(XmlExportable::encodeEntities(rec.transform)); - - if (rec.configurationXml != "") { - out << ">\n " + indent + rec.configurationXml - + "\n" + indent + " </derivation>\n"; - } else { - out << "/>\n"; - } + writeBackwardCompatibleDerivation(out, indent + " ", + i->first, rec); } //!!! We should probably own the PlayParameterRepository @@ -992,4 +966,82 @@ out << indent + "</data>\n"; } +void +Document::writeBackwardCompatibleDerivation(QTextStream &out, QString indent, + Model *targetModel, + const ModelRecord &rec) const +{ + // There is a lot of redundancy in the XML we output here, because + // we want it to work with older SV session file reading code as + // well. + // + // Formerly, a transform was described using a derivation element + // which set out the source and target models, execution context + // (step size, input channel etc) and transform id, containing a + // plugin element which set out the transform parameters and so + // on. (The plugin element came from a "configurationXml" string + // obtained from PluginXml.) + // + // This has been replaced by a derivation element setting out the + // source and target models and input channel, containing a + // transform element which sets out everything in the Transform. + // + // In order to retain compatibility with older SV code, however, + // we have to write out the same stuff into the derivation as + // before, and manufacture an appropriate plugin element as well + // as the transform element. In order that newer code knows it's + // dealing with a newer format, we will also write an attribute + // 'type="transform"' in the derivation element. + const Transform &transform = rec.transform; + + // Just for reference, this is what we would write if we didn't + // have to be backward compatible: + // + // out << indent + // << QString("<derivation type=\"transform\" source=\"%1\" " + // "model=\"%2\" channel=\"%3\">\n") + // .arg(XmlExportable::getObjectExportId(rec.source)) + // .arg(XmlExportable::getObjectExportId(targetModel)) + // .arg(rec.channel); + // + // transform.toXml(out, indent + " "); + // + // out << indent << "</derivation>\n"; + // + // Unfortunately, we can't just do that. So we do this... + + QString extentsAttributes; + if (transform.getStartTime() != RealTime::zeroTime || + transform.getDuration() != RealTime::zeroTime) { + extentsAttributes = QString("startFrame=\"%1\" duration=\"%2\" ") + .arg(RealTime::realTime2Frame(transform.getStartTime(), + targetModel->getSampleRate())) + .arg(RealTime::realTime2Frame(transform.getDuration(), + targetModel->getSampleRate())); + } + + out << indent; + out << QString("<derivation type=\"transform\" source=\"%1\" " + "model=\"%2\" channel=\"%3\" domain=\"%4\" " + "stepSize=\"%5\" blockSize=\"%6\" %7windowType=\"%8\" " + "transform=\"%9\">\n") + .arg(XmlExportable::getObjectExportId(rec.source)) + .arg(XmlExportable::getObjectExportId(targetModel)) + .arg(rec.channel) + .arg(TransformFactory::getInstance()->getTransformInputDomain + (transform.getIdentifier())) + .arg(transform.getStepSize()) + .arg(transform.getBlockSize()) + .arg(extentsAttributes) + .arg(int(transform.getWindowType())) + .arg(XmlExportable::encodeEntities(transform.getIdentifier())); + + transform.toXml(out, indent + " "); + + out << indent << " " + << TransformFactory::getInstance()->getPluginConfigurationXml(transform); + + out << indent << "</derivation>\n"; +} + Modified: sonic-visualiser/trunk/framework/Document.h =================================================================== --- sonic-visualiser/trunk/framework/Document.h 2007-12-07 16:45:27 UTC (rev 893) +++ sonic-visualiser/trunk/framework/Document.h 2007-12-07 16:47:31 UTC (rev 894) @@ -18,7 +18,6 @@ #include "layer/LayerFactory.h" #include "plugin/transform/Transform.h" -#include "plugin/transform/PluginTransformer.h"//!!! #include "plugin/transform/ModelTransformer.h" #include "base/Command.h" @@ -114,10 +113,8 @@ * running the transform and associating the resulting model with * the new layer. */ - Layer *createDerivedLayer(TransformId, - Model *inputModel, - const PluginTransformer::ExecutionContext &context, - QString configurationXml); + Layer *createDerivedLayer(const Transform &, + const ModelTransformer::Input &); /** * Delete the given layer, and also its associated model if no @@ -144,27 +141,23 @@ */ const WaveFileModel *getMainModel() const { return m_mainModel; } - std::vector<Model *> getTransformerInputModels(); + std::vector<Model *> getTransformInputModels(); /** * Add a derived model associated with the given transform, * running the transform and returning the resulting model. */ - Model *addDerivedModel(TransformId transform, - Model *inputModel, - const PluginTransformer::ExecutionContext &context, - QString configurationXml); + Model *addDerivedModel(const Transform &transform, + const ModelTransformer::Input &input); /** * Add a derived model associated with the given transform. This * is necessary to register any derived model that was not created * by the document using createDerivedModel or createDerivedLayer. */ - void addDerivedModel(TransformId, - Model *inputModel, - const PluginTransformer::ExecutionContext &context, - Model *outputModelToAdd, - QString configurationXml); + void addDerivedModel(const Transform &transform, + const ModelTransformer::Input &input, + Model *outputModelToAdd); /** * Add an imported (non-derived, non-main) model. This is @@ -267,10 +260,14 @@ // transform name is set but source is NULL, then there was a // transform involved but the (target) model has been modified // since being generated from it. + + // This does not use ModelTransformer::Input, because it would + // be confusing to have Input objects hanging around with NULL + // models in them. + const Model *source; - TransformId transform; - PluginTransformer::ExecutionContext context; - QString configurationXml; + int channel; + Transform transform; // Count of the number of layers using this model. int refcount; @@ -322,6 +319,8 @@ void removeFromLayerViewMap(Layer *, View *); QString getUniqueLayerName(QString candidate); + void writeBackwardCompatibleDerivation(QTextStream &, QString, Model *, + const ModelRecord &) const; /** * And these are the layers. We also control the lifespans of Modified: sonic-visualiser/trunk/framework/SVFileReader.cpp =================================================================== --- sonic-visualiser/trunk/framework/SVFileReader.cpp 2007-12-07 16:45:27 UTC (rev 893) +++ sonic-visualiser/trunk/framework/SVFileReader.cpp 2007-12-07 16:47:31 UTC (rev 894) @@ -32,6 +32,8 @@ #include "data/model/TextModel.h" #include "data/model/ImageModel.h" +#include "plugin/transform/TransformFactory.h" + #include "view/Pane.h" #include "Document.h" @@ -53,6 +55,7 @@ m_currentDerivedModel(0), m_currentDerivedModelId(-1), m_currentPlayParameters(0), + m_currentTransformSource(0), m_datasetSeparator(" "), m_inRow(false), m_inLayer(false), @@ -136,6 +139,11 @@ // row // view // window + // plugin + // transform + // selections + // selection + // measurement if (name == "sv") { @@ -212,6 +220,14 @@ ok = readMeasurement(attributes); + } else if (name == "transform") { + + ok = readTransform(attributes); + + } else if (name == "parameter") { + + ok = readParameter(attributes); + } else { std::cerr << "WARNING: SV-XML: Unexpected element \"" << name.toLocal8Bit().data() << "\"" << std::endl; @@ -286,24 +302,25 @@ << " as target, not regenerating" << std::endl; } else { m_currentDerivedModel = m_models[m_currentDerivedModelId] = - m_document->addDerivedModel(m_currentTransformer, - m_currentTransformerSource, - m_currentTransformerContext, - m_currentTransformerConfiguration); + m_document->addDerivedModel + (m_currentTransform, + ModelTransformer::Input(m_currentTransformSource, + m_currentTransformChannel)); } } else { - m_document->addDerivedModel(m_currentTransformer, - m_currentTransformerSource, - m_currentTransformerContext, - m_currentDerivedModel, - m_currentTransformerConfiguration); + m_document->addDerivedModel + (m_currentTransform, + ModelTransformer::Input(m_currentTransformSource, + m_currentTransformChannel), + m_currentDerivedModel); } m_addedModels.insert(m_currentDerivedModel); m_currentDerivedModel = 0; m_currentDerivedModelId = -1; - m_currentTransformer = ""; - m_currentTransformerConfiguration = ""; + m_currentTransformSource = 0; + m_currentTransform = Transform(); + m_currentTransformChannel = -1; } else if (name == "row") { m_inRow = false; @@ -993,8 +1010,6 @@ return false; } - QString transform = attributes.value("transform"); - if (haveModel(modelId)) { m_currentDerivedModel = m_models[modelId]; } else { @@ -1009,32 +1024,44 @@ sourceId = attributes.value("source").trimmed().toInt(&sourceOk); if (sourceOk && haveModel(sourceId)) { - m_currentTransformerSource = m_models[sourceId]; + m_currentTransformSource = m_models[sourceId]; } else { - m_currentTransformerSource = m_document->getMainModel(); + m_currentTransformSource = m_document->getMainModel(); } - m_currentTransformer = transform; - m_currentTransformerConfiguration = ""; + m_currentTransform = Transform(); - m_currentTransformerContext = PluginTransformer::ExecutionContext(); - bool ok = false; int channel = attributes.value("channel").trimmed().toInt(&ok); - if (ok) m_currentTransformerContext.channel = channel; + if (ok) m_currentTransformChannel = channel; + else m_currentTransformChannel = -1; - int domain = attributes.value("domain").trimmed().toInt(&ok); - if (ok) m_currentTransformerContext.domain = Vamp::Plugin::InputDomain(domain); + QString type = attributes.value("type"); + if (type == "transform") { + m_currentTransformIsNewStyle = true; + return true; + } else { + m_currentTransformIsNewStyle = false; + std::cerr << "NOTE: SV-XML: Reading old-style derivation element" + << std::endl; + } + + QString transformId = attributes.value("transform"); + + m_currentTransform.setIdentifier(transformId); + int stepSize = attributes.value("stepSize").trimmed().toInt(&ok); - if (ok) m_currentTransformerContext.stepSize = stepSize; + if (ok) m_currentTransform.setStepSize(stepSize); int blockSize = attributes.value("blockSize").trimmed().toInt(&ok); - if (ok) m_currentTransformerContext.blockSize = blockSize; + if (ok) m_currentTransform.setBlockSize(blockSize); int windowType = attributes.value("windowType").trimmed().toInt(&ok); - if (ok) m_currentTransformerContext.windowType = WindowType(windowType); + if (ok) m_currentTransform.setWindowType(WindowType(windowType)); + if (!m_currentTransformSource) return true; + QString startFrameStr = attributes.value("startFrame"); QString durationStr = attributes.value("duration"); @@ -1050,9 +1077,14 @@ if (!ok) duration = 0; } - m_currentTransformerContext.startFrame = startFrame; - m_currentTransformerContext.duration = duration; + m_currentTransform.setStartTime + (RealTime::frame2RealTime + (startFrame, m_currentTransformSource->getSampleRate())); + m_currentTransform.setDuration + (RealTime::frame2RealTime + (duration, m_currentTransformSource->getSampleRate())); + return true; } @@ -1119,6 +1151,10 @@ return false; } + if (!m_currentPlayParameters && m_currentTransformIsNewStyle) { + return true; + } + QString configurationXml = "<plugin"; for (int i = 0; i < attributes.length(); ++i) { @@ -1132,13 +1168,48 @@ if (m_currentPlayParameters) { m_currentPlayParameters->setPlayPluginConfiguration(configurationXml); } else { - m_currentTransformerConfiguration += configurationXml; + TransformFactory::getInstance()-> + setParametersFromPluginConfigurationXml(m_currentTransform, + configurationXml); } return true; } bool +SVFileReader::readTransform(const QXmlAttributes &attributes) +{ + if (m_currentDerivedModelId < 0) { + std::cerr << "WARNING: SV-XML: Transform found outside derivation" << std::endl; + return false; + } + + m_currentTransform.setFromXmlAttributes(attributes); + return true; +} + +bool +SVFileReader::readParameter(const QXmlAttributes &attributes) +{ + if (m_currentDerivedModelId < 0) { + std::cerr << "WARNING: SV-XML: Parameter found outside derivation" << std::endl; + return false; + } + + QString name = attributes.value("name"); + if (name == "") { + std::cerr << "WARNING: SV-XML: Ignoring nameless transform parameter" + << std::endl; + return false; + } + + float value = attributes.value("value").trimmed().toFloat(); + + m_currentTransform.setParameter(name, value); + return true; +} + +bool SVFileReader::readSelection(const QXmlAttributes &attributes) { bool ok; Modified: sonic-visualiser/trunk/framework/SVFileReader.h =================================================================== --- sonic-visualiser/trunk/framework/SVFileReader.h 2007-12-07 16:45:27 UTC (rev 893) +++ sonic-visualiser/trunk/framework/SVFileReader.h 2007-12-07 16:47:31 UTC (rev 894) @@ -18,7 +18,6 @@ #include "layer/LayerFactory.h" #include "plugin/transform/Transform.h" -#include "plugin/transform/PluginTransformer.h" #include <QXmlDefaultHandler> @@ -89,10 +88,21 @@ a derivation element, and no model element should appear for it at all. --> - <derivation source="0" model="2" transform="..." ...> - <plugin id="..." ... /> + <derivation type="transform" source="0" model="2" channel="-1"> + <transform id="vamp:soname:pluginid:output" ... /> </derivation> + <!-- Note that the derivation element just described replaces + this earlier formulation, which had more attributes in the + derivation element and a plugin element describing plugin + parameters and properties. What we actually read and + write these days is a horrid composite of the two formats, + for backward compatibility reasons. --> + + <derivation source="0" model="2" transform="vamp:soname:pluginid:output" ...> + <plugin id="pluginid" ... /> + </derivation> + <!-- The playparameters element lists playback settings for a model. --> @@ -195,6 +205,8 @@ bool readDerivation(const QXmlAttributes &); bool readPlayParameters(const QXmlAttributes &); bool readPlugin(const QXmlAttributes &); + bool readTransform(const QXmlAttributes &); + bool readParameter(const QXmlAttributes &); bool readSelection(const QXmlAttributes &); bool readMeasurement(const QXmlAttributes &); void addUnaddedModels(); @@ -216,10 +228,10 @@ Model *m_currentDerivedModel; int m_currentDerivedModelId; PlayParameters *m_currentPlayParameters; - QString m_currentTransformer; - Model *m_currentTransformerSource; - PluginTransformer::ExecutionContext m_currentTransformerContext; - QString m_currentTransformerConfiguration; + Transform m_currentTransform; + Model *m_currentTransformSource; + int m_currentTransformChannel; + bool m_currentTransformIsNewStyle; QString m_datasetSeparator; bool m_inRow; bool m_inLayer; Modified: sonic-visualiser/trunk/plugin/plugin.pro =================================================================== --- sonic-visualiser/trunk/plugin/plugin.pro 2007-12-07 16:45:27 UTC (rev 893) +++ sonic-visualiser/trunk/plugin/plugin.pro 2007-12-07 16:47:31 UTC (rev 894) @@ -36,7 +36,6 @@ api/alsa/seq_midi_event.h \ api/alsa/sound/asequencer.h \ transform/FeatureExtractionModelTransformer.h \ - transform/PluginTransformer.h \ transform/RealTimeEffectModelTransformer.h \ transform/Transform.h \ transform/TransformDescription.h \ @@ -55,7 +54,6 @@ api/dssi_alsa_compat.c \ plugins/SamplePlayer.cpp \ transform/FeatureExtractionModelTransformer.cpp \ - transform/PluginTransformer.cpp \ transform/RealTimeEffectModelTransformer.cpp \ transform/Transform.cpp \ transform/TransformFactory.cpp \ Modified: sonic-visualiser/trunk/plugin/transform/FeatureExtractionModelTransformer.cpp =================================================================== --- sonic-visualiser/trunk/plugin/transform/FeatureExtractionModelTransformer.cpp 2007-12-07 16:45:27 UTC (rev 893) +++ sonic-visualiser/trunk/plugin/transform/FeatureExtractionModelTransformer.cpp 2007-12-07 16:47:31 UTC (rev 894) @@ -29,22 +29,23 @@ #include "data/model/FFTModel.h" #include "data/model/WaveFileModel.h" +#include "TransformFactory.h" + #include <QMessageBox> #include <iostream> -FeatureExtractionModelTransformer::FeatureExtractionModelTransformer(Model *inputModel, - QString pluginId, - const ExecutionContext &context, - QString configurationXml, - QString outputName) : - PluginTransformer(inputModel, context), +FeatureExtractionModelTransformer::FeatureExtractionModelTransformer(Input in, + const Transform &transform) : + ModelTransformer(in, transform), m_plugin(0), m_descriptor(0), m_outputFeatureNo(0) { -// std::cerr << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: plugin " << pluginId.toStdString() << ", outputName " << outputName.toStdString() << std::endl; +// std::cerr << "FeatureExtractionModelTransformer::FeatureExtractionModelTransformer: plugin " << pluginId.toStdString() << ", outputName " << m_transform.getOutput().toStdString() << std::endl; + QString pluginId = transform.getPluginIdentifier(); + FeatureExtractionPluginFactory *factory = FeatureExtractionPluginFactory::instanceFor(pluginId); @@ -54,23 +55,25 @@ return; } - m_plugin = factory->instantiatePlugin(pluginId, m_input->getSampleRate()); + DenseTimeValueModel *input = getConformingInput(); + if (!input) { + std::cerr << "FeatureExtractionModelTransformer: Input model not conformable" << std::endl; + return; + } + m_plugin = factory->instantiatePlugin(pluginId, input->getSampleRate()); if (!m_plugin) { std::cerr << "FeatureExtractionModelTransformer: Failed to instantiate plugin \"" << pluginId.toStdString() << "\"" << std::endl; return; } - m_context.makeConsistentWithPlugin(m_plugin); + TransformFactory::getInstance()->makeContextConsistentWithPlugin + (m_transform, m_plugin); - if (configurationXml != "") { - PluginXml(m_plugin).setParametersFromXml(configurationXml); - } + TransformFactory::getInstance()->setPluginParameters + (m_transform, m_plugin); - DenseTimeValueModel *input = getInput(); - if (!input) return; - size_t channelCount = input->getChannelCount(); if (m_plugin->getMaxChannelCount() < channelCount) { channelCount = 1; @@ -85,14 +88,14 @@ } std::cerr << "Initialising feature extraction plugin with channels = " - << channelCount << ", step = " << m_context.stepSize - << ", block = " << m_context.blockSize << std::endl; + << channelCount << ", step = " << m_transform.getStepSize() + << ", block = " << m_transform.getBlockSize() << std::endl; if (!m_plugin->initialise(channelCount, - m_context.stepSize, - m_context.blockSize)) { + m_transform.getStepSize(), + m_transform.getBlockSize())) { std::cerr << "FeatureExtractionModelTransformer: Plugin " - << m_plugin->getIdentifier() << " failed to initialise!" << std::endl; + << pluginId.toStdString() << " failed to initialise!" << std::endl; return; } @@ -105,7 +108,8 @@ } for (size_t i = 0; i < outputs.size(); ++i) { - if (outputName == "" || outputs[i].identifier == outputName.toStdString()) { + if (m_transform.getOutput() == "" || + outputs[i].identifier == m_transform.getOutput().toStdString()) { m_outputFeatureNo = i; m_descriptor = new Vamp::Plugin::OutputDescriptor (outputs[i]); @@ -116,7 +120,7 @@ if (!m_descriptor) { std::cerr << "FeatureExtractionModelTransformer: Plugin \"" << pluginId.toStdString() << "\" has no output named \"" - << outputName.toStdString() << "\"" << std::endl; + << m_transform.getOutput().toStdString() << "\"" << std::endl; return; } @@ -140,7 +144,7 @@ haveExtents = true; } - size_t modelRate = m_input->getSampleRate(); + size_t modelRate = input->getSampleRate(); size_t modelResolution = 1; switch (m_descriptor->sampleType) { @@ -152,7 +156,7 @@ break; case Vamp::Plugin::OutputDescriptor::OneSamplePerStep: - modelResolution = m_context.stepSize; + modelResolution = m_transform.getStepSize(); break; case Vamp::Plugin::OutputDescriptor::FixedSampleRate: @@ -219,7 +223,7 @@ m_output = model; } - if (m_output) m_output->setSourceModel(m_input); + if (m_output) m_output->setSourceModel(input); } FeatureExtractionModelTransformer::~FeatureExtractionModelTransformer() @@ -230,12 +234,12 @@ } DenseTimeValueModel * -FeatureExtractionModelTransformer::getInput() +FeatureExtractionModelTransformer::getConformingInput() { DenseTimeValueModel *dtvm = dynamic_cast<DenseTimeValueModel *>(getInputModel()); if (!dtvm) { - std::cerr << "FeatureExtractionModelTransformer::getInput: WARNING: Input model is not conformable to DenseTimeValueModel" << std::endl; + std::cerr << "FeatureExtractionModelTransformer::getConformingInput: WARNING: Input model is not conformable to DenseTimeValueModel" << std::endl; } return dtvm; } @@ -243,7 +247,7 @@ void FeatureExtractionModelTransformer::run() { - DenseTimeValueModel *input = getInput(); + DenseTimeValueModel *input = getConformingInput(); if (!input) return; if (!m_output) return; @@ -260,7 +264,7 @@ sleep(1); } - size_t sampleRate = m_input->getSampleRate(); + size_t sampleRate = input->getSampleRate(); size_t channelCount = input->getChannelCount(); if (m_plugin->getMaxChannelCount() < channelCount) { @@ -269,9 +273,12 @@ float **buffers = new float*[channelCount]; for (size_t ch = 0; ch < channelCount; ++ch) { - buffers[ch] = new float[m_context.blockSize + 2]; + buffers[ch] = new float[m_transform.getBlockSize() + 2]; } + size_t stepSize = m_transform.getStepSize(); + size_t blockSize = m_transform.getBlockSize(); + bool frequencyDomain = (m_plugin->getInputDomain() == Vamp::Plugin::FrequencyDomain); std::vector<FFTModel *> fftModels; @@ -279,12 +286,12 @@ if (frequencyDomain) { for (size_t ch = 0; ch < channelCount; ++ch) { FFTModel *model = new FFTModel - (getInput(), - channelCount == 1 ? m_context.channel : ch, - m_context.windowType, - m_context.blockSize, - m_context.stepSize, - m_context.blockSize, + (getConformingInput(), + channelCount == 1 ? m_input.getChannel() : ch, + m_transform.getWindowType(), + blockSize, + stepSize, + blockSize, false, StorageAdviser::PrecisionCritical); if (!model->isOK()) { @@ -301,12 +308,18 @@ } } - long startFrame = m_input->getStartFrame(); - long endFrame = m_input->getEndFrame(); + long startFrame = m_input.getModel()->getStartFrame(); + long endFrame = m_input.getModel()->getEndFrame(); - long contextStart = m_context.startFrame; - long contextDuration = m_context.duration; + RealTime contextStartRT = m_transform.getStartTime(); + RealTime contextDurationRT = m_transform.getDuration(); + long contextStart = + RealTime::realTime2Frame(contextStartRT, sampleRate); + + long contextDuration = + RealTime::realTime2Frame(contextDurationRT, sampleRate); + if (contextStart == 0 || contextStart < startFrame) { contextStart = startFrame; } @@ -327,7 +340,7 @@ while (!m_abandoned) { if (frequencyDomain) { - if (blockFrame - int(m_context.blockSize)/2 > + if (blockFrame - int(blockSize)/2 > contextStart + contextDuration) break; } else { if (blockFrame >= @@ -336,24 +349,24 @@ // std::cerr << "FeatureExtractionModelTransformer::run: blockFrame " // << blockFrame << ", endFrame " << endFrame << ", blockSize " -// << m_context.blockSize << std::endl; +// << blockSize << std::endl; long completion = - (((blockFrame - contextStart) / m_context.stepSize) * 99) / - (contextDuration / m_context.stepSize); + (((blockFrame - contextStart) / stepSize) * 99) / + (contextDuration / stepSize); - // channelCount is either m_input->channelCount or 1 + // channelCount is either m_input.getModel()->channelCount or 1 for (size_t ch = 0; ch < channelCount; ++ch) { if (frequencyDomain) { - int column = (blockFrame - startFrame) / m_context.stepSize; - for (size_t i = 0; i <= m_context.blockSize/2; ++i) { + int column = (blockFrame - startFrame) / stepSize; + for (size_t i = 0; i <= blockSize/2; ++i) { fftModels[ch]->getValuesAt (column, i, buffers[ch][i*2], buffers[ch][i*2+1]); } } else { getFrames(ch, channelCount, - blockFrame, m_context.blockSize, buffers[ch]); + blockFrame, blockSize, buffers[ch]); } } @@ -371,7 +384,7 @@ prevCompletion = completion; } - blockFrame += m_context.stepSize; + blockFrame += stepSize; } if (m_abandoned) return; @@ -410,8 +423,11 @@ startFrame = 0; } - long got = getInput()->getData - ((channelCount == 1 ? m_context.channel : channel), + DenseTimeValueModel *input = getConformingInput(); + if (!input) return; + + long got = input->getData + ((channelCount == 1 ? m_input.getChannel() : channel), startFrame, size, buffer + offset); while (got < size) { @@ -419,10 +435,10 @@ ++got; } - if (m_context.channel == -1 && channelCount == 1 && - getInput()->getChannelCount() > 1) { + if (m_input.getChannel() == -1 && channelCount == 1 && + input->getChannelCount() > 1) { // use mean instead of sum, as plugin input - int cc = getInput()->getChannelCount(); + int cc = input->getChannelCount(); for (long i = 0; i < size; ++i) { buffer[i] /= cc; } @@ -433,7 +449,7 @@ FeatureExtractionModelTransformer::addFeature(size_t blockFrame, const Vamp::Plugin::Feature &feature) { - size_t inputRate = m_input->getSampleRate(); + size_t inputRate = m_input.getModel()->getSampleRate(); // std::cerr << "FeatureExtractionModelTransformer::addFeature(" // << blockFrame << ")" << std::endl; @@ -472,8 +488,10 @@ if (binCount == 0) { - SparseOneDimensionalModel *model = getOutput<SparseOneDimensionalModel>(); + SparseOneDimensionalModel *model = + getConformingOutput<SparseOneDimensionalModel>(); if (!model) return; + model->addPoint(SparseOneDimensionalModel::Point(frame, feature.label.c_str())); } else if (binCount == 1) { @@ -481,8 +499,10 @@ float value = 0.0; if (feature.values.size() > 0) value = feature.values[0]; - SparseTimeValueModel *model = getOutput<SparseTimeValueModel>(); + SparseTimeValueModel *model = + getConformingOutput<SparseTimeValueModel>(); if (!model) return; + model->addPoint(SparseTimeValueModel::Point(frame, value, feature.label.c_str())); // std::cerr << "SparseTimeValueModel::addPoint(" << frame << ", " << value << "), " << feature.label.c_str() << std::endl; @@ -500,7 +520,7 @@ if (velocity < 0) velocity = 127; if (velocity > 127) velocity = 127; - NoteModel *model = getOutput<NoteModel>(); + NoteModel *model = getConformingOutput<NoteModel>(); if (!model) return; model->addPoint(NoteModel::Point(frame, pitch, @@ -513,7 +533,7 @@ DenseThreeDimensionalModel::Column values = feature.values; EditableDenseThreeDimensionalModel *model = - getOutput<EditableDenseThreeDimensionalModel>(); + getConformingOutput<EditableDenseThreeDimensionalModel>(); if (!model) return; model->setColumn(frame / model->getResolution(), values); @@ -533,29 +553,32 @@ if (binCount == 0) { - SparseOneDimensionalModel *model = getOutput<SparseOneDimensionalModel>(); + SparseOneDimensionalModel *model = + getConformingOutput<SparseOneDimensionalModel>(); if (!model) return; - model->setCompletion(completion, m_context.updates); + model->setCompletion(completion, true); //!!!m_context.updates); } else if (binCount == 1) { - SparseTimeValueModel *model = getOutput<SparseTimeValueModel>(); + SparseTimeValueModel *model = + getConformingOutput<SparseTimeValueModel>(); if (!model) return; - model->setCompletion(completion, m_context.updates); + model->setCompletion(completion, true); //!!!m_context.updates); } else if (m_descriptor->sampleType == Vamp::Plugin::OutputDescriptor::VariableSampleRate) { - NoteModel *model = getOutput<NoteModel>(); + NoteModel *model = + getConformingOutput<NoteModel>(); if (!model) return; - model->setCompletion(completion, m_context.updates); + model->setCompletion(completion, true); //!!!m_context.updates); } else { EditableDenseThreeDimensionalModel *model = - getOutput<EditableDenseThreeDimensionalModel>(); + getConformingOutput<EditableDenseThreeDimensionalModel>(); if (!model) return; - model->setCompletion(completion, m_context.updates); + model->setCompletion(completion, true); //!!!m_context.updates); } } Modified: sonic-visualiser/trunk/plugin/transform/FeatureExtractionModelTransformer.h =================================================================== --- sonic-visualiser/trunk/plugin/transform/FeatureExtractionModelTransformer.h 2007-12-07 16:45:27 UTC (rev 893) +++ sonic-visualiser/trunk/plugin/transform/FeatureExtractionModelTransformer.h 2007-12-07 16:47:31 UTC (rev 894) @@ -16,20 +16,21 @@ #ifndef _FEATURE_EXTRACTION_PLUGIN_TRANSFORMER_H_ #define _FEATURE_EXTRACTION_PLUGIN_TRANSFORMER_H_ -#include "PluginTransformer.h" +#include "ModelTransformer.h" +#include <vamp-sdk/Plugin.h> + +#include <iostream> + class DenseTimeValueModel; -class FeatureExtractionModelTransformer : public PluginTransformer +class FeatureExtractionModelTransformer : public ModelTransformer { Q_OBJECT public: - FeatureExtractionModelTransformer(Model *inputModel, - QString plugin, - const ExecutionContext &context, - QString configurationXml = "", - QString outputName = ""); + FeatureExtractionModelTransformer(Input input, + const Transform &transform); virtual ~FeatureExtractionModelTransformer(); protected: @@ -48,8 +49,8 @@ long startFrame, long size, float *buffer); // just casts - DenseTimeValueModel *getInput(); - template <typename ModelClass> ModelClass *getOutput() { + DenseTimeValueModel *getConformingInput(); + template <typename ModelClass> ModelClass *getConformingOutput() { ModelClass *mc = dynamic_cast<ModelClass *>(m_output); if (!mc) { std::cerr << "FeatureExtractionModelTransformer::getOutput: Output model not conformable" << std::endl; Modified: sonic-visualiser/trunk/plugin/transform/ModelTransformer.cpp =================================================================== --- sonic-visualiser/trunk/plugin/transform/ModelTransformer.cpp 2007-12-07 16:45:27 UTC (rev 893) +++ sonic-visualiser/trunk/plugin/transform/ModelTransformer.cpp 2007-12-07 16:47:31 UTC (rev 894) @@ -15,8 +15,9 @@ #include "ModelTransformer.h" -ModelTransformer::ModelTransformer(Model *m) : - m_input(m), +ModelTransformer::ModelTransformer(Input input, const Transform &transform) : + m_transform(transform), + m_input(input), m_output(0), m_detached(false), m_abandoned(false) Modified: sonic-visualiser/trunk/plugin/transform/ModelTransformer.h =================================================================== --- sonic-visualiser/trunk/plugin/transform/ModelTransformer.h 2007-12-07 16:45:27 UTC (rev 893) +++ sonic-visualiser/trunk/plugin/transform/ModelTransformer.h 2007-12-07 16:47:31 UTC (rev 894) @@ -20,6 +20,8 @@ #include "data/model/Model.h" +#include "Transform.h" + /** * A ModelTransformer turns one data model into another. * @@ -38,19 +40,38 @@ public: virtual ~ModelTransformer(); + class Input { + public: + Input(Model *m) : m_model(m), m_channel(-1) { } + Input(Model *m, int c) : m_model(m), m_channel(c) { } + + Model *getModel() const { return m_model; } + void setModel(Model *m) { m_model = m; } + + int getChannel() const { return m_channel; } + void setChannel(int c) { m_channel = c; } + + protected: + Model *m_model; + 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. void abandon() { m_abandoned = true; } - Model *getInputModel() { return m_input; } + Model *getInputModel() { return m_input.getModel(); } + int getInputChannel() { return m_input.getChannel(); } + Model *getOutputModel() { return m_output; } Model *detachOutputModel() { m_detached = true; return m_output; } protected: - ModelTransformer(Model *m); + ModelTransformer(Input input, const Transform &transform); - Model *m_input; // I don't own this + Transform m_transform; + Input m_input; // I don't own the model in this Model *m_output; // I own this, unless... bool m_detached; // ... this is true. bool m_abandoned; Modified: sonic-visualiser/trunk/plugin/transform/ModelTransformerFactory.cpp =================================================================== --- sonic-visualiser/trunk/plugin/transform/ModelTransformerFactory.cpp 2007-12-07 16:45:27 UTC (rev 893) +++ sonic-visualiser/trunk/plugin/transform/ModelTransformerFactory.cpp 2007-12-07 16:47:31 UTC (rev 894) @@ -51,7 +51,8 @@ } bool -ModelTransformerFactory::getChannelRange(TransformId identifier, Vamp::PluginBase *plugin, +ModelTransformerFactory::getChannelRange(TransformId identifier, + Vamp::PluginBase *plugin, int &minChannels, int &maxChannels) { Vamp::Plugin *vp = 0; @@ -66,18 +67,18 @@ } } -Model * -ModelTransformerFactory::getConfigurationForTransformer(TransformId identifier, - const std::vector<Model *> &candidateInputModels, - Model *defaultInputModel, - PluginTransformer::ExecutionContext &context, - QString &configurationXml, - AudioCallbackPlaySource *source, - size_t startFrame, - size_t duration) +ModelTransformer::Input +ModelTransformerFactory::getConfigurationForTransform(Transform &transform, + const std::vector<Model *> &candidateInputModels, + Model *defaultInputModel, + AudioCallbackPlaySource *source, + size_t startFrame, + size_t duration) { - if (candidateInputModels.empty()) return 0; + ModelTransformer::Input input(0); + if (candidateInputModels.empty()) return input; + //!!! This will need revision -- we'll have to have a callback //from the dialog for when the candidate input model is changed, //as we'll need to reinitialise the channel settings in the dialog @@ -99,15 +100,15 @@ } } - QString id = identifier.section(':', 0, 2); - QString output = identifier.section(':', 3); + QString id = transform.getPluginIdentifier(); + QString output = transform.getOutput(); QString outputLabel = ""; QString outputDescription = ""; bool ok = false; - configurationXml = m_lastConfigurations[identifier]; + QString configurationXml = m_lastConfigurations[transform.getIdentifier()]; -// std::cerr << "last configuration: " << configurationXml.toStdString() << std::endl; + std::cerr << "last configuration: " << configurationXml.toStdString() << std::endl; Vamp::PluginBase *plugin = 0; @@ -117,7 +118,7 @@ if (FeatureExtractionPluginFactory::instanceFor(id)) { - std::cerr << "getConfigurationForTransformer: instantiating Vamp plugin" << std::endl; + std::cerr << "getConfigurationForTransform: instantiating Vamp plugin" << std::endl; Vamp::Plugin *vp = FeatureExtractionPluginFactory::instanceFor(id)->instantiatePlugin @@ -184,11 +185,18 @@ if (plugin) { - context = PluginTransformer::ExecutionContext(context.channel, plugin); + // Ensure block size etc are valid + TransformFactory::getInstance()-> + makeContextConsistentWithPlugin(transform, plugin); - if (configurationXml != "") { - PluginXml(plugin).setParametersFromXml(configurationXml); - } + // Prepare the plugin with any existing parameters already + // found in the transform + TransformFactory::getInstance()-> + setPluginParameters(transform, plugin); + + // For this interactive usage, we want to override those with + // whatever the user chose last time around + PluginXml(plugin).setParametersFromXml(configurationXml); int sourceChannels = 1; if (dynamic_cast<DenseTimeValueModel *>(inputModel)) { @@ -197,7 +205,8 @@ } int minChannels = 1, maxChannels = sourceChannels; - getChannelRange(identifier, plugin, minChannels, maxChannels); + getChannelRange(transform.getIdentifier(), plugin, + minChannels, maxChannels); int targetChannels = sourceChannels; if (!effect) { @@ -205,7 +214,7 @@ if (sourceChannels > maxChannels) targetChannels = maxChannels; } - int defaultChannel = context.channel; + int defaultChannel = -1; //!!! no longer saved! [was context.channel] PluginParameterDialog *dialog = new PluginParameterDialog(plugin); @@ -242,23 +251,43 @@ } else { std::cerr << "Selected input empty: \"" << selectedInput.toStdString() << "\"" << std::endl; } + + // Write parameters back to transform object + TransformFactory::getInstance()-> + setParametersFromPlugin(transform, plugin); - configurationXml = PluginXml(plugin).toXmlString(); - context.cha... [truncated message content] |