annotate plugin/FeatureExtractionPluginFactory.cpp @ 117:c30728d5625c sv1-v0.9rc1

* Make vertical scale alignment modes work in note layer as well as time-value layer, and several significant fixes to it * Make it possible to draw notes properly on the note layer * Show units (and frequencies etc in note layer's case) in the time-value and note layer description boxes * Minor fix to item edit dialog layout * Some minor menu rearrangement * Comment out a lot of debug output * Add SV website and reference URLs to Help menu, and add code to (attempt to) open them in the user's preferred browser
author Chris Cannam
date Fri, 12 May 2006 14:40:43 +0000
parents b2067aff8cd6
children 4b2ea82fd0ed
rev   line source
Chris@49 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@52 4 Sonic Visualiser
Chris@52 5 An audio file viewer and annotation editor.
Chris@52 6 Centre for Digital Music, Queen Mary, University of London.
Chris@52 7 This file copyright 2006 Chris Cannam.
Chris@0 8
Chris@52 9 This program is free software; you can redistribute it and/or
Chris@52 10 modify it under the terms of the GNU General Public License as
Chris@52 11 published by the Free Software Foundation; either version 2 of the
Chris@52 12 License, or (at your option) any later version. See the file
Chris@52 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@0 16 #include "FeatureExtractionPluginFactory.h"
Chris@0 17 #include "PluginIdentifier.h"
Chris@0 18
Chris@66 19 #include "vamp/vamp.h"
Chris@66 20 #include "vamp-sdk/PluginHostAdapter.h"
Chris@66 21
Chris@66 22 #include "base/System.h"
Chris@66 23
Chris@66 24 #include <QDir>
Chris@66 25 #include <QFile>
Chris@66 26 #include <QFileInfo>
Chris@66 27
Chris@0 28 #include <iostream>
Chris@0 29
Chris@0 30 static FeatureExtractionPluginFactory *_nativeInstance = 0;
Chris@0 31
Chris@0 32 FeatureExtractionPluginFactory *
Chris@0 33 FeatureExtractionPluginFactory::instance(QString pluginType)
Chris@0 34 {
Chris@71 35 if (pluginType == "vamp") {
Chris@0 36 if (!_nativeInstance) {
Chris@0 37 std::cerr << "FeatureExtractionPluginFactory::instance(" << pluginType.toStdString()
Chris@0 38 << "): creating new FeatureExtractionPluginFactory" << std::endl;
Chris@0 39 _nativeInstance = new FeatureExtractionPluginFactory();
Chris@0 40 }
Chris@0 41 return _nativeInstance;
Chris@0 42 }
Chris@0 43
Chris@0 44 else return 0;
Chris@0 45 }
Chris@0 46
Chris@0 47 FeatureExtractionPluginFactory *
Chris@0 48 FeatureExtractionPluginFactory::instanceFor(QString identifier)
Chris@0 49 {
Chris@0 50 QString type, soName, label;
Chris@0 51 PluginIdentifier::parseIdentifier(identifier, type, soName, label);
Chris@0 52 return instance(type);
Chris@0 53 }
Chris@0 54
Chris@0 55 std::vector<QString>
Chris@66 56 FeatureExtractionPluginFactory::getPluginPath()
Chris@66 57 {
Chris@117 58 if (!m_pluginPath.empty()) return m_pluginPath;
Chris@117 59
Chris@66 60 std::vector<QString> path;
Chris@66 61 std::string envPath;
Chris@66 62
Chris@78 63 char *cpath = getenv("VAMP_PATH");
Chris@66 64 if (cpath) envPath = cpath;
Chris@66 65
Chris@66 66 if (envPath == "") {
Chris@78 67 envPath = DEFAULT_VAMP_PATH;
Chris@66 68 char *chome = getenv("HOME");
Chris@66 69 if (chome) {
Chris@78 70 std::string home(chome);
Chris@78 71 int f;
Chris@78 72 while ((f = envPath.find("$HOME")) >= 0 && f < envPath.length()) {
Chris@78 73 envPath.replace(f, 5, home);
Chris@78 74 }
Chris@66 75 }
Chris@83 76 #ifdef Q_WS_WIN32
Chris@83 77 char *cpfiles = getenv("ProgramFiles");
Chris@83 78 if (!cpfiles) cpfiles = "C:\\Program Files";
Chris@83 79 std::string pfiles(cpfiles);
Chris@83 80 int f;
Chris@83 81 while ((f = envPath.find("%ProgramFiles%")) >= 0 && f < envPath.length()) {
Chris@83 82 envPath.replace(f, 14, pfiles);
Chris@83 83 }
Chris@83 84 #endif
Chris@66 85 }
Chris@66 86
Chris@78 87 std::cerr << "VAMP path is: \"" << envPath << "\"" << std::endl;
Chris@78 88
Chris@66 89 std::string::size_type index = 0, newindex = 0;
Chris@66 90
Chris@78 91 while ((newindex = envPath.find(PATH_SEPARATOR, index)) < envPath.size()) {
Chris@66 92 path.push_back(envPath.substr(index, newindex - index).c_str());
Chris@66 93 index = newindex + 1;
Chris@66 94 }
Chris@66 95
Chris@66 96 path.push_back(envPath.substr(index).c_str());
Chris@66 97
Chris@117 98 m_pluginPath = path;
Chris@66 99 return path;
Chris@66 100 }
Chris@66 101
Chris@66 102 std::vector<QString>
Chris@0 103 FeatureExtractionPluginFactory::getAllPluginIdentifiers()
Chris@0 104 {
Chris@0 105 FeatureExtractionPluginFactory *factory;
Chris@0 106 std::vector<QString> rv;
Chris@0 107
Chris@66 108 factory = instance("vamp");
Chris@0 109 if (factory) {
Chris@0 110 std::vector<QString> tmp = factory->getPluginIdentifiers();
Chris@0 111 for (size_t i = 0; i < tmp.size(); ++i) {
Chris@0 112 rv.push_back(tmp[i]);
Chris@0 113 }
Chris@0 114 }
Chris@0 115
Chris@0 116 // Plugins can change the locale, revert it to default.
Chris@0 117 setlocale(LC_ALL, "C");
Chris@0 118 return rv;
Chris@0 119 }
Chris@0 120
Chris@0 121 std::vector<QString>
Chris@0 122 FeatureExtractionPluginFactory::getPluginIdentifiers()
Chris@0 123 {
Chris@0 124 std::vector<QString> rv;
Chris@66 125 std::vector<QString> path = getPluginPath();
Chris@66 126
Chris@66 127 for (std::vector<QString>::iterator i = path.begin(); i != path.end(); ++i) {
Chris@66 128
Chris@117 129 // std::cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: scanning directory " << i->toStdString() << std::endl;
Chris@66 130
Chris@66 131 QDir pluginDir(*i, PLUGIN_GLOB,
Chris@66 132 QDir::Name | QDir::IgnoreCase,
Chris@66 133 QDir::Files | QDir::Readable);
Chris@66 134
Chris@66 135 for (unsigned int j = 0; j < pluginDir.count(); ++j) {
Chris@66 136
Chris@66 137 QString soname = pluginDir.filePath(pluginDir[j]);
Chris@66 138
Chris@66 139 void *libraryHandle = DLOPEN(soname, RTLD_LAZY);
Chris@66 140
Chris@66 141 if (!libraryHandle) {
Chris@71 142 std::cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to load library " << soname.toStdString() << ": " << DLERROR() << std::endl;
Chris@66 143 continue;
Chris@66 144 }
Chris@66 145
Chris@66 146 VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction)
Chris@66 147 DLSYM(libraryHandle, "vampGetPluginDescriptor");
Chris@66 148
Chris@66 149 if (!fn) {
Chris@66 150 std::cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: No descriptor function in " << soname.toStdString() << std::endl;
Chris@66 151 if (DLCLOSE(libraryHandle) != 0) {
Chris@66 152 std::cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to unload library " << soname.toStdString() << std::endl;
Chris@66 153 }
Chris@66 154 continue;
Chris@66 155 }
Chris@66 156
Chris@66 157 const VampPluginDescriptor *descriptor = 0;
Chris@66 158 int index = 0;
Chris@66 159
Chris@66 160 while ((descriptor = fn(index))) {
Chris@82 161 QString id = PluginIdentifier::createIdentifier
Chris@82 162 ("vamp", soname, descriptor->name);
Chris@66 163 rv.push_back(id);
Chris@66 164 std::cerr << "Found id " << id.toStdString() << std::endl;
Chris@66 165 ++index;
Chris@66 166 }
Chris@66 167
Chris@66 168 if (DLCLOSE(libraryHandle) != 0) {
Chris@66 169 std::cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to unload library " << soname.toStdString() << std::endl;
Chris@66 170 }
Chris@66 171 }
Chris@66 172 }
Chris@66 173
Chris@0 174 return rv;
Chris@0 175 }
Chris@0 176
Chris@66 177 QString
Chris@66 178 FeatureExtractionPluginFactory::findPluginFile(QString soname, QString inDir)
Chris@66 179 {
Chris@66 180 QString file = "";
Chris@66 181
Chris@66 182 if (inDir != "") {
Chris@66 183
Chris@66 184 QDir dir(inDir, PLUGIN_GLOB,
Chris@66 185 QDir::Name | QDir::IgnoreCase,
Chris@66 186 QDir::Files | QDir::Readable);
Chris@66 187 if (!dir.exists()) return "";
Chris@66 188
Chris@66 189 file = dir.filePath(QFileInfo(soname).fileName());
Chris@66 190 if (QFileInfo(file).exists()) {
Chris@66 191 return file;
Chris@66 192 }
Chris@66 193
Chris@66 194 for (unsigned int j = 0; j < dir.count(); ++j) {
Chris@66 195 file = dir.filePath(dir[j]);
Chris@66 196 if (QFileInfo(file).baseName() == QFileInfo(soname).baseName()) {
Chris@66 197 return file;
Chris@66 198 }
Chris@66 199 }
Chris@66 200
Chris@66 201 return "";
Chris@66 202
Chris@66 203 } else {
Chris@66 204
Chris@66 205 QFileInfo fi(soname);
Chris@66 206 if (fi.exists()) return soname;
Chris@66 207
Chris@66 208 if (fi.isAbsolute() && fi.absolutePath() != "") {
Chris@66 209 file = findPluginFile(soname, fi.absolutePath());
Chris@66 210 if (file != "") return file;
Chris@66 211 }
Chris@66 212
Chris@66 213 std::vector<QString> path = getPluginPath();
Chris@66 214 for (std::vector<QString>::iterator i = path.begin();
Chris@66 215 i != path.end(); ++i) {
Chris@66 216 if (*i != "") {
Chris@66 217 file = findPluginFile(soname, *i);
Chris@66 218 if (file != "") return file;
Chris@66 219 }
Chris@66 220 }
Chris@66 221
Chris@66 222 return "";
Chris@66 223 }
Chris@66 224 }
Chris@66 225
Chris@66 226 Vamp::Plugin *
Chris@0 227 FeatureExtractionPluginFactory::instantiatePlugin(QString identifier,
Chris@0 228 float inputSampleRate)
Chris@0 229 {
Chris@66 230 Vamp::Plugin *rv = 0;
Chris@66 231
Chris@66 232 const VampPluginDescriptor *descriptor = 0;
Chris@66 233 int index = 0;
Chris@66 234
Chris@66 235 QString type, soname, label;
Chris@66 236 PluginIdentifier::parseIdentifier(identifier, type, soname, label);
Chris@71 237 if (type != "vamp") {
Chris@0 238 std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Wrong factory for plugin type " << type.toStdString() << std::endl;
Chris@0 239 return 0;
Chris@0 240 }
Chris@0 241
Chris@66 242 QString found = findPluginFile(soname);
Chris@66 243
Chris@66 244 if (found == "") {
Chris@66 245 std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to find library file " << soname.toStdString() << std::endl;
Chris@117 246 return 0;
Chris@66 247 } else if (found != soname) {
Chris@117 248 // std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: WARNING: Given library name was " << soname.toStdString() << ", found at " << found.toStdString() << std::endl;
Chris@117 249 // std::cerr << soname.toStdString() << " -> " << found.toStdString() << std::endl;
Chris@0 250 }
Chris@0 251
Chris@66 252 soname = found;
Chris@66 253
Chris@66 254 void *libraryHandle = DLOPEN(soname, RTLD_LAZY);
Chris@66 255
Chris@66 256 if (!libraryHandle) {
Chris@71 257 std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to load library " << soname.toStdString() << ": " << DLERROR() << std::endl;
Chris@66 258 return 0;
Chris@19 259 }
Chris@19 260
Chris@66 261 VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction)
Chris@66 262 DLSYM(libraryHandle, "vampGetPluginDescriptor");
Chris@66 263
Chris@66 264 if (!fn) {
Chris@66 265 std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: No descriptor function in " << soname.toStdString() << std::endl;
Chris@66 266 goto done;
Chris@0 267 }
Chris@0 268
Chris@66 269 while ((descriptor = fn(index))) {
Chris@66 270 if (label == descriptor->name) break;
Chris@66 271 ++index;
Chris@47 272 }
Chris@47 273
Chris@66 274 if (!descriptor) {
Chris@66 275 std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to find plugin \"" << label.toStdString() << "\" in library " << soname.toStdString() << std::endl;
Chris@66 276 goto done;
Martin@37 277 }
Martin@37 278
Chris@66 279 rv = new Vamp::PluginHostAdapter(descriptor, inputSampleRate);
Chris@66 280
Chris@117 281 // std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Constructed Vamp plugin, rv is " << rv << std::endl;
Chris@79 282
Chris@66 283 //!!! need to dlclose() when plugins from a given library are unloaded
Chris@66 284
Chris@66 285 done:
Chris@66 286 if (!rv) {
Chris@66 287 if (DLCLOSE(libraryHandle) != 0) {
Chris@66 288 std::cerr << "WARNING: FeatureExtractionPluginFactory::instantiatePlugin: Failed to unload library " << soname.toStdString() << std::endl;
Chris@66 289 }
Chris@66 290 }
Chris@73 291
Chris@73 292 // std::cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Instantiated plugin " << label.toStdString() << " from library " << soname.toStdString() << ": descriptor " << descriptor << ", rv "<< rv << ", label " << rv->getName() << ", outputs " << rv->getOutputDescriptors().size() << std::endl;
Chris@73 293
Chris@66 294 return rv;
Chris@0 295 }
Chris@0 296