Chris@330: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@330: Chris@330: /* Chris@330: Sonic Visualiser Chris@330: An audio file viewer and annotation editor. Chris@330: Centre for Digital Music, Queen Mary, University of London. Chris@330: This file copyright 2006 Chris Cannam and QMUL. Chris@330: Chris@330: This program is free software; you can redistribute it and/or Chris@330: modify it under the terms of the GNU General Public License as Chris@330: published by the Free Software Foundation; either version 2 of the Chris@330: License, or (at your option) any later version. See the file Chris@330: COPYING included with this distribution for more information. Chris@330: */ Chris@330: Chris@330: #include "TransformFactory.h" Chris@330: Chris@330: #include "plugin/FeatureExtractionPluginFactory.h" Chris@330: #include "plugin/RealTimePluginFactory.h" Chris@332: #include "plugin/RealTimePluginInstance.h" Chris@330: #include "plugin/PluginXml.h" Chris@330: Chris@332: #include "vamp-sdk/Plugin.h" Chris@330: #include "vamp-sdk/PluginHostAdapter.h" Chris@332: #include "vamp-sdk/hostext/PluginWrapper.h" Chris@330: Chris@330: #include Chris@330: #include Chris@330: Chris@330: #include Chris@350: #include Chris@330: Chris@330: TransformFactory * Chris@330: TransformFactory::m_instance = new TransformFactory; Chris@330: Chris@330: TransformFactory * Chris@330: TransformFactory::getInstance() Chris@330: { Chris@330: return m_instance; Chris@330: } Chris@330: Chris@330: TransformFactory::~TransformFactory() Chris@330: { Chris@330: } Chris@330: Chris@330: TransformList Chris@350: TransformFactory::getAllTransformDescriptions() Chris@330: { Chris@330: if (m_transforms.empty()) populateTransforms(); Chris@330: Chris@330: std::set dset; Chris@330: for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); Chris@330: i != m_transforms.end(); ++i) { Chris@358: // std::cerr << "inserting transform into set: id = " << i->second.identifier.toStdString() << std::endl; Chris@330: dset.insert(i->second); Chris@330: } Chris@330: Chris@330: TransformList list; Chris@330: for (std::set::const_iterator i = dset.begin(); Chris@330: i != dset.end(); ++i) { Chris@358: // std::cerr << "inserting transform into list: id = " << i->identifier.toStdString() << std::endl; Chris@330: list.push_back(*i); Chris@330: } Chris@330: Chris@330: return list; Chris@330: } Chris@330: Chris@350: TransformDescription Chris@350: TransformFactory::getTransformDescription(TransformId id) Chris@350: { Chris@350: if (m_transforms.empty()) populateTransforms(); Chris@350: Chris@350: if (m_transforms.find(id) == m_transforms.end()) { Chris@350: return TransformDescription(); Chris@350: } Chris@350: Chris@350: return m_transforms[id]; Chris@350: } Chris@350: Chris@330: std::vector Chris@330: TransformFactory::getAllTransformTypes() Chris@330: { Chris@330: if (m_transforms.empty()) populateTransforms(); Chris@330: Chris@330: std::set types; Chris@330: for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); Chris@330: i != m_transforms.end(); ++i) { Chris@330: types.insert(i->second.type); Chris@330: } Chris@330: Chris@330: std::vector rv; Chris@330: for (std::set::iterator i = types.begin(); i != types.end(); ++i) { Chris@330: rv.push_back(*i); Chris@330: } Chris@330: Chris@330: return rv; Chris@330: } Chris@330: Chris@330: std::vector Chris@330: TransformFactory::getTransformCategories(QString transformType) Chris@330: { Chris@330: if (m_transforms.empty()) populateTransforms(); Chris@330: Chris@330: std::set categories; Chris@330: for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); Chris@330: i != m_transforms.end(); ++i) { Chris@330: if (i->second.type == transformType) { Chris@330: categories.insert(i->second.category); Chris@330: } Chris@330: } Chris@330: Chris@330: bool haveEmpty = false; Chris@330: Chris@330: std::vector rv; Chris@330: for (std::set::iterator i = categories.begin(); Chris@330: i != categories.end(); ++i) { Chris@330: if (*i != "") rv.push_back(*i); Chris@330: else haveEmpty = true; Chris@330: } Chris@330: Chris@330: if (haveEmpty) rv.push_back(""); // make sure empty category sorts last Chris@330: Chris@330: return rv; Chris@330: } Chris@330: Chris@330: std::vector Chris@330: TransformFactory::getTransformMakers(QString transformType) Chris@330: { Chris@330: if (m_transforms.empty()) populateTransforms(); Chris@330: Chris@330: std::set makers; Chris@330: for (TransformDescriptionMap::const_iterator i = m_transforms.begin(); Chris@330: i != m_transforms.end(); ++i) { Chris@330: if (i->second.type == transformType) { Chris@330: makers.insert(i->second.maker); Chris@330: } Chris@330: } Chris@330: Chris@330: bool haveEmpty = false; Chris@330: Chris@330: std::vector rv; Chris@330: for (std::set::iterator i = makers.begin(); Chris@330: i != makers.end(); ++i) { Chris@330: if (*i != "") rv.push_back(*i); Chris@330: else haveEmpty = true; Chris@330: } Chris@330: Chris@330: if (haveEmpty) rv.push_back(""); // make sure empty category sorts last Chris@330: Chris@330: return rv; Chris@330: } Chris@330: Chris@330: void Chris@330: TransformFactory::populateTransforms() Chris@330: { Chris@330: TransformDescriptionMap transforms; Chris@330: Chris@330: populateFeatureExtractionPlugins(transforms); Chris@330: populateRealTimePlugins(transforms); Chris@330: Chris@330: // disambiguate plugins with similar names Chris@330: Chris@330: std::map names; Chris@330: std::map pluginSources; Chris@330: std::map pluginMakers; Chris@330: Chris@330: for (TransformDescriptionMap::iterator i = transforms.begin(); Chris@330: i != transforms.end(); ++i) { Chris@330: Chris@330: TransformDescription desc = i->second; Chris@330: Chris@330: QString td = desc.name; Chris@330: QString tn = td.section(": ", 0, 0); Chris@330: QString pn = desc.identifier.section(":", 1, 1); Chris@330: Chris@330: if (pluginSources.find(tn) != pluginSources.end()) { Chris@330: if (pluginSources[tn] != pn && pluginMakers[tn] != desc.maker) { Chris@330: ++names[tn]; Chris@330: } Chris@330: } else { Chris@330: ++names[tn]; Chris@330: pluginSources[tn] = pn; Chris@330: pluginMakers[tn] = desc.maker; Chris@330: } Chris@330: } Chris@330: Chris@330: std::map counts; Chris@330: m_transforms.clear(); Chris@330: Chris@330: for (TransformDescriptionMap::iterator i = transforms.begin(); Chris@330: i != transforms.end(); ++i) { Chris@330: Chris@330: TransformDescription desc = i->second; Chris@330: QString identifier = desc.identifier; Chris@330: QString maker = desc.maker; Chris@330: Chris@330: QString td = desc.name; Chris@330: QString tn = td.section(": ", 0, 0); Chris@330: QString to = td.section(": ", 1); Chris@330: Chris@330: if (names[tn] > 1) { Chris@330: maker.replace(QRegExp(tr(" [\\(<].*$")), ""); Chris@330: tn = QString("%1 [%2]").arg(tn).arg(maker); Chris@330: } Chris@330: Chris@330: if (to != "") { Chris@330: desc.name = QString("%1: %2").arg(tn).arg(to); Chris@330: } else { Chris@330: desc.name = tn; Chris@330: } Chris@330: Chris@330: m_transforms[identifier] = desc; Chris@330: } Chris@330: } Chris@330: Chris@330: void Chris@330: TransformFactory::populateFeatureExtractionPlugins(TransformDescriptionMap &transforms) Chris@330: { Chris@330: std::vector plugs = Chris@330: FeatureExtractionPluginFactory::getAllPluginIdentifiers(); Chris@330: Chris@330: for (size_t i = 0; i < plugs.size(); ++i) { Chris@330: Chris@330: QString pluginId = plugs[i]; Chris@330: Chris@330: FeatureExtractionPluginFactory *factory = Chris@330: FeatureExtractionPluginFactory::instanceFor(pluginId); Chris@330: Chris@330: if (!factory) { Chris@330: std::cerr << "WARNING: TransformFactory::populateTransforms: No feature extraction plugin factory for instance " << pluginId.toLocal8Bit().data() << std::endl; Chris@330: continue; Chris@330: } Chris@330: Chris@330: Vamp::Plugin *plugin = Chris@350: factory->instantiatePlugin(pluginId, 44100); Chris@330: Chris@330: if (!plugin) { Chris@330: std::cerr << "WARNING: TransformFactory::populateTransforms: Failed to instantiate plugin " << pluginId.toLocal8Bit().data() << std::endl; Chris@330: continue; Chris@330: } Chris@330: Chris@330: QString pluginName = plugin->getName().c_str(); Chris@330: QString category = factory->getPluginCategory(pluginId); Chris@330: Chris@330: Vamp::Plugin::OutputList outputs = Chris@330: plugin->getOutputDescriptors(); Chris@330: Chris@330: for (size_t j = 0; j < outputs.size(); ++j) { Chris@330: Chris@330: QString transformId = QString("%1:%2") Chris@330: .arg(pluginId).arg(outputs[j].identifier.c_str()); Chris@330: Chris@330: QString userName; Chris@330: QString friendlyName; Chris@330: QString units = outputs[j].unit.c_str(); Chris@330: QString description = plugin->getDescription().c_str(); Chris@330: QString maker = plugin->getMaker().c_str(); Chris@330: if (maker == "") maker = tr(""); Chris@330: Chris@330: if (description == "") { Chris@330: if (outputs.size() == 1) { Chris@330: description = tr("Extract features using \"%1\" plugin (from %2)") Chris@330: .arg(pluginName).arg(maker); Chris@330: } else { Chris@330: description = tr("Extract features using \"%1\" output of \"%2\" plugin (from %3)") Chris@330: .arg(outputs[j].name.c_str()).arg(pluginName).arg(maker); Chris@330: } Chris@330: } else { Chris@330: if (outputs.size() == 1) { Chris@330: description = tr("%1 using \"%2\" plugin (from %3)") Chris@330: .arg(description).arg(pluginName).arg(maker); Chris@330: } else { Chris@330: description = tr("%1 using \"%2\" output of \"%3\" plugin (from %4)") Chris@330: .arg(description).arg(outputs[j].name.c_str()).arg(pluginName).arg(maker); Chris@330: } Chris@330: } Chris@330: Chris@330: if (outputs.size() == 1) { Chris@330: userName = pluginName; Chris@330: friendlyName = pluginName; Chris@330: } else { Chris@330: userName = QString("%1: %2") Chris@330: .arg(pluginName) Chris@330: .arg(outputs[j].name.c_str()); Chris@330: friendlyName = outputs[j].name.c_str(); Chris@330: } Chris@330: Chris@330: bool configurable = (!plugin->getPrograms().empty() || Chris@330: !plugin->getParameterDescriptors().empty()); Chris@330: Chris@358: // std::cerr << "Feature extraction plugin transform: " << transformId.toStdString() << " friendly name: " << friendlyName.toStdString() << std::endl; Chris@330: Chris@330: transforms[transformId] = Chris@330: TransformDescription(tr("Analysis"), Chris@332: category, Chris@332: transformId, Chris@332: userName, Chris@332: friendlyName, Chris@332: description, Chris@332: maker, Chris@332: units, Chris@332: configurable); Chris@330: } Chris@330: Chris@330: delete plugin; Chris@330: } Chris@330: } Chris@330: Chris@330: void Chris@330: TransformFactory::populateRealTimePlugins(TransformDescriptionMap &transforms) Chris@330: { Chris@330: std::vector plugs = Chris@330: RealTimePluginFactory::getAllPluginIdentifiers(); Chris@330: Chris@330: static QRegExp unitRE("[\\[\\(]([A-Za-z0-9/]+)[\\)\\]]$"); Chris@330: Chris@330: for (size_t i = 0; i < plugs.size(); ++i) { Chris@330: Chris@330: QString pluginId = plugs[i]; Chris@330: Chris@330: RealTimePluginFactory *factory = Chris@330: RealTimePluginFactory::instanceFor(pluginId); Chris@330: Chris@330: if (!factory) { Chris@330: std::cerr << "WARNING: TransformFactory::populateTransforms: No real time plugin factory for instance " << pluginId.toLocal8Bit().data() << std::endl; Chris@330: continue; Chris@330: } Chris@330: Chris@330: const RealTimePluginDescriptor *descriptor = Chris@330: factory->getPluginDescriptor(pluginId); Chris@330: Chris@330: if (!descriptor) { Chris@330: std::cerr << "WARNING: TransformFactory::populateTransforms: Failed to query plugin " << pluginId.toLocal8Bit().data() << std::endl; Chris@330: continue; Chris@330: } Chris@330: Chris@330: //!!! if (descriptor->controlOutputPortCount == 0 || Chris@330: // descriptor->audioInputPortCount == 0) continue; Chris@330: Chris@330: // std::cout << "TransformFactory::populateRealTimePlugins: plugin " << pluginId.toStdString() << " has " << descriptor->controlOutputPortCount << " control output ports, " << descriptor->audioOutputPortCount << " audio outputs, " << descriptor->audioInputPortCount << " audio inputs" << std::endl; Chris@330: Chris@330: QString pluginName = descriptor->name.c_str(); Chris@330: QString category = factory->getPluginCategory(pluginId); Chris@330: bool configurable = (descriptor->parameterCount > 0); Chris@330: QString maker = descriptor->maker.c_str(); Chris@330: if (maker == "") maker = tr(""); Chris@330: Chris@330: if (descriptor->audioInputPortCount > 0) { Chris@330: Chris@330: for (size_t j = 0; j < descriptor->controlOutputPortCount; ++j) { Chris@330: Chris@330: QString transformId = QString("%1:%2").arg(pluginId).arg(j); Chris@330: QString userName; Chris@330: QString units; Chris@330: QString portName; Chris@330: Chris@330: if (j < descriptor->controlOutputPortNames.size() && Chris@330: descriptor->controlOutputPortNames[j] != "") { Chris@330: Chris@330: portName = descriptor->controlOutputPortNames[j].c_str(); Chris@330: Chris@330: userName = tr("%1: %2") Chris@330: .arg(pluginName) Chris@330: .arg(portName); Chris@330: Chris@330: if (unitRE.indexIn(portName) >= 0) { Chris@330: units = unitRE.cap(1); Chris@330: } Chris@330: Chris@330: } else if (descriptor->controlOutputPortCount > 1) { Chris@330: Chris@330: userName = tr("%1: Output %2") Chris@330: .arg(pluginName) Chris@330: .arg(j + 1); Chris@330: Chris@330: } else { Chris@330: Chris@330: userName = pluginName; Chris@330: } Chris@330: Chris@330: QString description; Chris@330: Chris@330: if (portName != "") { Chris@330: description = tr("Extract \"%1\" data output from \"%2\" effect plugin (from %3)") Chris@330: .arg(portName) Chris@330: .arg(pluginName) Chris@330: .arg(maker); Chris@330: } else { Chris@330: description = tr("Extract data output %1 from \"%2\" effect plugin (from %3)") Chris@330: .arg(j + 1) Chris@330: .arg(pluginName) Chris@330: .arg(maker); Chris@330: } Chris@330: Chris@330: transforms[transformId] = Chris@330: TransformDescription(tr("Effects Data"), Chris@332: category, Chris@332: transformId, Chris@332: userName, Chris@332: userName, Chris@332: description, Chris@332: maker, Chris@332: units, Chris@332: configurable); Chris@330: } Chris@330: } Chris@330: Chris@330: if (!descriptor->isSynth || descriptor->audioInputPortCount > 0) { Chris@330: Chris@330: if (descriptor->audioOutputPortCount > 0) { Chris@330: Chris@330: QString transformId = QString("%1:A").arg(pluginId); Chris@330: QString type = tr("Effects"); Chris@330: Chris@330: QString description = tr("Transform audio signal with \"%1\" effect plugin (from %2)") Chris@330: .arg(pluginName) Chris@330: .arg(maker); Chris@330: Chris@330: if (descriptor->audioInputPortCount == 0) { Chris@330: type = tr("Generators"); Chris@330: QString description = tr("Generate audio signal using \"%1\" plugin (from %2)") Chris@330: .arg(pluginName) Chris@330: .arg(maker); Chris@330: } Chris@330: Chris@330: transforms[transformId] = Chris@330: TransformDescription(type, Chris@332: category, Chris@332: transformId, Chris@332: pluginName, Chris@332: pluginName, Chris@332: description, Chris@332: maker, Chris@332: "", Chris@332: configurable); Chris@330: } Chris@330: } Chris@330: } Chris@330: } Chris@330: Chris@350: Chris@350: Transform Chris@350: TransformFactory::getDefaultTransformFor(TransformId id, size_t rate) Chris@350: { Chris@350: Transform t; Chris@350: t.setIdentifier(id); Chris@350: if (rate != 0) t.setSampleRate(rate); Chris@350: Chris@351: Vamp::PluginBase *plugin = instantiateDefaultPluginFor(id, rate); Chris@350: Chris@350: if (plugin) { Chris@366: t.setPluginVersion(QString("%1").arg(plugin->getPluginVersion())); Chris@350: setParametersFromPlugin(t, plugin); Chris@350: makeContextConsistentWithPlugin(t, plugin); Chris@350: delete plugin; Chris@350: } Chris@350: Chris@350: return t; Chris@350: } Chris@350: Chris@350: Vamp::PluginBase * Chris@351: TransformFactory::instantiatePluginFor(const Transform &transform) Chris@351: { Chris@351: Vamp::PluginBase *plugin = instantiateDefaultPluginFor Chris@351: (transform.getIdentifier(), transform.getSampleRate()); Chris@351: if (plugin) { Chris@351: setPluginParameters(transform, plugin); Chris@351: } Chris@351: return plugin; Chris@351: } Chris@351: Chris@351: Vamp::PluginBase * Chris@351: TransformFactory::instantiateDefaultPluginFor(TransformId identifier, size_t rate) Chris@350: { Chris@350: Transform t; Chris@350: t.setIdentifier(identifier); Chris@350: if (rate == 0) rate = 44100; Chris@350: QString pluginId = t.getPluginIdentifier(); Chris@350: Chris@350: Vamp::PluginBase *plugin = 0; Chris@350: Chris@350: if (t.getType() == Transform::FeatureExtraction) { Chris@350: Chris@350: FeatureExtractionPluginFactory *factory = Chris@350: FeatureExtractionPluginFactory::instanceFor(pluginId); Chris@350: Chris@439: if (factory) { Chris@439: plugin = factory->instantiatePlugin(pluginId, rate); Chris@439: } Chris@350: Chris@350: } else { Chris@350: Chris@350: RealTimePluginFactory *factory = Chris@350: RealTimePluginFactory::instanceFor(pluginId); Chris@439: Chris@439: if (factory) { Chris@439: plugin = factory->instantiatePlugin(pluginId, 0, 0, rate, 1024, 1); Chris@439: } Chris@350: } Chris@350: Chris@350: return plugin; Chris@350: } Chris@350: Chris@350: Vamp::Plugin * Chris@350: TransformFactory::downcastVampPlugin(Vamp::PluginBase *plugin) Chris@350: { Chris@350: Vamp::Plugin *vp = dynamic_cast(plugin); Chris@350: if (!vp) { Chris@350: // std::cerr << "makeConsistentWithPlugin: not a Vamp::Plugin" << std::endl; Chris@350: vp = dynamic_cast(plugin); //!!! why? Chris@350: } Chris@350: if (!vp) { Chris@350: // std::cerr << "makeConsistentWithPlugin: not a Vamp::PluginHostAdapter" << std::endl; Chris@350: vp = dynamic_cast(plugin); //!!! no, I mean really why? Chris@350: } Chris@350: if (!vp) { Chris@350: // std::cerr << "makeConsistentWithPlugin: not a Vamp::HostExt::PluginWrapper" << std::endl; Chris@350: } Chris@350: return vp; Chris@350: } Chris@350: Chris@330: bool Chris@330: TransformFactory::haveTransform(TransformId identifier) Chris@330: { Chris@333: if (m_transforms.empty()) populateTransforms(); Chris@330: return (m_transforms.find(identifier) != m_transforms.end()); Chris@330: } Chris@330: Chris@330: QString Chris@330: TransformFactory::getTransformName(TransformId identifier) Chris@330: { Chris@330: if (m_transforms.find(identifier) != m_transforms.end()) { Chris@330: return m_transforms[identifier].name; Chris@330: } else return ""; Chris@330: } Chris@330: Chris@330: QString Chris@330: TransformFactory::getTransformFriendlyName(TransformId identifier) Chris@330: { Chris@330: if (m_transforms.find(identifier) != m_transforms.end()) { Chris@330: return m_transforms[identifier].friendlyName; Chris@330: } else return ""; Chris@330: } Chris@330: Chris@330: QString Chris@330: TransformFactory::getTransformUnits(TransformId identifier) Chris@330: { Chris@330: if (m_transforms.find(identifier) != m_transforms.end()) { Chris@330: return m_transforms[identifier].units; Chris@330: } else return ""; Chris@330: } Chris@330: Chris@350: Vamp::Plugin::InputDomain Chris@350: TransformFactory::getTransformInputDomain(TransformId identifier) Chris@350: { Chris@350: Transform transform; Chris@350: transform.setIdentifier(identifier); Chris@350: Chris@350: if (transform.getType() != Transform::FeatureExtraction) { Chris@350: return Vamp::Plugin::TimeDomain; Chris@350: } Chris@350: Chris@350: Vamp::Plugin *plugin = Chris@351: downcastVampPlugin(instantiateDefaultPluginFor(identifier, 0)); Chris@350: Chris@350: if (plugin) { Chris@350: Vamp::Plugin::InputDomain d = plugin->getInputDomain(); Chris@350: delete plugin; Chris@350: return d; Chris@350: } Chris@350: Chris@350: return Vamp::Plugin::TimeDomain; Chris@350: } Chris@350: Chris@330: bool Chris@330: TransformFactory::isTransformConfigurable(TransformId identifier) Chris@330: { Chris@330: if (m_transforms.find(identifier) != m_transforms.end()) { Chris@330: return m_transforms[identifier].configurable; Chris@330: } else return false; Chris@330: } Chris@330: Chris@330: bool Chris@330: TransformFactory::getTransformChannelRange(TransformId identifier, Chris@330: int &min, int &max) Chris@330: { Chris@330: QString id = identifier.section(':', 0, 2); Chris@330: Chris@330: if (FeatureExtractionPluginFactory::instanceFor(id)) { Chris@330: Chris@330: Vamp::Plugin *plugin = Chris@330: FeatureExtractionPluginFactory::instanceFor(id)-> Chris@350: instantiatePlugin(id, 44100); Chris@330: if (!plugin) return false; Chris@330: Chris@330: min = plugin->getMinChannelCount(); Chris@330: max = plugin->getMaxChannelCount(); Chris@330: delete plugin; Chris@330: Chris@330: return true; Chris@330: Chris@330: } else if (RealTimePluginFactory::instanceFor(id)) { Chris@330: Chris@350: // don't need to instantiate Chris@350: Chris@330: const RealTimePluginDescriptor *descriptor = Chris@330: RealTimePluginFactory::instanceFor(id)-> Chris@330: getPluginDescriptor(id); Chris@330: if (!descriptor) return false; Chris@330: Chris@330: min = descriptor->audioInputPortCount; Chris@330: max = descriptor->audioInputPortCount; Chris@330: Chris@330: return true; Chris@330: } Chris@330: Chris@330: return false; Chris@330: } Chris@332: Chris@332: void Chris@332: TransformFactory::setParametersFromPlugin(Transform &transform, Chris@332: Vamp::PluginBase *plugin) Chris@332: { Chris@332: Transform::ParameterMap pmap; Chris@332: Chris@350: //!!! record plugin & API version Chris@350: Chris@350: //!!! check that this is the right plugin! Chris@350: Chris@332: Vamp::PluginBase::ParameterList parameters = Chris@332: plugin->getParameterDescriptors(); Chris@332: Chris@332: for (Vamp::PluginBase::ParameterList::const_iterator i = parameters.begin(); Chris@332: i != parameters.end(); ++i) { Chris@332: pmap[i->identifier.c_str()] = plugin->getParameter(i->identifier); Chris@332: } Chris@332: Chris@332: transform.setParameters(pmap); Chris@332: Chris@332: if (plugin->getPrograms().empty()) { Chris@332: transform.setProgram(""); Chris@332: } else { Chris@332: transform.setProgram(plugin->getCurrentProgram().c_str()); Chris@332: } Chris@332: Chris@332: RealTimePluginInstance *rtpi = Chris@332: dynamic_cast(plugin); Chris@332: Chris@332: Transform::ConfigurationMap cmap; Chris@332: Chris@332: if (rtpi) { Chris@332: Chris@332: RealTimePluginInstance::ConfigurationPairMap configurePairs = Chris@332: rtpi->getConfigurePairs(); Chris@332: Chris@332: for (RealTimePluginInstance::ConfigurationPairMap::const_iterator i Chris@332: = configurePairs.begin(); i != configurePairs.end(); ++i) { Chris@332: cmap[i->first.c_str()] = i->second.c_str(); Chris@332: } Chris@332: } Chris@332: Chris@332: transform.setConfiguration(cmap); Chris@332: } Chris@332: Chris@332: void Chris@350: TransformFactory::setPluginParameters(const Transform &transform, Chris@350: Vamp::PluginBase *plugin) Chris@350: { Chris@350: //!!! check plugin & API version (see e.g. PluginXml::setParameters) Chris@350: Chris@350: //!!! check that this is the right plugin! Chris@350: Chris@350: RealTimePluginInstance *rtpi = Chris@350: dynamic_cast(plugin); Chris@350: Chris@350: if (rtpi) { Chris@350: const Transform::ConfigurationMap &cmap = transform.getConfiguration(); Chris@350: for (Transform::ConfigurationMap::const_iterator i = cmap.begin(); Chris@350: i != cmap.end(); ++i) { Chris@350: rtpi->configure(i->first.toStdString(), i->second.toStdString()); Chris@350: } Chris@350: } Chris@350: Chris@350: if (transform.getProgram() != "") { Chris@350: plugin->selectProgram(transform.getProgram().toStdString()); Chris@350: } Chris@350: Chris@350: const Transform::ParameterMap &pmap = transform.getParameters(); Chris@350: Chris@350: Vamp::PluginBase::ParameterList parameters = Chris@350: plugin->getParameterDescriptors(); Chris@350: Chris@350: for (Vamp::PluginBase::ParameterList::const_iterator i = parameters.begin(); Chris@350: i != parameters.end(); ++i) { Chris@350: QString key = i->identifier.c_str(); Chris@350: Transform::ParameterMap::const_iterator pmi = pmap.find(key); Chris@350: if (pmi != pmap.end()) { Chris@350: plugin->setParameter(i->identifier, pmi->second); Chris@350: } Chris@350: } Chris@350: } Chris@350: Chris@350: void Chris@332: TransformFactory::makeContextConsistentWithPlugin(Transform &transform, Chris@332: Vamp::PluginBase *plugin) Chris@332: { Chris@350: const Vamp::Plugin *vp = downcastVampPlugin(plugin); Chris@332: Chris@332: if (!vp) { Chris@332: // time domain input for real-time effects plugin Chris@332: if (!transform.getBlockSize()) { Chris@332: if (!transform.getStepSize()) transform.setStepSize(1024); Chris@332: transform.setBlockSize(transform.getStepSize()); Chris@332: } else { Chris@332: transform.setStepSize(transform.getBlockSize()); Chris@332: } Chris@332: } else { Chris@332: Vamp::Plugin::InputDomain domain = vp->getInputDomain(); Chris@332: if (!transform.getStepSize()) { Chris@332: transform.setStepSize(vp->getPreferredStepSize()); Chris@332: } Chris@332: if (!transform.getBlockSize()) { Chris@332: transform.setBlockSize(vp->getPreferredBlockSize()); Chris@332: } Chris@332: if (!transform.getBlockSize()) { Chris@332: transform.setBlockSize(1024); Chris@332: } Chris@332: if (!transform.getStepSize()) { Chris@332: if (domain == Vamp::Plugin::FrequencyDomain) { Chris@332: // std::cerr << "frequency domain, step = " << blockSize/2 << std::endl; Chris@332: transform.setStepSize(transform.getBlockSize()/2); Chris@332: } else { Chris@332: // std::cerr << "time domain, step = " << blockSize/2 << std::endl; Chris@332: transform.setStepSize(transform.getBlockSize()); Chris@332: } Chris@332: } Chris@332: } Chris@332: } Chris@332: Chris@350: QString Chris@350: TransformFactory::getPluginConfigurationXml(const Transform &t) Chris@332: { Chris@350: QString xml; Chris@350: Chris@351: Vamp::PluginBase *plugin = instantiateDefaultPluginFor Chris@351: (t.getIdentifier(), 0); Chris@350: if (!plugin) { Chris@350: std::cerr << "TransformFactory::getPluginConfigurationXml: " Chris@350: << "Unable to instantiate plugin for transform \"" Chris@350: << t.getIdentifier().toStdString() << "\"" << std::endl; Chris@350: return xml; Chris@332: } Chris@332: Chris@351: setPluginParameters(t, plugin); Chris@351: Chris@350: QTextStream out(&xml); Chris@350: PluginXml(plugin).toXml(out); Chris@350: delete plugin; Chris@332: Chris@350: return xml; Chris@350: } Chris@332: Chris@350: void Chris@350: TransformFactory::setParametersFromPluginConfigurationXml(Transform &t, Chris@350: QString xml) Chris@350: { Chris@351: Vamp::PluginBase *plugin = instantiateDefaultPluginFor Chris@351: (t.getIdentifier(), 0); Chris@350: if (!plugin) { Chris@350: std::cerr << "TransformFactory::setParametersFromPluginConfigurationXml: " Chris@350: << "Unable to instantiate plugin for transform \"" Chris@350: << t.getIdentifier().toStdString() << "\"" << std::endl; Chris@350: return; Chris@332: } Chris@332: Chris@350: PluginXml(plugin).setParametersFromXml(xml); Chris@350: setParametersFromPlugin(t, plugin); Chris@350: delete plugin; Chris@332: } Chris@332: