annotate vamp-hostsdk/PluginLoader.h @ 525:8c18bdaad04f c++11-mutex

Avoid simple static allocation of mutex, as it could lead to mutex being destroyed before last adapter that needs to use it (since adapters are usually also static)
author Chris Cannam
date Mon, 09 Sep 2019 10:24:13 +0100
parents 328cb056da44
children
rev   line source
cannam@233 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@233 2
cannam@233 3 /*
cannam@233 4 Vamp
cannam@233 5
cannam@233 6 An API for audio analysis and feature extraction plugins.
cannam@233 7
cannam@233 8 Centre for Digital Music, Queen Mary, University of London.
cannam@290 9 Copyright 2006-2009 Chris Cannam and QMUL.
cannam@233 10
cannam@233 11 Permission is hereby granted, free of charge, to any person
cannam@233 12 obtaining a copy of this software and associated documentation
cannam@233 13 files (the "Software"), to deal in the Software without
cannam@233 14 restriction, including without limitation the rights to use, copy,
cannam@233 15 modify, merge, publish, distribute, sublicense, and/or sell copies
cannam@233 16 of the Software, and to permit persons to whom the Software is
cannam@233 17 furnished to do so, subject to the following conditions:
cannam@233 18
cannam@233 19 The above copyright notice and this permission notice shall be
cannam@233 20 included in all copies or substantial portions of the Software.
cannam@233 21
cannam@233 22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
cannam@233 23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
cannam@233 24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
cannam@233 25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
cannam@233 26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
cannam@233 27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
cannam@233 28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cannam@233 29
cannam@233 30 Except as contained in this notice, the names of the Centre for
cannam@233 31 Digital Music; Queen Mary, University of London; and Chris Cannam
cannam@233 32 shall not be used in advertising or otherwise to promote the sale,
cannam@233 33 use or other dealings in this Software without prior written
cannam@233 34 authorization.
cannam@233 35 */
cannam@233 36
cannam@233 37 #ifndef _VAMP_PLUGIN_LOADER_H_
cannam@233 38 #define _VAMP_PLUGIN_LOADER_H_
cannam@233 39
cannam@233 40 #include <vector>
cannam@233 41 #include <string>
cannam@233 42 #include <map>
cannam@233 43
cannam@243 44 #include "hostguard.h"
cannam@233 45 #include "PluginWrapper.h"
cannam@233 46
cannam@263 47 _VAMP_SDK_HOSTSPACE_BEGIN(PluginLoader.h)
cannam@263 48
cannam@233 49 namespace Vamp {
cannam@233 50
cannam@233 51 class Plugin;
cannam@233 52
cannam@233 53 namespace HostExt {
cannam@233 54
cannam@233 55 /**
cannam@233 56 * \class PluginLoader PluginLoader.h <vamp-hostsdk/PluginLoader.h>
cannam@233 57 *
cannam@233 58 * Vamp::HostExt::PluginLoader is a convenience class for discovering
cannam@233 59 * and loading Vamp plugins using the typical plugin-path, library
cannam@233 60 * naming, and categorisation conventions described in the Vamp SDK
cannam@233 61 * documentation. This class is intended to greatly simplify the task
cannam@233 62 * of becoming a Vamp plugin host for any C++ application.
cannam@233 63 *
cannam@233 64 * Hosts are not required by the Vamp specification to use the same
cannam@233 65 * plugin search path and naming conventions as implemented by this
cannam@233 66 * class, and are certainly not required to use this actual class.
cannam@233 67 * But we do strongly recommend it.
cannam@233 68 *
Chris@388 69 * This class is not thread-safe; use it from a single application
Chris@388 70 * thread, or guard access to it with a mutex.
Chris@388 71 *
cannam@233 72 * \note This class was introduced in version 1.1 of the Vamp plugin SDK.
cannam@233 73 */
cannam@233 74
cannam@233 75 class PluginLoader
cannam@233 76 {
cannam@233 77 public:
cannam@233 78 /**
cannam@233 79 * Obtain a pointer to the singleton instance of PluginLoader.
cannam@233 80 * Use this to obtain your loader object.
cannam@233 81 */
cannam@233 82 static PluginLoader *getInstance();
cannam@233 83
cannam@233 84 /**
cannam@233 85 * PluginKey is a string type that is used to identify a plugin
cannam@233 86 * uniquely within the scope of "the current system". It consists
cannam@233 87 * of the lower-cased base name of the plugin library, a colon
cannam@233 88 * separator, and the identifier string for the plugin. It is
cannam@233 89 * only meaningful in the context of a given plugin path (the one
cannam@233 90 * returned by PluginHostAdapter::getPluginPath()).
cannam@233 91 *
cannam@233 92 * Use composePluginKey() to construct a plugin key from a known
cannam@233 93 * plugin library name and identifier.
cannam@233 94 *
cannam@233 95 * Note: the fact that the library component of the key is
cannam@233 96 * lower-cased implies that library names are matched
cannam@233 97 * case-insensitively by the PluginLoader class, regardless of the
cannam@233 98 * case sensitivity of the underlying filesystem. (Plugin
cannam@233 99 * identifiers _are_ case sensitive, however.) Also, it is not
cannam@233 100 * possible to portably extract a working library name from a
cannam@233 101 * plugin key, as the result may fail on case-sensitive
cannam@233 102 * filesystems. Use getLibraryPathForPlugin() instead.
cannam@233 103 */
cannam@233 104 typedef std::string PluginKey;
cannam@233 105
cannam@233 106 /**
cannam@233 107 * PluginKeyList is a sequence of plugin keys, such as returned by
cannam@233 108 * listPlugins().
cannam@233 109 */
cannam@233 110 typedef std::vector<PluginKey> PluginKeyList;
cannam@233 111
cannam@233 112 /**
cannam@233 113 * PluginCategoryHierarchy is a sequence of general->specific
cannam@233 114 * category names, as may be associated with a single plugin.
cannam@233 115 * This sequence describes the location of a plugin within a
cannam@233 116 * category forest, containing the human-readable names of the
cannam@233 117 * plugin's category tree root, followed by each of the nodes down
cannam@233 118 * to the leaf containing the plugin.
cannam@233 119 *
cannam@233 120 * \see getPluginCategory()
cannam@233 121 */
cannam@233 122 typedef std::vector<std::string> PluginCategoryHierarchy;
cannam@233 123
cannam@233 124 /**
cannam@233 125 * Search for all available Vamp plugins, and return a list of
cannam@233 126 * them in the order in which they were found.
cannam@233 127 */
cannam@233 128 PluginKeyList listPlugins();
cannam@233 129
cannam@233 130 /**
Chris@473 131 * Search for available Vamp plugins in libraries with the given
Chris@473 132 * library names, and return a list of them in the order in which
Chris@473 133 * they were found. Do not attempt to load any plugin libraries
Chris@473 134 * other than those named.
Chris@473 135 *
Chris@473 136 * The library names should be supplied without path or
Chris@473 137 * suffix. For example, use "vamp-example-plugins" to find plugins
Chris@473 138 * in /install/path/of/vamp-example-plugins.dll (or .so etc). This
Chris@473 139 * is the same concept of "library name" as appears in the plugin
Chris@473 140 * key: \see composePluginKey().
Chris@473 141 */
Chris@473 142 PluginKeyList listPluginsIn(std::vector<std::string> libraryNames);
Chris@473 143
Chris@473 144 /**
Chris@473 145 * Search for available Vamp plugins in libraries other than those
Chris@473 146 * with the given library names, and return a list of them in the
Chris@473 147 * order in which they were found. Do not attempt to load any of
Chris@473 148 * the libraries named.
Chris@473 149 *
Chris@473 150 * The library names should be supplied without path or
Chris@473 151 * suffix. For example, use "vamp-example-plugins" to find plugins
Chris@473 152 * not appearing in /install/path/of/vamp-example-plugins.dll (or
Chris@473 153 * .so etc). This is the same concept of "library name" as appears
Chris@473 154 * in the plugin key: \see composePluginKey().
Chris@473 155 */
Chris@473 156 PluginKeyList listPluginsNotIn(std::vector<std::string> libraryNames);
Chris@473 157
Chris@473 158 /**
cannam@233 159 * AdapterFlags contains a set of values that may be OR'd together
cannam@233 160 * to indicate in which circumstances PluginLoader should use a
cannam@233 161 * plugin adapter to make a plugin easier to use for a host that
cannam@233 162 * does not want to cater for complex features.
cannam@233 163 *
cannam@233 164 * The available flags are:
cannam@233 165 *
cannam@233 166 * ADAPT_INPUT_DOMAIN - If the plugin expects frequency domain
cannam@233 167 * input, wrap it in a PluginInputDomainAdapter that automatically
cannam@233 168 * converts the plugin to one that expects time-domain input.
cannam@233 169 * This enables a host to accommodate time- and frequency-domain
cannam@233 170 * plugins without needing to do any conversion itself.
cannam@233 171 *
cannam@233 172 * ADAPT_CHANNEL_COUNT - Wrap the plugin in a PluginChannelAdapter
cannam@233 173 * to handle any mismatch between the number of channels of audio
cannam@233 174 * the plugin can handle and the number available in the host.
cannam@233 175 * This enables a host to use plugins that may require the input
cannam@233 176 * to be mixed down to mono, etc., without having to worry about
cannam@233 177 * doing that itself.
cannam@233 178 *
cannam@233 179 * ADAPT_BUFFER_SIZE - Wrap the plugin in a PluginBufferingAdapter
cannam@233 180 * permitting the host to provide audio input using any block
cannam@233 181 * size, with no overlap, regardless of the plugin's preferred
cannam@233 182 * block size (suitable for hosts that read from non-seekable
cannam@233 183 * streaming media, for example). This adapter introduces some
cannam@233 184 * run-time overhead and also changes the semantics of the plugin
cannam@233 185 * slightly (see the PluginBufferingAdapter header documentation
cannam@233 186 * for details).
cannam@233 187 *
cannam@233 188 * ADAPT_ALL_SAFE - Perform all available adaptations that are
cannam@233 189 * meaningful for the plugin and "safe". Currently this means to
cannam@233 190 * ADAPT_INPUT_DOMAIN if the plugin wants FrequencyDomain input;
cannam@233 191 * ADAPT_CHANNEL_COUNT always; and ADAPT_BUFFER_SIZE never.
cannam@233 192 *
cannam@233 193 * ADAPT_ALL - Perform all available adaptations that are
cannam@233 194 * meaningful for the plugin.
cannam@233 195 *
cannam@233 196 * See PluginInputDomainAdapter, PluginChannelAdapter and
cannam@233 197 * PluginBufferingAdapter for more details of the classes that the
cannam@233 198 * loader may use if these flags are set.
cannam@233 199 */
cannam@233 200 enum AdapterFlags {
cannam@233 201
cannam@233 202 ADAPT_INPUT_DOMAIN = 0x01,
cannam@233 203 ADAPT_CHANNEL_COUNT = 0x02,
cannam@233 204 ADAPT_BUFFER_SIZE = 0x04,
cannam@233 205
cannam@233 206 ADAPT_ALL_SAFE = 0x03,
cannam@233 207
cannam@233 208 ADAPT_ALL = 0xff
cannam@233 209 };
cannam@233 210
cannam@233 211 /**
cannam@233 212 * Load a Vamp plugin, given its identifying key. If the plugin
cannam@233 213 * could not be loaded, returns 0.
cannam@233 214 *
cannam@233 215 * The returned plugin should be deleted (using the standard C++
cannam@233 216 * delete keyword) after use.
cannam@233 217 *
cannam@233 218 * \param adapterFlags a bitwise OR of the values in the AdapterFlags
cannam@233 219 * enumeration, indicating under which circumstances an adapter should be
cannam@233 220 * used to wrap the original plugin. If adapterFlags is 0, no
cannam@233 221 * optional adapters will be used. Otherwise, the returned plugin
cannam@233 222 * may be of an adapter class type which will behave identically
cannam@233 223 * to the original plugin, apart from any particular features
cannam@233 224 * implemented by the adapter itself.
cannam@233 225 *
cannam@233 226 * \see AdapterFlags, PluginInputDomainAdapter, PluginChannelAdapter
cannam@233 227 */
cannam@233 228 Plugin *loadPlugin(PluginKey key,
cannam@233 229 float inputSampleRate,
cannam@233 230 int adapterFlags = 0);
Chris@423 231
Chris@423 232 /**
cannam@233 233 * Given a Vamp plugin library name and plugin identifier, return
cannam@233 234 * the corresponding plugin key in a form suitable for passing in to
cannam@233 235 * loadPlugin().
Chris@511 236 *
Chris@511 237 * (Note that the reverse of this is not well-defined and is not
Chris@511 238 * offered in this API - consider using getLibraryPathForPlugin
Chris@511 239 * instead. See documentation for the PluginKey type for details.)
Chris@511 240 *
Chris@511 241 * \see PluginKey, getLibraryPathForPlugin, loadPlugin
cannam@233 242 */
cannam@233 243 PluginKey composePluginKey(std::string libraryName,
cannam@233 244 std::string identifier);
cannam@233 245
cannam@233 246 /**
cannam@233 247 * Return the category hierarchy for a Vamp plugin, given its
cannam@233 248 * identifying key.
cannam@233 249 *
cannam@233 250 * If the plugin has no category information, return an empty
cannam@233 251 * hierarchy.
cannam@233 252 *
cannam@233 253 * \see PluginCategoryHierarchy
cannam@233 254 */
cannam@233 255 PluginCategoryHierarchy getPluginCategory(PluginKey plugin);
cannam@233 256
cannam@233 257 /**
cannam@233 258 * Return the file path of the dynamic library from which the
cannam@233 259 * given plugin will be loaded (if available).
cannam@233 260 */
cannam@233 261 std::string getLibraryPathForPlugin(PluginKey plugin);
cannam@233 262
cannam@233 263 protected:
cannam@233 264 PluginLoader();
cannam@233 265 virtual ~PluginLoader();
cannam@233 266
cannam@233 267 class Impl;
cannam@233 268 Impl *m_impl;
cannam@233 269
cannam@233 270 static PluginLoader *m_instance;
cannam@233 271 };
cannam@233 272
cannam@233 273 }
cannam@233 274
cannam@233 275 }
cannam@233 276
cannam@263 277 _VAMP_SDK_HOSTSPACE_END(PluginLoader.h)
cannam@263 278
cannam@233 279 #endif
cannam@233 280