Mercurial > hg > svcore
view transform/TransformFactory.cpp @ 56:2157fa46c1e7
* Add plugin parameter dialog, and use it to set up parameters for feature
extraction plugins via a semi-opaque (translucent?) configurationXml string
which is associated with a given transform instance.
This is not yet saved to and restored from the SV file properly.
* Remove no-longer-relevant BeatDetect and BeatDetectionFunction transforms
(replaced a long time ago with the beat detector plugin).
author | Chris Cannam |
---|---|
date | Wed, 22 Mar 2006 17:38:29 +0000 |
parents | d397ea0a79f5 |
children | 7439f1696314 |
line wrap: on
line source
/* -*- 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 "TransformFactory.h" #include "FeatureExtractionPluginTransform.h" #include "plugin/FeatureExtractionPluginFactory.h" #include "widgets/PluginParameterDialog.h" #include <iostream> TransformFactory * TransformFactory::m_instance = new TransformFactory; TransformFactory * TransformFactory::instance() { return m_instance; } TransformFactory::~TransformFactory() { } TransformFactory::TransformList TransformFactory::getAllTransforms() { if (m_transforms.empty()) populateTransforms(); TransformList list; for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); i != m_transforms.end(); ++i) { list.push_back(i->second); } return list; } void TransformFactory::populateTransforms() { std::vector<QString> fexplugs = FeatureExtractionPluginFactory::getAllPluginIdentifiers(); std::map<QString, QString> makers; for (size_t i = 0; i < fexplugs.size(); ++i) { QString pluginId = fexplugs[i]; FeatureExtractionPluginFactory *factory = FeatureExtractionPluginFactory::instanceFor(pluginId); if (!factory) { std::cerr << "WARNING: TransformFactory::populateTransforms: No feature extraction plugin factory for instance " << pluginId.toLocal8Bit().data() << std::endl; continue; } FeatureExtractionPlugin *plugin = factory->instantiatePlugin(pluginId, 48000); if (!plugin) { std::cerr << "WARNING: TransformFactory::populateTransforms: Failed to instantiate plugin " << pluginId.toLocal8Bit().data() << std::endl; continue; } QString pluginDescription = plugin->getDescription().c_str(); FeatureExtractionPlugin::OutputList outputs = plugin->getOutputDescriptors(); for (size_t j = 0; j < outputs.size(); ++j) { QString transformName = QString("%1:%2") .arg(pluginId).arg(outputs[j].name.c_str()); QString userDescription; if (outputs.size() == 1) { userDescription = pluginDescription; } else { userDescription = QString("%1: %2") .arg(pluginDescription) .arg(outputs[j].description.c_str()); } bool configurable = (!plugin->getPrograms().empty() || !plugin->getParameterDescriptors().empty()); m_transforms[transformName] = TransformDesc(transformName, userDescription, configurable); makers[transformName] = plugin->getMaker().c_str(); } } // disambiguate plugins with similar descriptions std::map<QString, int> descriptions; for (TransformDescriptionMap::iterator i = m_transforms.begin(); i != m_transforms.end(); ++i) { TransformDesc desc = i->second; ++descriptions[desc.description]; ++descriptions[QString("%1 [%2]").arg(desc.description).arg(makers[desc.name])]; } std::map<QString, int> counts; TransformDescriptionMap newMap; for (TransformDescriptionMap::iterator i = m_transforms.begin(); i != m_transforms.end(); ++i) { TransformDesc desc = i->second; QString name = desc.name, description = desc.description; if (descriptions[description] > 1) { description = QString("%1 [%2]").arg(description).arg(makers[name]); if (descriptions[description] > 1) { description = QString("%1 <%2>") .arg(description).arg(++counts[description]); } } desc.description = description; newMap[name] = desc; } m_transforms = newMap; } QString TransformFactory::getTransformDescription(TransformName name) { if (m_transforms.find(name) != m_transforms.end()) { return m_transforms[name].description; } else return ""; } QString TransformFactory::getTransformFriendlyName(TransformName name) { QString description = getTransformDescription(name); int i = description.indexOf(':'); if (i >= 0) { return description.remove(0, i + 2); } else { return description; } } bool TransformFactory::getConfigurationForTransform(TransformName name, Model *inputModel, QString &configurationXml) { QString id = name.section(':', 0, 2); QString output = name.section(':', 3); bool ok = false; configurationXml = m_lastConfigurations[name]; std::cerr << "last configuration: " << configurationXml.toStdString() << std::endl; if (FeatureExtractionPluginFactory::instanceFor(id)) { FeatureExtractionPlugin *plugin = FeatureExtractionPluginFactory::instanceFor(id)->instantiatePlugin (id, inputModel->getSampleRate()); if (plugin) { if (configurationXml != "") { plugin->setParametersFromXml(configurationXml); } PluginParameterDialog *dialog = new PluginParameterDialog(plugin); if (dialog->exec() == QDialog::Accepted) { ok = true; } configurationXml = plugin->toXmlString(); delete plugin; } } if (ok) m_lastConfigurations[name] = configurationXml; return ok; } Transform * TransformFactory::createTransform(TransformName name, Model *inputModel, QString configurationXml, bool start) { Transform *transform = 0; // The only transform type we support at the moment is the // FeatureExtractionPluginTransform. In future we may wish to // support e.g. RealTimePluginTransform for audio->audio or // audio->midi transforms using standard effects plugins. QString id = name.section(':', 0, 2); QString output = name.section(':', 3); if (FeatureExtractionPluginFactory::instanceFor(id)) { transform = new FeatureExtractionPluginTransform(inputModel, id, configurationXml, output); } else { std::cerr << "TransformFactory::createTransform: Unknown transform " << name.toStdString() << std::endl; } if (start && transform) transform->start(); transform->setObjectName(name); return transform; } Model * TransformFactory::transform(TransformName name, Model *inputModel, QString configurationXml) { Transform *t = createTransform(name, inputModel, configurationXml, false); if (!t) return 0; connect(t, SIGNAL(finished()), this, SLOT(transformFinished())); t->start(); return t->detachOutputModel(); } void TransformFactory::transformFinished() { QObject *s = sender(); Transform *transform = dynamic_cast<Transform *>(s); if (!transform) { std::cerr << "WARNING: TransformFactory::transformFinished: sender is not a transform" << std::endl; return; } transform->wait(); // unnecessary but reassuring delete transform; }