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@320: #ifndef _TRANSFORM_H_
Chris@320: #define _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 <vamp-hostsdk/PluginBase.h>
Chris@486: 
Chris@328: #include <QString>
Chris@320: 
Chris@400: #include <map>
Chris@848: #include <vector>
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@350:      * This is the inverse of toXml.
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@328:     enum Type { FeatureExtraction, RealTimeEffect };
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<QString, float> 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<QString, QString> 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@350:     size_t getStepSize() const;
Chris@350:     void setStepSize(size_t s);
Chris@328:     
Chris@350:     size_t getBlockSize() const;
Chris@350:     void setBlockSize(size_t 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@350:     float getSampleRate() const; // 0 -> as input
Chris@350:     void setSampleRate(float rate);
Chris@328: 
Chris@328:     void toXml(QTextStream &stream, QString indent = "",
Chris@328:                QString extraAttributes = "") const;
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@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 <typename A, typename B>
Chris@400:     bool mapLessThan(const std::map<A, B> &a, const std::map<A, B> &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<A, B>::const_iterator i;
Chris@400:         typename std::map<A, B>::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@328:     size_t m_stepSize;
Chris@328:     size_t m_blockSize;
Chris@328:     WindowType m_windowType;
Chris@350:     RealTime m_startTime;
Chris@350:     RealTime m_duration;
Chris@328:     float m_sampleRate;
Chris@320: };
Chris@320: 
Chris@848: typedef std::vector<Transform> Transforms;
Chris@848: 
Chris@320: #endif
Chris@328: