Mercurial > hg > vamp-plugin-sdk
changeset 474:8e846c1aed96
Merge from branch enumerate-options
author | Chris Cannam |
---|---|
date | Fri, 04 Nov 2016 10:44:27 +0000 |
parents | 79a219ba6178 (current diff) 0545cd3f1738 (diff) |
children | e2716b9352ca |
files | |
diffstat | 4 files changed, 204 insertions(+), 50 deletions(-) [+] |
line wrap: on
line diff
--- a/src/vamp-hostsdk/Files.cpp Fri Oct 28 14:30:26 2016 +0100 +++ b/src/vamp-hostsdk/Files.cpp Fri Nov 04 10:44:27 2016 +0000 @@ -66,21 +66,25 @@ vector<string> Files::listLibraryFiles() { - return listLibraryFilesMatching(""); + return listLibraryFilesMatching({}); } vector<string> -Files::listLibraryFilesMatching(string libraryName) +Files::listLibraryFilesMatching(Filter filter) { vector<string> path = Vamp::PluginHostAdapter::getPluginPath(); vector<string> libraryFiles; // we match case-insensitively, but only with ascii range - // characters (this string is expected to be utf-8) - for (size_t i = 0; i < libraryName.length(); ++i) { - if (!(libraryName[i] & 0x80)) { - libraryName[i] = char(tolower(libraryName[i])); + // characters (input strings are expected to be utf-8) + vector<string> libraryNames; + for (auto n: filter.libraryNames) { + for (size_t i = 0; i < n.length(); ++i) { + if (!(n[i] & 0x80)) { + n[i] = char(tolower(n[i])); + } } + libraryNames.push_back(n); } for (size_t i = 0; i < path.size(); ++i) { @@ -89,27 +93,53 @@ for (vector<string>::iterator fi = files.begin(); fi != files.end(); ++fi) { - - if (libraryName != "") { - // we match case-insensitively, but only with ascii - // range characters (this string is expected to be - // utf-8) - string temp = *fi; - for (size_t i = 0; i < temp.length(); ++i) { - if (!(temp[i] & 0x80)) { - temp[i] = char(tolower(temp[i])); - } - } - // libraryName should be lacking an extension, as it - // is supposed to have come from the plugin key - string::size_type pi = temp.find('.'); - if (pi == string::npos) { - if (libraryName != temp) continue; - } else { - if (libraryName != temp.substr(0, pi)) continue; + + // we match case-insensitively, but only with ascii range + // characters (this string is expected to be utf-8) + string cleaned = *fi; + for (size_t i = 0; i < cleaned.length(); ++i) { + if (!(cleaned[i] & 0x80)) { + cleaned[i] = char(tolower(cleaned[i])); } } + // libraryName should be lacking an extension, as it is + // supposed to have come from the plugin key + string::size_type pi = cleaned.find('.'); + if (pi != string::npos) { + cleaned = cleaned.substr(0, pi); + } + + bool matched = false; + + switch (filter.type) { + + case Filter::All: + matched = true; + break; + + case Filter::Matching: + for (const auto &n: libraryNames) { + if (cleaned == n) { + matched = true; + break; + } + } + break; + + case Filter::NotMatching: + matched = true; + for (const auto &n: libraryNames) { + if (cleaned == n) { + matched = false; + break; + } + } + break; + } + + if (!matched) continue; + string fullPath = path[i]; fullPath = splicePath(fullPath, *fi); libraryFiles.push_back(fullPath);
--- a/src/vamp-hostsdk/Files.h Fri Oct 28 14:30:26 2016 +0100 +++ b/src/vamp-hostsdk/Files.h Fri Nov 04 10:44:27 2016 +0000 @@ -47,7 +47,13 @@ { public: static std::vector<std::string> listLibraryFiles(); - static std::vector<std::string> listLibraryFilesMatching(std::string libname); + + struct Filter { + enum { All, Matching, NotMatching } type; + std::vector<std::string> libraryNames; + Filter() : type(All) { } + }; + static std::vector<std::string> listLibraryFilesMatching(Filter); static void *loadLibrary(std::string filename); static void unloadLibrary(void *);
--- a/src/vamp-hostsdk/PluginLoader.cpp Fri Oct 28 14:30:26 2016 +0100 +++ b/src/vamp-hostsdk/PluginLoader.cpp Fri Nov 04 10:44:27 2016 +0000 @@ -61,6 +61,8 @@ virtual ~Impl(); PluginKeyList listPlugins(); + PluginKeyList listPluginsIn(vector<string>); + PluginKeyList listPluginsNotIn(vector<string>); Plugin *loadPlugin(PluginKey key, float inputSampleRate, @@ -96,7 +98,18 @@ map<PluginKey, string> m_pluginLibraryNameMap; bool m_allPluginsEnumerated; - void enumeratePlugins(PluginKey forPlugin = ""); + + struct Enumeration { + enum { All, SinglePlugin, InLibraries, NotInLibraries } type; + PluginKey key; + vector<string> libraryNames; + Enumeration() : type(All) { } + }; + vector<string> listLibraryFilesFor(Enumeration); + + /// Populate m_pluginLibraryNameMap and return a list of the keys + /// that were added to it + vector<PluginKey> enumeratePlugins(Enumeration); map<PluginKey, PluginCategoryHierarchy> m_taxonomy; void generateTaxonomy(); @@ -144,6 +157,18 @@ return m_impl->listPlugins(); } +PluginLoader::PluginKeyList +PluginLoader::listPluginsIn(vector<string> libs) +{ + return m_impl->listPluginsIn(libs); +} + +PluginLoader::PluginKeyList +PluginLoader::listPluginsNotIn(vector<string> libs) +{ + return m_impl->listPluginsNotIn(libs); +} + Plugin * PluginLoader::loadPlugin(PluginKey key, float inputSampleRate, @@ -188,34 +213,89 @@ PluginLoader::PluginKeyList PluginLoader::Impl::listPlugins() { - if (!m_allPluginsEnumerated) enumeratePlugins(); + if (!m_allPluginsEnumerated) enumeratePlugins({}); vector<PluginKey> plugins; - for (map<PluginKey, string>::iterator mi = m_pluginLibraryNameMap.begin(); - mi != m_pluginLibraryNameMap.end(); ++mi) { - plugins.push_back(mi->first); + for (const auto &mi: m_pluginLibraryNameMap) { + plugins.push_back(mi.first); } return plugins; } -void -PluginLoader::Impl::enumeratePlugins(PluginKey forPlugin) +PluginLoader::PluginKeyList +PluginLoader::Impl::listPluginsIn(vector<string> libs) +{ + Enumeration enumeration; + enumeration.type = Enumeration::InLibraries; + enumeration.libraryNames = libs; + return enumeratePlugins(enumeration); +} + +PluginLoader::PluginKeyList +PluginLoader::Impl::listPluginsNotIn(vector<string> libs) +{ + Enumeration enumeration; + enumeration.type = Enumeration::NotInLibraries; + enumeration.libraryNames = libs; + return enumeratePlugins(enumeration); +} + +vector<string> +PluginLoader::Impl::listLibraryFilesFor(Enumeration enumeration) +{ + Files::Filter filter; + + switch (enumeration.type) { + + case Enumeration::All: + filter.type = Files::Filter::All; + break; + + case Enumeration::SinglePlugin: + { + string libraryName, identifier; + if (!decomposePluginKey(enumeration.key, libraryName, identifier)) { + std::cerr << "WARNING: Vamp::HostExt::PluginLoader: " + << "Invalid plugin key \"" << enumeration.key + << "\" in enumerate" << std::endl; + return {}; + } + filter.type = Files::Filter::Matching; + filter.libraryNames = { libraryName }; + break; + } + + case Enumeration::InLibraries: + filter.type = Files::Filter::Matching; + filter.libraryNames = enumeration.libraryNames; + break; + + case Enumeration::NotInLibraries: + filter.type = Files::Filter::NotMatching; + filter.libraryNames = enumeration.libraryNames; + break; + } + + return Files::listLibraryFilesMatching(filter); +} + +vector<PluginLoader::PluginKey> +PluginLoader::Impl::enumeratePlugins(Enumeration enumeration) { string libraryName, identifier; - vector<string> fullPaths; + if (enumeration.type == Enumeration::SinglePlugin) { + decomposePluginKey(enumeration.key, libraryName, identifier); + } - if (forPlugin != "") { - if (!decomposePluginKey(forPlugin, libraryName, identifier)) { - std::cerr << "WARNING: Vamp::HostExt::PluginLoader: Invalid plugin key \"" - << forPlugin << "\" in enumerate" << std::endl; - return; - } - fullPaths = Files::listLibraryFilesMatching(libraryName); - } else { - fullPaths = Files::listLibraryFiles(); - } + vector<string> fullPaths = listLibraryFilesFor(enumeration); + // For these we should warn if a plugin can be loaded from a library + bool specific = (enumeration.type == Enumeration::SinglePlugin || + enumeration.type == Enumeration::InLibraries); + + vector<PluginKey> added; + for (size_t i = 0; i < fullPaths.size(); ++i) { string fullPath = fullPaths[i]; @@ -227,8 +307,9 @@ (handle, "vampGetPluginDescriptor"); if (!fn) { - if (forPlugin != "") { - cerr << "Vamp::HostExt::PluginLoader: No vampGetPluginDescriptor function found in library \"" + if (specific) { + cerr << "Vamp::HostExt::PluginLoader: " + << "No vampGetPluginDescriptor function found in library \"" << fullPath << "\"" << endl; } Files::unloadLibrary(handle); @@ -242,18 +323,20 @@ while ((descriptor = fn(VAMP_API_VERSION, index))) { ++index; if (identifier != "") { - if (descriptor->identifier != identifier) continue; + if (descriptor->identifier != identifier) { + continue; + } } found = true; PluginKey key = composePluginKey(fullPath, descriptor->identifier); -// std::cerr << "enumerate: " << key << " (path: " << fullPath << ")" << std::endl; if (m_pluginLibraryNameMap.find(key) == m_pluginLibraryNameMap.end()) { m_pluginLibraryNameMap[key] = fullPath; } + added.push_back(key); } - if (!found && forPlugin != "") { + if (!found && specific) { cerr << "Vamp::HostExt::PluginLoader: Plugin \"" << identifier << "\" not found in library \"" << fullPath << "\"" << endl; @@ -262,7 +345,11 @@ Files::unloadLibrary(handle); } - if (forPlugin == "") m_allPluginsEnumerated = true; + if (enumeration.type == Enumeration::All) { + m_allPluginsEnumerated = true; + } + + return added; } PluginLoader::PluginKey @@ -302,7 +389,10 @@ { if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) { if (m_allPluginsEnumerated) return ""; - enumeratePlugins(plugin); + Enumeration enumeration; + enumeration.type = Enumeration::SinglePlugin; + enumeration.key = plugin; + enumeratePlugins(enumeration); } if (m_pluginLibraryNameMap.find(plugin) == m_pluginLibraryNameMap.end()) { return "";
--- a/vamp-hostsdk/PluginLoader.h Fri Oct 28 14:30:26 2016 +0100 +++ b/vamp-hostsdk/PluginLoader.h Fri Nov 04 10:44:27 2016 +0000 @@ -128,6 +128,34 @@ PluginKeyList listPlugins(); /** + * Search for available Vamp plugins in libraries with the given + * library names, and return a list of them in the order in which + * they were found. Do not attempt to load any plugin libraries + * other than those named. + * + * The library names should be supplied without path or + * suffix. For example, use "vamp-example-plugins" to find plugins + * in /install/path/of/vamp-example-plugins.dll (or .so etc). This + * is the same concept of "library name" as appears in the plugin + * key: \see composePluginKey(). + */ + PluginKeyList listPluginsIn(std::vector<std::string> libraryNames); + + /** + * Search for available Vamp plugins in libraries other than those + * with the given library names, and return a list of them in the + * order in which they were found. Do not attempt to load any of + * the libraries named. + * + * The library names should be supplied without path or + * suffix. For example, use "vamp-example-plugins" to find plugins + * not appearing in /install/path/of/vamp-example-plugins.dll (or + * .so etc). This is the same concept of "library name" as appears + * in the plugin key: \see composePluginKey(). + */ + PluginKeyList listPluginsNotIn(std::vector<std::string> libraryNames); + + /** * AdapterFlags contains a set of values that may be OR'd together * to indicate in which circumstances PluginLoader should use a * plugin adapter to make a plugin easier to use for a host that