Mercurial > hg > sonic-visualiser
changeset 27:61259228d029
* More to do with passing around step/blocksize etc from plugin dialog to
plugins. Still some puzzling unresolved details.
author | Chris Cannam |
---|---|
date | Tue, 19 Sep 2006 14:37:06 +0000 |
parents | d88d117e0c34 |
children | b5f55ea61bb8 |
files | document/Document.cpp document/Document.h main/MainWindow.cpp sv.pro transform/FeatureExtractionPluginTransform.cpp transform/FeatureExtractionPluginTransform.h transform/PluginTransform.cpp transform/PluginTransform.h transform/RealTimePluginTransform.cpp transform/RealTimePluginTransform.h transform/TransformFactory.cpp transform/TransformFactory.h |
diffstat | 12 files changed, 250 insertions(+), 109 deletions(-) [+] |
line wrap: on
line diff
--- a/document/Document.cpp Mon Sep 18 16:43:17 2006 +0000 +++ b/document/Document.cpp Tue Sep 19 14:37:06 2006 +0000 @@ -161,11 +161,11 @@ Layer * Document::createDerivedLayer(TransformName transform, Model *inputModel, - int channel, + const PluginTransform::ExecutionContext &context, QString configurationXml) { Model *newModel = createModelForTransform(transform, inputModel, - channel, configurationXml); + context, configurationXml); if (!newModel) { // error already printed to stderr by createModelForTransform emit modelGenerationFailed(transform); @@ -252,12 +252,12 @@ // model: regenerate it. TransformName transform = m_models[model].transform; - int channel = m_models[model].channel; + PluginTransform::ExecutionContext context = m_models[model].context; Model *replacementModel = createModelForTransform(transform, m_mainModel, - channel, + context, m_models[model].configurationXml); if (!replacementModel) { @@ -288,7 +288,7 @@ void Document::addDerivedModel(TransformName transform, Model *inputModel, - int channel, + const PluginTransform::ExecutionContext &context, Model *outputModelToAdd, QString configurationXml) { @@ -301,7 +301,7 @@ ModelRecord rec; rec.source = inputModel; rec.transform = transform; - rec.channel = channel; + rec.context = context; rec.configurationXml = configurationXml; rec.refcount = 0; @@ -323,7 +323,6 @@ ModelRecord rec; rec.source = 0; rec.transform = ""; - rec.channel = -1; rec.refcount = 0; m_models[model] = rec; @@ -334,7 +333,7 @@ Model * Document::createModelForTransform(TransformName transform, Model *inputModel, - int channel, + const PluginTransform::ExecutionContext &context, QString configurationXml) { Model *model = 0; @@ -342,19 +341,19 @@ for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) { if (i->second.transform == transform && i->second.source == inputModel && - i->second.channel == channel && + i->second.context == context && i->second.configurationXml == configurationXml) { return i->first; } } model = TransformFactory::getInstance()->transform - (transform, inputModel, channel, configurationXml); + (transform, inputModel, context, configurationXml); if (!model) { std::cerr << "WARNING: Document::createModelForTransform: no output model for transform " << transform.toStdString() << std::endl; } else { - addDerivedModel(transform, inputModel, channel, model, configurationXml); + addDerivedModel(transform, inputModel, context, model, configurationXml); } return model; @@ -696,11 +695,13 @@ if (rec.source && rec.transform != "") { + //!!! stream the rest of the execution context in both directions (i.e. not just channel) + out << indent; out << QString(" <derivation source=\"%1\" model=\"%2\" channel=\"%3\" transform=\"%4\"") .arg(XmlExportable::getObjectExportId(rec.source)) .arg(XmlExportable::getObjectExportId(i->first)) - .arg(rec.channel) + .arg(rec.context.channel) .arg(XmlExportable::encodeEntities(rec.transform)); if (rec.configurationXml != "") {
--- a/document/Document.h Mon Sep 18 16:43:17 2006 +0000 +++ b/document/Document.h Tue Sep 19 14:37:06 2006 +0000 @@ -18,6 +18,7 @@ #include "layer/LayerFactory.h" #include "transform/Transform.h" +#include "transform/PluginTransform.h" #include "base/Command.h" #include <map> @@ -113,7 +114,7 @@ */ Layer *createDerivedLayer(TransformName, Model *inputModel, - int inputChannel, // -1 -> all + const PluginTransform::ExecutionContext &context, QString configurationXml); /** @@ -136,7 +137,7 @@ */ void addDerivedModel(TransformName, Model *inputModel, - int inputChannel, // -1 -> all + const PluginTransform::ExecutionContext &context, Model *outputModelToAdd, QString configurationXml); @@ -194,7 +195,7 @@ protected: Model *createModelForTransform(TransformName transform, Model *inputModel, - int channel, + const PluginTransform::ExecutionContext &context, QString configurationXml); void releaseModel(Model *model); @@ -230,7 +231,7 @@ // since being generated from it. const Model *source; TransformName transform; - int channel; + PluginTransform::ExecutionContext context; QString configurationXml; // Count of the number of layers using this model.
--- a/main/MainWindow.cpp Mon Sep 18 16:43:17 2006 +0000 +++ b/main/MainWindow.cpp Tue Sep 19 14:37:06 2006 +0000 @@ -2790,6 +2790,9 @@ bool needConfiguration = false; + //!!! actually we should probably always ask for configuration + //because we need the execution context + if (factory->isTransformConfigurable(transform)) { needConfiguration = true; } else { @@ -2803,21 +2806,23 @@ } } + PluginTransform::ExecutionContext context(channel); + if (needConfiguration) { bool ok = factory->getConfigurationForTransform - (transform, m_document->getMainModel(), channel, configurationXml); + (transform, m_document->getMainModel(), context, configurationXml); if (!ok) return; } Layer *newLayer = m_document->createDerivedLayer(transform, m_document->getMainModel(), - channel, + context, configurationXml); if (newLayer) { m_document->addLayerToView(pane, newLayer); - m_document->setChannel(newLayer, channel); + m_document->setChannel(newLayer, context.channel); } updateMenuStates();
--- a/sv.pro Mon Sep 18 16:43:17 2006 +0000 +++ b/sv.pro Tue Sep 19 14:37:06 2006 +0000 @@ -42,6 +42,7 @@ main/MainWindow.h \ main/PreferencesDialog.h \ transform/FeatureExtractionPluginTransform.h \ + transform/PluginTransform.h \ transform/RealTimePluginTransform.h \ transform/Transform.h \ transform/TransformFactory.h @@ -59,6 +60,7 @@ main/MainWindow.cpp \ main/PreferencesDialog.cpp \ transform/FeatureExtractionPluginTransform.cpp \ + transform/PluginTransform.cpp \ transform/RealTimePluginTransform.cpp \ transform/Transform.cpp \ transform/TransformFactory.cpp
--- a/transform/FeatureExtractionPluginTransform.cpp Mon Sep 18 16:43:17 2006 +0000 +++ b/transform/FeatureExtractionPluginTransform.cpp Tue Sep 19 14:37:06 2006 +0000 @@ -34,18 +34,11 @@ FeatureExtractionPluginTransform::FeatureExtractionPluginTransform(Model *inputModel, QString pluginId, - int channel, + const ExecutionContext &context, QString configurationXml, - QString outputName, - size_t stepSize, - size_t blockSize, - WindowType windowType) : - Transform(inputModel), + QString outputName) : + PluginTransform(inputModel, context), m_plugin(0), - m_channel(channel), - m_stepSize(0), - m_blockSize(0), - m_windowType(windowType), m_descriptor(0), m_outputFeatureNo(0) { @@ -72,18 +65,6 @@ PluginXml(m_plugin).setParametersFromXml(configurationXml); } - if (m_blockSize == 0) m_blockSize = m_plugin->getPreferredBlockSize(); - if (m_stepSize == 0) m_stepSize = m_plugin->getPreferredStepSize(); - - if (m_blockSize == 0) m_blockSize = 1024; - if (m_stepSize == 0) { - if (m_plugin->getInputDomain() == Vamp::Plugin::FrequencyDomain) { - m_stepSize = m_blockSize / 2; - } else { - m_stepSize = m_blockSize; - } - } - DenseTimeValueModel *input = getInput(); if (!input) return; @@ -100,7 +81,13 @@ return; } - if (!m_plugin->initialise(channelCount, m_stepSize, m_blockSize)) { + std::cerr << "Initialising feature extraction plugin with channels = " + << channelCount << ", step = " << m_context.stepSize + << ", block = " << m_context.blockSize << std::endl; + + if (!m_plugin->initialise(channelCount, + m_context.stepSize, + m_context.blockSize)) { std::cerr << "FeatureExtractionPluginTransform: Plugin " << m_plugin->getName() << " failed to initialise!" << std::endl; return; @@ -160,7 +147,7 @@ break; case Vamp::Plugin::OutputDescriptor::OneSamplePerStep: - modelResolution = m_stepSize; + modelResolution = m_context.stepSize; break; case Vamp::Plugin::OutputDescriptor::FixedSampleRate: @@ -248,7 +235,7 @@ float **buffers = new float*[channelCount]; for (size_t ch = 0; ch < channelCount; ++ch) { - buffers[ch] = new float[m_blockSize]; + buffers[ch] = new float[m_context.blockSize]; } bool frequencyDomain = (m_plugin->getInputDomain() == @@ -259,11 +246,11 @@ for (size_t ch = 0; ch < channelCount; ++ch) { fftModels.push_back(new FFTModel (getInput(), - channelCount == 1 ? m_channel : ch, - m_windowType, - m_blockSize, - m_stepSize, - m_blockSize, + channelCount == 1 ? m_context.channel : ch, + m_context.windowType, + m_context.blockSize, + m_context.stepSize, + m_context.blockSize, false)); } } @@ -277,7 +264,7 @@ while (1) { if (frequencyDomain) { - if (blockFrame - int(m_blockSize)/2 > endFrame) break; + if (blockFrame - int(m_context.blockSize)/2 > endFrame) break; } else { if (blockFrame >= endFrame) break; } @@ -286,21 +273,21 @@ // << blockFrame << std::endl; long completion = - (((blockFrame - startFrame) / m_stepSize) * 99) / - ( (endFrame - startFrame) / m_stepSize); + (((blockFrame - startFrame) / m_context.stepSize) * 99) / + ( (endFrame - startFrame) / m_context.stepSize); // channelCount is either m_input->channelCount or 1 for (size_t ch = 0; ch < channelCount; ++ch) { if (frequencyDomain) { - int column = (blockFrame - startFrame) / m_stepSize; - for (size_t i = 0; i < m_blockSize/2; ++i) { + int column = (blockFrame - startFrame) / m_context.stepSize; + for (size_t i = 0; i < m_context.blockSize/2; ++i) { fftModels[ch]->getValuesAt (column, i, buffers[ch][i*2], buffers[ch][i*2+1]); } /*!!! float sum = 0.0; - for (size_t i = 0; i < m_blockSize/2; ++i) { + for (size_t i = 0; i < m_context.blockSize/2; ++i) { sum += buffers[ch][i*2]; } if (fabs(sum) < 0.0001) { @@ -309,7 +296,7 @@ */ } else { getFrames(ch, channelCount, - blockFrame, m_blockSize, buffers[ch]); + blockFrame, m_context.blockSize, buffers[ch]); } } @@ -327,7 +314,7 @@ prevCompletion = completion; } - blockFrame += m_stepSize; + blockFrame += m_context.stepSize; } Vamp::Plugin::FeatureSet features = m_plugin->getRemainingFeatures(); @@ -365,7 +352,7 @@ } long got = getInput()->getValues - ((channelCount == 1 ? m_channel : channel), + ((channelCount == 1 ? m_context.channel : channel), startFrame, startFrame + size, buffer + offset); while (got < size) { @@ -373,7 +360,7 @@ ++got; } - if (m_channel == -1 && channelCount == 1 && + if (m_context.channel == -1 && channelCount == 1 && getInput()->getChannelCount() > 1) { // use mean instead of sum, as plugin input int cc = getInput()->getChannelCount();
--- a/transform/FeatureExtractionPluginTransform.h Mon Sep 18 16:43:17 2006 +0000 +++ b/transform/FeatureExtractionPluginTransform.h Tue Sep 19 14:37:06 2006 +0000 @@ -16,35 +16,24 @@ #ifndef _FEATURE_EXTRACTION_PLUGIN_TRANSFORM_H_ #define _FEATURE_EXTRACTION_PLUGIN_TRANSFORM_H_ -#include "Transform.h" - -#include "base/Window.h" - -#include "vamp-sdk/Plugin.h" +#include "PluginTransform.h" class DenseTimeValueModel; -class FeatureExtractionPluginTransform : public Transform +class FeatureExtractionPluginTransform : public PluginTransform { public: FeatureExtractionPluginTransform(Model *inputModel, QString plugin, - int channel, + const ExecutionContext &context, QString configurationXml = "", - QString outputName = "", - size_t stepSize = 0, - size_t blockSize = 0, - WindowType windowType = HanningWindow); + QString outputName = ""); virtual ~FeatureExtractionPluginTransform(); protected: virtual void run(); Vamp::Plugin *m_plugin; - int m_channel; - size_t m_stepSize; - size_t m_blockSize; - WindowType m_windowType; Vamp::Plugin::OutputDescriptor *m_descriptor; int m_outputFeatureNo;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/transform/PluginTransform.cpp Tue Sep 19 14:37:06 2006 +0000 @@ -0,0 +1,93 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006 Chris Cannam. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "PluginTransform.h" + +PluginTransform::PluginTransform(Model *inputModel, + const ExecutionContext &context) : + Transform(inputModel), + m_context(context) +{ +} + +PluginTransform::ExecutionContext::ExecutionContext(int _c, size_t _bs) : + channel(_c), + domain(Vamp::Plugin::TimeDomain), + stepSize(_bs ? _bs : 1024), + blockSize(_bs ? _bs : 1024), + windowType(HanningWindow) +{ +} + +PluginTransform::ExecutionContext::ExecutionContext(int _c, size_t _ss, + size_t _bs, WindowType _wt) : + channel(_c), + domain(Vamp::Plugin::FrequencyDomain), + stepSize(_ss ? _ss : (_bs ? _bs / 2 : 512)), + blockSize(_bs ? _bs : 1024), + windowType(_wt) +{ +} + +PluginTransform::ExecutionContext::ExecutionContext(int _c, + const Vamp::PluginBase *_plugin) : + channel(_c), + domain(Vamp::Plugin::TimeDomain), + stepSize(0), + blockSize(0), + windowType(HanningWindow) +{ + makeConsistentWithPlugin(_plugin); +} + +bool +PluginTransform::ExecutionContext::operator==(const ExecutionContext &c) +{ + return (c.channel == channel && + c.domain == domain && + c.stepSize == stepSize && + c.blockSize == blockSize && + c.windowType == windowType); +} + +void +PluginTransform::ExecutionContext::makeConsistentWithPlugin(const Vamp::PluginBase *_plugin) +{ + const Vamp::Plugin *vp = dynamic_cast<const Vamp::Plugin *>(_plugin); + + if (!vp) { + domain = Vamp::Plugin::TimeDomain; + if (!stepSize) { + if (!blockSize) blockSize = 1024; + stepSize = blockSize; + } else { + if (!blockSize) blockSize = stepSize; + } + } else { + domain = vp->getInputDomain(); + if (!stepSize) stepSize = vp->getPreferredStepSize(); + if (!blockSize) blockSize = vp->getPreferredBlockSize(); + if (!blockSize) blockSize = 1024; + if (!stepSize) { + if (domain == Vamp::Plugin::FrequencyDomain) { + stepSize = blockSize/2; + } else { + stepSize = blockSize; + } + } + } +} + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/transform/PluginTransform.h Tue Sep 19 14:37:06 2006 +0000 @@ -0,0 +1,60 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006 Chris Cannam. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef _PLUGIN_TRANSFORM_H_ +#define _PLUGIN_TRANSFORM_H_ + +#include "Transform.h" + +#include "base/Window.h" + +#include "vamp-sdk/Plugin.h" + +//!!! should this just move back up to Transform? It is after all used +//directly in all sorts of generic places, like Document + +class PluginTransform : public Transform +{ +public: + class ExecutionContext { + public: + // Time domain: + ExecutionContext(int _c = -1, size_t _bs = 0); + + // Frequency domain: + ExecutionContext(int _c, size_t _ss, size_t _bs, WindowType _wt); + + // From plugin defaults: + ExecutionContext(int _c, const Vamp::PluginBase *_plugin); + + bool operator==(const ExecutionContext &); + + void makeConsistentWithPlugin(const Vamp::PluginBase *_plugin); + + int channel; + Vamp::Plugin::InputDomain domain; + size_t stepSize; + size_t blockSize; + WindowType windowType; + }; + +protected: + PluginTransform(Model *inputModel, + const ExecutionContext &context); + + ExecutionContext m_context; +}; + +#endif
--- a/transform/RealTimePluginTransform.cpp Mon Sep 18 16:43:17 2006 +0000 +++ b/transform/RealTimePluginTransform.cpp Tue Sep 19 14:37:06 2006 +0000 @@ -28,18 +28,15 @@ RealTimePluginTransform::RealTimePluginTransform(Model *inputModel, QString pluginId, - int channel, + const ExecutionContext &context, QString configurationXml, QString units, - int output, - size_t blockSize) : - Transform(inputModel), + int output) : + PluginTransform(inputModel, context), m_plugin(0), - m_channel(channel), - m_outputNo(output), - m_blockSize(blockSize) + m_outputNo(output) { - if (!m_blockSize) m_blockSize = 1024; + if (!m_context.blockSize) m_context.blockSize = 1024; std::cerr << "RealTimePluginTransform::RealTimePluginTransform: plugin " << pluginId.toStdString() << ", output " << output << std::endl; @@ -56,7 +53,7 @@ if (!input) return; m_plugin = factory->instantiatePlugin(pluginId, 0, 0, m_input->getSampleRate(), - m_blockSize, + m_context.blockSize, input->getChannelCount()); if (!m_plugin) { @@ -75,7 +72,7 @@ } SparseTimeValueModel *model = new SparseTimeValueModel - (input->getSampleRate(), m_blockSize, 0.0, 0.0, false); + (input->getSampleRate(), m_context.blockSize, 0.0, 0.0, false); if (units != "") model->setScaleUnits(units); @@ -111,7 +108,7 @@ size_t sampleRate = input->getSampleRate(); int channelCount = input->getChannelCount(); - if (m_channel != -1) channelCount = 1; + if (m_context.channel != -1) channelCount = 1; size_t blockSize = m_plugin->getBufferSize(); @@ -135,11 +132,11 @@ if (channelCount == 1) { got = input->getValues - (m_channel, blockFrame, blockFrame + blockSize, buffers[0]); + (m_context.channel, blockFrame, blockFrame + blockSize, buffers[0]); while (got < blockSize) { buffers[0][got++] = 0.0; } - if (m_channel == -1 && channelCount > 1) { + if (m_context.channel == -1 && channelCount > 1) { // use mean instead of sum, as plugin input for (size_t i = 0; i < got; ++i) { buffers[0][i] /= channelCount;
--- a/transform/RealTimePluginTransform.h Mon Sep 18 16:43:17 2006 +0000 +++ b/transform/RealTimePluginTransform.h Tue Sep 19 14:37:06 2006 +0000 @@ -16,30 +16,27 @@ #ifndef _REAL_TIME_PLUGIN_TRANSFORM_H_ #define _REAL_TIME_PLUGIN_TRANSFORM_H_ -#include "Transform.h" +#include "PluginTransform.h" #include "plugin/RealTimePluginInstance.h" class DenseTimeValueModel; -class RealTimePluginTransform : public Transform +class RealTimePluginTransform : public PluginTransform { public: RealTimePluginTransform(Model *inputModel, QString plugin, - int channel, + const ExecutionContext &context, QString configurationXml = "", QString units = "", - int output = 0, - size_t blockSize = 0); + int output = 0); virtual ~RealTimePluginTransform(); protected: virtual void run(); RealTimePluginInstance *m_plugin; - int m_channel; int m_outputNo; - size_t m_blockSize; // just casts DenseTimeValueModel *getInput();
--- a/transform/TransformFactory.cpp Mon Sep 18 16:43:17 2006 +0000 +++ b/transform/TransformFactory.cpp Tue Sep 19 14:37:06 2006 +0000 @@ -350,7 +350,7 @@ bool TransformFactory::getConfigurationForTransform(TransformName name, Model *inputModel, - int &channel, + PluginTransform::ExecutionContext &context, QString &configurationXml) { QString id = name.section(':', 0, 2); @@ -382,6 +382,9 @@ } if (plugin) { + + context = PluginTransform::ExecutionContext(context.channel, plugin); + if (configurationXml != "") { PluginXml(plugin).setParametersFromXml(configurationXml); } @@ -399,7 +402,7 @@ if (sourceChannels < minChannels) targetChannels = minChannels; if (sourceChannels > maxChannels) targetChannels = maxChannels; - int defaultChannel = channel; + int defaultChannel = context.channel; PluginParameterDialog *dialog = new PluginParameterDialog(plugin, sourceChannels, @@ -412,10 +415,13 @@ ok = true; } configurationXml = PluginXml(plugin).toXmlString(); - channel = dialog->getChannel(); + context.channel = dialog->getChannel(); - //!!! where now for step size, block size, etc? -// dialog->getProcessingParameters(stepSize, blockSize, windowType); + dialog->getProcessingParameters(context.stepSize, + context.blockSize, + context.windowType); + + context.makeConsistentWithPlugin(plugin); delete dialog; delete plugin; @@ -428,25 +434,24 @@ Transform * TransformFactory::createTransform(TransformName name, Model *inputModel, - int channel, QString configurationXml, bool start) + const PluginTransform::ExecutionContext &context, + QString configurationXml, bool start) { Transform *transform = 0; - //!!! use channel - QString id = name.section(':', 0, 2); QString output = name.section(':', 3); if (FeatureExtractionPluginFactory::instanceFor(id)) { transform = new FeatureExtractionPluginTransform(inputModel, id, - channel, + context, configurationXml, output); } else if (RealTimePluginFactory::instanceFor(id)) { transform = new RealTimePluginTransform(inputModel, id, - channel, + context, configurationXml, getTransformUnits(name), output.toInt()); @@ -463,9 +468,10 @@ Model * TransformFactory::transform(TransformName name, Model *inputModel, - int channel, QString configurationXml) + const PluginTransform::ExecutionContext &context, + QString configurationXml) { - Transform *t = createTransform(name, inputModel, channel, + Transform *t = createTransform(name, inputModel, context, configurationXml, false); if (!t) return 0;
--- a/transform/TransformFactory.h Mon Sep 18 16:43:17 2006 +0000 +++ b/transform/TransformFactory.h Tue Sep 19 14:37:06 2006 +0000 @@ -17,6 +17,7 @@ #define _TRANSFORM_FACTORY_H_ #include "Transform.h" +#include "PluginTransform.h" #include <map> @@ -68,7 +69,7 @@ */ bool getConfigurationForTransform(TransformName name, Model *inputModel, - int &channel, + PluginTransform::ExecutionContext &context, QString &configurationXml); /** @@ -85,7 +86,8 @@ * when no longer needed. */ Model *transform(TransformName name, Model *inputModel, - int channel, QString configurationXml = ""); + const PluginTransform::ExecutionContext &context, + QString configurationXml = ""); /** * Full description of a transform, suitable for putting on a menu. @@ -128,7 +130,8 @@ protected: Transform *createTransform(TransformName name, Model *inputModel, - int channel, QString configurationXml, bool start); + const PluginTransform::ExecutionContext &context, + QString configurationXml, bool start); struct TransformIdent {