Chris@320: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@320: Chris@320: /* Chris@320: Sonic Visualiser Chris@320: An audio file viewer and annotation editor. Chris@320: Centre for Digital Music, Queen Mary, University of London. Chris@320: This file copyright 2006 Chris Cannam and QMUL. Chris@320: Chris@320: This program is free software; you can redistribute it and/or Chris@320: modify it under the terms of the GNU General Public License as Chris@320: published by the Free Software Foundation; either version 2 of the Chris@320: License, or (at your option) any later version. See the file Chris@320: COPYING included with this distribution for more information. Chris@320: */ Chris@320: Chris@320: #ifndef _TRANSFORM_FACTORY_H_ Chris@320: #define _TRANSFORM_FACTORY_H_ Chris@320: Chris@320: #include "Transform.h" Chris@320: #include "PluginTransform.h" Chris@320: Chris@320: #include Chris@320: #include Chris@320: Chris@320: namespace Vamp { class PluginBase; } Chris@320: Chris@320: class AudioCallbackPlaySource; Chris@320: Chris@320: class TransformFactory : public QObject Chris@320: { Chris@320: Q_OBJECT Chris@320: Chris@320: public: Chris@320: virtual ~TransformFactory(); Chris@320: Chris@320: static TransformFactory *getInstance(); Chris@320: Chris@320: // The identifier is intended to be computer-referenceable, and Chris@320: // unique within the application. The name is intended to be Chris@320: // human readable. In principle it doesn't have to be unique, but Chris@320: // the factory will add suffixes to ensure that it is, all the Chris@320: // same (just to avoid user confusion). The friendly name is a Chris@320: // shorter version of the name. The type is also intended to be Chris@320: // user-readable, for use in menus. Chris@320: Chris@320: struct TransformDesc { Chris@320: Chris@320: TransformDesc() { } Chris@320: TransformDesc(QString _type, QString _category, Chris@320: TransformId _identifier, QString _name, Chris@320: QString _friendlyName, QString _description, Chris@320: QString _maker, QString _units, bool _configurable) : Chris@320: type(_type), category(_category), Chris@320: identifier(_identifier), name(_name), Chris@320: friendlyName(_friendlyName), description(_description), Chris@320: maker(_maker), units(_units), configurable(_configurable) { } Chris@320: Chris@320: QString type; // e.g. feature extraction plugin Chris@320: QString category; // e.g. time > onsets Chris@320: TransformId identifier; // e.g. vamp:vamp-aubio:aubioonset Chris@320: QString name; // plugin's name if 1 output, else "name: output" Chris@320: QString friendlyName; // short text for layer name Chris@320: QString description; // sentence describing transform Chris@320: QString maker; Chris@320: QString units; Chris@320: bool configurable; Chris@320: Chris@320: bool operator<(const TransformDesc &od) const { Chris@320: return (name < od.name); Chris@320: }; Chris@320: }; Chris@320: typedef std::vector TransformList; Chris@320: Chris@320: TransformList getAllTransforms(); Chris@320: Chris@320: std::vector getAllTransformTypes(); Chris@320: Chris@320: std::vector getTransformCategories(QString transformType); Chris@320: std::vector getTransformMakers(QString transformType); Chris@320: Chris@320: /** Chris@320: * Get a configuration XML string for the given transform (by Chris@320: * asking the user, most likely). Returns the selected input Chris@320: * model if the transform is acceptable, 0 if the operation should Chris@320: * be cancelled. Audio callback play source may be used to Chris@320: * audition effects plugins, if provided. Chris@320: */ Chris@320: Model *getConfigurationForTransform(TransformId identifier, Chris@320: const std::vector &candidateInputModels, Chris@320: PluginTransform::ExecutionContext &context, Chris@320: QString &configurationXml, Chris@320: AudioCallbackPlaySource *source = 0, Chris@320: size_t startFrame = 0, Chris@320: size_t duration = 0); Chris@320: Chris@320: /** Chris@320: * Get the default execution context for the given transform Chris@320: * and input model (if known). Chris@320: */ Chris@320: PluginTransform::ExecutionContext getDefaultContextForTransform(TransformId identifier, Chris@320: Model *inputModel = 0); Chris@320: Chris@320: /** Chris@320: * Return the output model resulting from applying the named Chris@320: * transform to the given input model. The transform may still be Chris@320: * working in the background when the model is returned; check the Chris@320: * output model's isReady completion status for more details. Chris@320: * Chris@320: * If the transform is unknown or the input model is not an Chris@320: * appropriate type for the given transform, or if some other Chris@320: * problem occurs, return 0. Chris@320: * Chris@320: * The returned model is owned by the caller and must be deleted Chris@320: * when no longer needed. Chris@320: */ Chris@320: Model *transform(TransformId identifier, Model *inputModel, Chris@320: const PluginTransform::ExecutionContext &context, Chris@320: QString configurationXml = ""); Chris@320: Chris@320: /** Chris@320: * Full name of a transform, suitable for putting on a menu. Chris@320: */ Chris@320: QString getTransformName(TransformId identifier); Chris@320: Chris@320: /** Chris@320: * Brief but friendly name of a transform, suitable for use Chris@320: * as the name of the output layer. Chris@320: */ Chris@320: QString getTransformFriendlyName(TransformId identifier); Chris@320: Chris@320: QString getTransformUnits(TransformId identifier); Chris@320: Chris@320: /** Chris@320: * Return true if the transform has any configurable parameters, Chris@320: * i.e. if getConfigurationForTransform can ever return a non-trivial Chris@320: * (not equivalent to empty) configuration string. Chris@320: */ Chris@320: bool isTransformConfigurable(TransformId identifier); Chris@320: Chris@320: /** Chris@320: * If the transform has a prescribed number or range of channel Chris@320: * inputs, return true and set minChannels and maxChannels to the Chris@320: * minimum and maximum number of channel inputs the transform can Chris@320: * accept. Return false if it doesn't care. Chris@320: */ Chris@320: bool getTransformChannelRange(TransformId identifier, Chris@320: int &minChannels, int &maxChannels); Chris@320: Chris@320: protected slots: Chris@320: void transformFinished(); Chris@320: Chris@320: void modelAboutToBeDeleted(Model *); Chris@320: Chris@320: protected: Chris@320: Transform *createTransform(TransformId identifier, Model *inputModel, Chris@320: const PluginTransform::ExecutionContext &context, Chris@320: QString configurationXml); Chris@320: Chris@320: struct TransformIdent Chris@320: { Chris@320: TransformId identifier; Chris@320: QString configurationXml; Chris@320: }; Chris@320: Chris@320: typedef std::map TransformConfigurationMap; Chris@320: TransformConfigurationMap m_lastConfigurations; Chris@320: Chris@320: typedef std::map TransformDescriptionMap; Chris@320: TransformDescriptionMap m_transforms; Chris@320: Chris@320: typedef std::set TransformSet; Chris@320: TransformSet m_runningTransforms; Chris@320: Chris@320: void populateTransforms(); Chris@320: void populateFeatureExtractionPlugins(TransformDescriptionMap &); Chris@320: void populateRealTimePlugins(TransformDescriptionMap &); Chris@320: Chris@320: bool getChannelRange(TransformId identifier, Chris@320: Vamp::PluginBase *plugin, int &min, int &max); Chris@320: Chris@320: static TransformFactory *m_instance; Chris@320: }; Chris@320: Chris@320: Chris@320: #endif