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-2007 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@1546: #ifndef SV_TRANSFORM_FACTORY_H Chris@1546: #define SV_TRANSFORM_FACTORY_H Chris@330: Chris@330: #include "TransformDescription.h" Chris@330: Chris@457: #include "base/TextMatcher.h" Chris@457: Chris@475: #include Chris@350: Chris@387: #include Chris@443: #include Chris@460: #include Chris@460: #include Chris@387: Chris@330: #include Chris@330: #include Chris@1841: #include Chris@330: Chris@330: class TransformFactory : public QObject Chris@330: { Chris@330: Q_OBJECT Chris@330: Chris@330: public: Chris@457: TransformFactory(); Chris@330: virtual ~TransformFactory(); Chris@330: Chris@330: static TransformFactory *getInstance(); Chris@574: static void deleteInstance(); // only when exiting Chris@330: Chris@477: /** Chris@477: * TransformFactory has a background thread that can populate Chris@477: * uninstalled transforms from network RDF resources. It is not Chris@477: * started by default, but it's a good idea to start it when the Chris@477: * program starts up, if the uninstalled transforms may be of use Chris@477: * later; otherwise there will be a bottleneck the first time Chris@477: * they're requested. Chris@477: * Chris@477: * If this thread is not already running, start it now. Chris@477: */ Chris@477: void startPopulationThread(); Chris@477: Chris@350: TransformList getAllTransformDescriptions(); Chris@350: TransformDescription getTransformDescription(TransformId id); Chris@485: bool haveInstalledTransforms(); Chris@330: Chris@457: TransformList getUninstalledTransformDescriptions(); Chris@457: TransformDescription getUninstalledTransformDescription(TransformId id); Chris@485: bool haveUninstalledTransforms(bool waitForCheckToComplete = false); Chris@457: Chris@457: typedef enum { Chris@457: TransformUnknown, Chris@457: TransformInstalled, Chris@457: TransformNotInstalled Chris@457: } TransformInstallStatus; Chris@457: Chris@457: TransformInstallStatus getTransformInstallStatus(TransformId id); Chris@457: Chris@487: std::vector getAllTransformTypes(); Chris@487: std::vector getTransformCategories(TransformDescription::Type); Chris@487: std::vector getTransformMakers(TransformDescription::Type); Chris@487: QString getTransformTypeName(TransformDescription::Type) const; Chris@330: Chris@457: typedef std::map SearchResults; Chris@443: SearchResults search(QString keyword); Chris@443: SearchResults search(QStringList keywords); Chris@443: Chris@330: /** Chris@330: * Return true if the given transform is known. Chris@330: */ Chris@330: bool haveTransform(TransformId identifier); Chris@330: Chris@330: /** Chris@350: * A single transform ID can lead to many possible Transforms, Chris@350: * with different parameters and execution context settings. Chris@350: * Return the default one for the given transform. Chris@350: */ Chris@1830: Transform getDefaultTransformFor(TransformId identifier, Chris@1830: sv_samplerate_t rate = 0); Chris@350: Chris@350: /** Chris@330: * Full name of a transform, suitable for putting on a menu. Chris@330: */ Chris@330: QString getTransformName(TransformId identifier); Chris@330: Chris@330: /** Chris@330: * Brief but friendly name of a transform, suitable for use Chris@330: * as the name of the output layer. Chris@330: */ Chris@330: QString getTransformFriendlyName(TransformId identifier); Chris@330: Chris@330: QString getTransformUnits(TransformId identifier); Chris@330: Chris@1845: Provider getTransformProvider(TransformId identifier); Chris@472: Chris@350: Vamp::Plugin::InputDomain getTransformInputDomain(TransformId identifier); Chris@350: Chris@330: /** Chris@330: * Return true if the transform has any configurable parameters, Chris@330: * i.e. if getConfigurationForTransform can ever return a non-trivial Chris@330: * (not equivalent to empty) configuration string. Chris@330: */ Chris@330: bool isTransformConfigurable(TransformId identifier); Chris@330: Chris@330: /** Chris@330: * If the transform has a prescribed number or range of channel Chris@330: * inputs, return true and set minChannels and maxChannels to the Chris@330: * minimum and maximum number of channel inputs the transform can Chris@330: * accept. Return false if it doesn't care. Chris@330: */ Chris@330: bool getTransformChannelRange(TransformId identifier, Chris@330: int &minChannels, int &maxChannels); Chris@332: Chris@332: /** Chris@351: * Load an appropriate plugin for the given transform and set the Chris@351: * parameters, program and configuration strings on that plugin Chris@351: * from the Transform object. Chris@351: * Chris@351: * Note that this requires that the transform has a meaningful Chris@351: * sample rate set, as that is used as the rate for the plugin. A Chris@351: * Transform can legitimately have rate set at zero (= "use the Chris@351: * rate of the input source"), so the caller will need to test for Chris@351: * this case. Chris@351: * Chris@351: * Returns the plugin thus loaded. This will be a Chris@351: * Vamp::PluginBase, but not necessarily a Vamp::Plugin (only if Chris@351: * the transform was a feature-extraction type -- call Chris@351: * downcastVampPlugin if you only want Vamp::Plugins). Returns Chris@1830: * nullptr if no suitable plugin was available. Chris@351: */ Chris@1830: std::shared_ptr instantiatePluginFor(const Transform &transform); Chris@351: Chris@351: /** Chris@332: * Set the plugin parameters, program and configuration strings on Chris@332: * the given Transform object from the given plugin instance. Chris@332: * Note that no check is made whether the plugin is actually the Chris@332: * "correct" one for the transform. Chris@332: */ Chris@1830: void setParametersFromPlugin(Transform &transform, std::shared_ptr plugin); Chris@332: Chris@332: /** Chris@350: * Set the parameters, program and configuration strings on the Chris@350: * given plugin from the given Transform object. Chris@350: */ Chris@1830: void setPluginParameters(const Transform &transform, std::shared_ptr plugin); Chris@350: Chris@350: /** Chris@332: * If the given Transform object has no processing step and block Chris@332: * sizes set, set them to appropriate defaults for the given Chris@332: * plugin. Chris@332: */ Chris@1830: void makeContextConsistentWithPlugin(Transform &transform, std::shared_ptr plugin); Chris@332: Chris@332: /** Chris@350: * Retrieve a XML fragment that describes the Chris@350: * plugin parameters, program and configuration data for the given Chris@350: * transform. Chris@350: * Chris@350: * This function is provided for backward compatibility only. Use Chris@350: * Transform::toXml where compatibility with PluginXml Chris@350: * descriptions of transforms is not required. Chris@332: */ Chris@350: QString getPluginConfigurationXml(const Transform &transform); Chris@350: Chris@350: /** Chris@350: * Set the plugin parameters, program and configuration strings on Chris@350: * the given Transform object from the given XML Chris@350: * fragment. Chris@350: * Chris@350: * This function is provided for backward compatibility only. Use Chris@350: * Transform(QString) where compatibility with PluginXml Chris@350: * descriptions of transforms is not required. Chris@350: */ Chris@350: void setParametersFromPluginConfigurationXml(Transform &transform, Chris@350: QString xml); Chris@1149: Chris@1227: QString getStartupFailureReport() const { Chris@1227: return m_errorString; Chris@1227: } Chris@1227: Chris@330: protected: Chris@330: typedef std::map TransformDescriptionMap; Chris@457: Chris@330: TransformDescriptionMap m_transforms; Chris@457: bool m_transformsPopulated; Chris@457: Chris@457: TransformDescriptionMap m_uninstalledTransforms; Chris@457: bool m_uninstalledTransformsPopulated; Chris@330: Chris@1227: QString m_errorString; Chris@1227: Chris@330: void populateTransforms(); Chris@457: void populateUninstalledTransforms(); Chris@330: void populateFeatureExtractionPlugins(TransformDescriptionMap &); Chris@330: void populateRealTimePlugins(TransformDescriptionMap &); Chris@330: Chris@1830: std::shared_ptr instantiateDefaultPluginFor(TransformId id, sv_samplerate_t rate); Chris@460: QMutex m_transformsMutex; Chris@460: QMutex m_uninstalledTransformsMutex; Chris@460: Chris@460: class UninstalledTransformsPopulateThread : public QThread Chris@460: { Chris@460: public: Chris@460: UninstalledTransformsPopulateThread(TransformFactory *factory) : Chris@460: m_factory(factory) { Chris@460: } Chris@1580: void run() override; Chris@460: TransformFactory *m_factory; Chris@460: }; Chris@460: Chris@477: UninstalledTransformsPopulateThread *m_thread; Chris@574: bool m_exiting; Chris@479: bool m_populatingSlowly; Chris@477: Chris@1842: SearchResults searchUnadjusted(QStringList keywords); Chris@1842: Chris@330: static TransformFactory *m_instance; Chris@330: }; Chris@330: Chris@330: Chris@330: #endif