view transform/TransformFactory.h @ 490:c3fb8258e34d

* Make it possible to import an entire session from an RDF document. However, at the moment the timings of events appear to be constrained by how far the audio decoder has got through its audio file at the time the event is queried -- need to investigate.
author Chris Cannam
date Fri, 21 Nov 2008 18:03:14 +0000
parents c45e6c6722e0
children 1b8c748fd7ea
line wrap: on
line source
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */

/*
    Sonic Visualiser
    An audio file viewer and annotation editor.
    Centre for Digital Music, Queen Mary, University of London.
    This file copyright 2006-2007 Chris Cannam and QMUL.
   
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
    License, or (at your option) any later version.  See the file
    COPYING included with this distribution for more information.
*/

#ifndef _TRANSFORM_FACTORY_H_
#define _TRANSFORM_FACTORY_H_

#include "TransformDescription.h"

#include "base/TextMatcher.h"

#include <vamp-hostsdk/Plugin.h>

#include <QObject>
#include <QStringList>
#include <QThread>
#include <QMutex>

#include <map>
#include <set>

class TransformFactory : public QObject
{
    Q_OBJECT

public:
    TransformFactory();
    virtual ~TransformFactory();

    static TransformFactory *getInstance();

    /**
     * TransformFactory has a background thread that can populate
     * uninstalled transforms from network RDF resources.  It is not
     * started by default, but it's a good idea to start it when the
     * program starts up, if the uninstalled transforms may be of use
     * later; otherwise there will be a bottleneck the first time
     * they're requested.
     *
     * If this thread is not already running, start it now.
     */
    void startPopulationThread();

    TransformList getAllTransformDescriptions();
    TransformDescription getTransformDescription(TransformId id);
    bool haveInstalledTransforms();

    TransformList getUninstalledTransformDescriptions();
    TransformDescription getUninstalledTransformDescription(TransformId id);
    bool haveUninstalledTransforms(bool waitForCheckToComplete = false);
    
    typedef enum {
        TransformUnknown,
        TransformInstalled,
        TransformNotInstalled
    } TransformInstallStatus;

    TransformInstallStatus getTransformInstallStatus(TransformId id);

    std::vector<TransformDescription::Type> getAllTransformTypes();
    std::vector<QString> getTransformCategories(TransformDescription::Type);
    std::vector<QString> getTransformMakers(TransformDescription::Type);
    QString getTransformTypeName(TransformDescription::Type) const;

    typedef std::map<TransformId, TextMatcher::Match> SearchResults;
    SearchResults search(QString keyword);
    SearchResults search(QStringList keywords);
    
    /**
     * Return true if the given transform is known.
     */
    bool haveTransform(TransformId identifier);

    /**
     * A single transform ID can lead to many possible Transforms,
     * with different parameters and execution context settings.
     * Return the default one for the given transform.
     */
    Transform getDefaultTransformFor(TransformId identifier, size_t rate = 0);

    /**
     * Full name of a transform, suitable for putting on a menu.
     */
    QString getTransformName(TransformId identifier);

    /**
     * Brief but friendly name of a transform, suitable for use
     * as the name of the output layer.
     */
    QString getTransformFriendlyName(TransformId identifier);

    QString getTransformUnits(TransformId identifier);

    QString getTransformInfoUrl(TransformId identifier);

    Vamp::Plugin::InputDomain getTransformInputDomain(TransformId identifier);

    /**
     * Return true if the transform has any configurable parameters,
     * i.e. if getConfigurationForTransform can ever return a non-trivial
     * (not equivalent to empty) configuration string.
     */
    bool isTransformConfigurable(TransformId identifier);

    /**
     * If the transform has a prescribed number or range of channel
     * inputs, return true and set minChannels and maxChannels to the
     * minimum and maximum number of channel inputs the transform can
     * accept.  Return false if it doesn't care.
     */
    bool getTransformChannelRange(TransformId identifier,
                                  int &minChannels, int &maxChannels);

    /**
     * Load an appropriate plugin for the given transform and set the
     * parameters, program and configuration strings on that plugin
     * from the Transform object.
     *
     * Note that this requires that the transform has a meaningful
     * sample rate set, as that is used as the rate for the plugin.  A
     * Transform can legitimately have rate set at zero (= "use the
     * rate of the input source"), so the caller will need to test for
     * this case.
     *
     * Returns the plugin thus loaded.  This will be a
     * Vamp::PluginBase, but not necessarily a Vamp::Plugin (only if
     * the transform was a feature-extraction type -- call
     * downcastVampPlugin if you only want Vamp::Plugins).  Returns
     * NULL if no suitable plugin was available.
     *
     * The returned plugin is owned by the caller, and should be
     * deleted (using "delete") when no longer needed.
     */
    Vamp::PluginBase *instantiatePluginFor(const Transform &transform);

    /**
     * Convert a Vamp::PluginBase to a Vamp::Plugin, if it is one.
     * Return NULL otherwise.  This ill-fitting convenience function
     * is really just a dynamic_cast wrapper.
     */
    Vamp::Plugin *downcastVampPlugin(Vamp::PluginBase *);

    /**
     * Set the plugin parameters, program and configuration strings on
     * the given Transform object from the given plugin instance.
     * Note that no check is made whether the plugin is actually the
     * "correct" one for the transform.
     */
    void setParametersFromPlugin(Transform &transform, Vamp::PluginBase *plugin);

    /**
     * Set the parameters, program and configuration strings on the
     * given plugin from the given Transform object.
     */
    void setPluginParameters(const Transform &transform, Vamp::PluginBase *plugin);
    
    /**
     * If the given Transform object has no processing step and block
     * sizes set, set them to appropriate defaults for the given
     * plugin.
     */
    void makeContextConsistentWithPlugin(Transform &transform, Vamp::PluginBase *plugin); 

    /**
     * Retrieve a <plugin ... /> XML fragment that describes the
     * plugin parameters, program and configuration data for the given
     * transform.
     *
     * This function is provided for backward compatibility only.  Use
     * Transform::toXml where compatibility with PluginXml
     * descriptions of transforms is not required.
     */
    QString getPluginConfigurationXml(const Transform &transform);

    /**
     * Set the plugin parameters, program and configuration strings on
     * the given Transform object from the given <plugin ... /> XML
     * fragment.
     *
     * This function is provided for backward compatibility only.  Use
     * Transform(QString) where compatibility with PluginXml
     * descriptions of transforms is not required.
     */
    void setParametersFromPluginConfigurationXml(Transform &transform,
                                                 QString xml);

protected:
    typedef std::map<TransformId, TransformDescription> TransformDescriptionMap;

    TransformDescriptionMap m_transforms;
    bool m_transformsPopulated;

    TransformDescriptionMap m_uninstalledTransforms;
    bool m_uninstalledTransformsPopulated;

    void populateTransforms();
    void populateUninstalledTransforms();
    void populateFeatureExtractionPlugins(TransformDescriptionMap &);
    void populateRealTimePlugins(TransformDescriptionMap &);

    Vamp::PluginBase *instantiateDefaultPluginFor(TransformId id, size_t rate);

    QMutex m_transformsMutex;
    QMutex m_uninstalledTransformsMutex;

    class UninstalledTransformsPopulateThread : public QThread
    {
    public:
        UninstalledTransformsPopulateThread(TransformFactory *factory) :
            m_factory(factory) {
        }
        virtual void run();
        TransformFactory *m_factory;
    };

    UninstalledTransformsPopulateThread *m_thread;
    bool m_populatingSlowly;

    static TransformFactory *m_instance;
};


#endif