Mercurial > hg > svapp
changeset 72:4aa40182321f
* Merge from transforms branch -- switch over to using Transform object
properly
author | Chris Cannam |
---|---|
date | Fri, 07 Dec 2007 16:47:31 +0000 |
parents | 716e9d2f91c7 |
children | ef8a3028c711 |
files | framework/Document.cpp framework/Document.h framework/SVFileReader.cpp framework/SVFileReader.h |
diffstat | 4 files changed, 264 insertions(+), 130 deletions(-) [+] |
line wrap: on
line diff
--- a/framework/Document.cpp Fri Nov 30 17:31:09 2007 +0000 +++ b/framework/Document.cpp Fri Dec 07 16:47:31 2007 +0000 @@ -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"; +} +
--- a/framework/Document.h Fri Nov 30 17:31:09 2007 +0000 +++ b/framework/Document.h Fri Dec 07 16:47:31 2007 +0000 @@ -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
--- a/framework/SVFileReader.cpp Fri Nov 30 17:31:09 2007 +0000 +++ b/framework/SVFileReader.cpp Fri Dec 07 16:47:31 2007 +0000 @@ -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,31 +1024,43 @@ 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_currentTransformerContext = PluginTransformer::ExecutionContext(); + m_currentTransform = Transform(); 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,8 +1077,13 @@ 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;
--- a/framework/SVFileReader.h Fri Nov 30 17:31:09 2007 +0000 +++ b/framework/SVFileReader.h Fri Dec 07 16:47:31 2007 +0000 @@ -18,7 +18,6 @@ #include "layer/LayerFactory.h" #include "plugin/transform/Transform.h" -#include "plugin/transform/PluginTransformer.h" #include <QXmlDefaultHandler> @@ -89,8 +88,19 @@ 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 @@ -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;