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@328: This file copyright 2006-2007 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@1581: #ifndef SV_TRANSFORM_H Chris@1581: #define SV_TRANSFORM_H Chris@320: Chris@328: #include "base/XmlExportable.h" Chris@328: #include "base/Window.h" Chris@350: #include "base/RealTime.h" Chris@328: Chris@486: #include Chris@486: Chris@328: #include Chris@320: Chris@400: #include Chris@848: #include Chris@400: Chris@320: typedef QString TransformId; Chris@320: Chris@350: class QXmlAttributes; Chris@350: Chris@328: class Transform : public XmlExportable Chris@320: { Chris@320: public: Chris@350: /** Chris@350: * Construct a new Transform with default data and no identifier. Chris@350: * The Transform object will be meaningless until some data and an Chris@350: * identifier have been set on it. Chris@350: * Chris@350: * To construct a Transform for use with a particular transform Chris@350: * identifier, use TransformFactory::getDefaultTransformFor. Chris@350: */ Chris@328: Transform(); Chris@350: Chris@350: /** Chris@350: * Construct a Transform by parsing the given XML data string. Chris@1163: * This is the inverse of toXml. If this fails, getErrorString() Chris@1163: * will return a non-empty string. Chris@350: */ Chris@350: Transform(QString xml); Chris@350: Chris@320: virtual ~Transform(); Chris@320: Chris@350: /** Chris@350: * Compare two Transforms. They only compare equal if every data Chris@350: * element matches. Chris@350: */ Chris@400: bool operator==(const Transform &) const; Chris@400: Chris@400: /** Chris@400: * Order two Transforms, so that they can be used as keys in Chris@400: * containers. Chris@400: */ Chris@400: bool operator<(const Transform &) const; Chris@350: Chris@350: void setIdentifier(TransformId id); Chris@350: TransformId getIdentifier() const; Chris@320: Chris@1138: enum Type { FeatureExtraction, RealTimeEffect, UnknownType }; Chris@328: Chris@328: Type getType() const; Chris@328: QString getPluginIdentifier() const; Chris@328: QString getOutput() const; Chris@353: Chris@353: void setPluginIdentifier(QString pluginIdentifier); Chris@353: void setOutput(QString output); Chris@353: Chris@353: // Turn a plugin ID and output name into a transform ID. Note Chris@353: // that our pluginIdentifier is the same thing as the Vamp SDK's Chris@353: // PluginLoader::PluginKey. Chris@353: static TransformId getIdentifierForPluginOutput(QString pluginIdentifier, Chris@353: QString output = ""); Chris@328: Chris@328: typedef std::map ParameterMap; Chris@328: Chris@350: const ParameterMap &getParameters() const; Chris@350: void setParameters(const ParameterMap &pm); Chris@350: void setParameter(QString name, float value); Chris@328: Chris@328: typedef std::map ConfigurationMap; Chris@328: Chris@350: const ConfigurationMap &getConfiguration() const; Chris@350: void setConfiguration(const ConfigurationMap &cm); Chris@350: void setConfigurationValue(QString name, QString value); Chris@328: Chris@508: enum SummaryType { Chris@508: Chris@508: // This is the same as Vamp::PluginSummarisingAdapter::SummaryType Chris@508: // except with NoSummary instead of UnknownSummaryType Chris@508: Chris@508: Minimum = 0, Chris@508: Maximum = 1, Chris@508: Mean = 2, Chris@508: Median = 3, Chris@508: Mode = 4, Chris@508: Sum = 5, Chris@508: Variance = 6, Chris@508: StandardDeviation = 7, Chris@508: Count = 8, Chris@508: Chris@508: NoSummary = 999 Chris@508: }; Chris@508: SummaryType getSummaryType() const; Chris@508: void setSummaryType(SummaryType type); Chris@508: Chris@366: QString getPluginVersion() const; Chris@366: void setPluginVersion(QString version); Chris@366: Chris@350: QString getProgram() const; Chris@350: void setProgram(QString program); Chris@328: Chris@930: int getStepSize() const; Chris@930: void setStepSize(int s); Chris@328: Chris@930: int getBlockSize() const; Chris@930: void setBlockSize(int s); Chris@328: Chris@350: WindowType getWindowType() const; Chris@350: void setWindowType(WindowType type); Chris@350: Chris@350: RealTime getStartTime() const; Chris@350: void setStartTime(RealTime t); Chris@350: Chris@350: RealTime getDuration() const; // 0 -> all Chris@350: void setDuration(RealTime d); Chris@350: Chris@1047: sv_samplerate_t getSampleRate() const; // 0 -> as input Chris@1047: void setSampleRate(sv_samplerate_t rate); Chris@328: Chris@328: void toXml(QTextStream &stream, QString indent = "", Chris@1580: QString extraAttributes = "") const override; Chris@328: Chris@350: /** Chris@350: * Set the main transform data from the given XML attributes. Chris@350: * This does not set the parameters or configuration, which are Chris@350: * exported to separate XML elements rather than attributes of the Chris@350: * transform element. Chris@366: * Chris@366: * Note that this only sets those attributes which are actually Chris@366: * present in the argument. Any attributes not defined in the Chris@366: * attribute will remain unchanged in the Transform. If your aim Chris@366: * is to create a transform exactly matching the given attributes, Chris@366: * ensure you start from an empty transform rather than one that Chris@366: * has already been configured. Chris@350: */ Chris@350: void setFromXmlAttributes(const QXmlAttributes &); Chris@320: Chris@1163: QString getErrorString() const { return m_errorString; } Chris@1163: Chris@508: static SummaryType stringToSummaryType(QString); Chris@508: static QString summaryTypeToString(SummaryType); Chris@508: Chris@320: protected: Chris@328: TransformId m_id; // pluginid:output, that is type:soname:label:output Chris@328: Chris@328: static QString createIdentifier Chris@328: (QString type, QString soName, QString label, QString output); Chris@320: Chris@328: static void parseIdentifier Chris@328: (QString identifier, Chris@328: QString &type, QString &soName, QString &label, QString &output); Chris@328: Chris@400: template Chris@400: bool mapLessThan(const std::map &a, const std::map &b) const { Chris@400: // Return true if a is "less than" b. Ordering doesn't have Chris@400: // to be meaningful, just consistent. Chris@400: typename std::map::const_iterator i; Chris@400: typename std::map::const_iterator j; Chris@400: for (i = a.begin(), j = b.begin(); i != a.end(); ++i) { Chris@400: if (j == b.end()) return false; // a is longer than b Chris@400: if (i->first != j->first) return i->first < j->first; Chris@400: if (i->second != j->second) return i->second < j->second; Chris@400: } Chris@400: if (j != b.end()) return true; // a is shorter than b Chris@400: return false; // equal Chris@400: } Chris@400: Chris@328: ParameterMap m_parameters; Chris@328: ConfigurationMap m_configuration; Chris@508: SummaryType m_summaryType; Chris@366: QString m_pluginVersion; Chris@328: QString m_program; Chris@930: int m_stepSize; Chris@930: int m_blockSize; Chris@328: WindowType m_windowType; Chris@350: RealTime m_startTime; Chris@350: RealTime m_duration; Chris@1047: sv_samplerate_t m_sampleRate; Chris@1163: QString m_errorString; Chris@320: }; Chris@320: Chris@848: typedef std::vector Transforms; Chris@848: Chris@320: #endif Chris@328: