changeset 1209:385deb828b4a piper

Bodge in piper-cpp client (not yet working)
author Chris Cannam
date Fri, 14 Oct 2016 14:33:43 +0100
parents fef49844b3f8
children 584b2d7d7cd9
files plugin/FeatureExtractionPluginFactory.cpp plugin/FeatureExtractionPluginFactory.h svcore.pro
diffstat 3 files changed, 36 insertions(+), 330 deletions(-) [+]
line wrap: on
line diff
--- a/plugin/FeatureExtractionPluginFactory.cpp	Tue Sep 20 09:16:13 2016 +0100
+++ b/plugin/FeatureExtractionPluginFactory.cpp	Fri Oct 14 14:33:43 2016 +0100
@@ -36,27 +36,6 @@
 
 //#define DEBUG_PLUGIN_SCAN_AND_INSTANTIATE 1
 
-class PluginDeletionNotifyAdapter : public Vamp::HostExt::PluginWrapper {
-public:
-    PluginDeletionNotifyAdapter(Vamp::Plugin *plugin,
-                                FeatureExtractionPluginFactory *factory) :
-        PluginWrapper(plugin), m_factory(factory) { }
-    virtual ~PluginDeletionNotifyAdapter();
-protected:
-    FeatureExtractionPluginFactory *m_factory;
-};
-
-PluginDeletionNotifyAdapter::~PluginDeletionNotifyAdapter()
-{
-    // see notes in vamp-sdk/hostext/PluginLoader.cpp from which this is drawn
-    Vamp::Plugin *p = m_plugin;
-    delete m_plugin;
-    m_plugin = 0;
-    // acceptable use after free here, as pluginDeleted uses p only as
-    // pointer key and does not deref it
-    if (m_factory) m_factory->pluginDeleted(p);
-}
-
 static FeatureExtractionPluginFactory *_nativeInstance = 0;
 
 FeatureExtractionPluginFactory *
@@ -81,14 +60,10 @@
     return instance(type);
 }
 
-vector<QString>
-FeatureExtractionPluginFactory::getPluginPath()
+FeatureExtractionPluginFactory::FeatureExtractionPluginFactory() :
+    m_transport("piper-cpp/bin/piper-vamp-server"),
+    m_client(&m_transport)
 {
-    if (!m_pluginPath.empty()) return m_pluginPath;
-
-    vector<string> p = Vamp::PluginHostAdapter::getPluginPath();
-    for (size_t i = 0; i < p.size(); ++i) m_pluginPath.push_back(p[i].c_str());
-    return m_pluginPath;
 }
 
 vector<QString>
@@ -117,319 +92,51 @@
 {
     Profiler profiler("FeatureExtractionPluginFactory::getPluginIdentifiers");
 
+    QMutexLocker locker(&m_mutex);
+
+    if (m_pluginData.empty()) {
+        populate();
+    }
+
     vector<QString> rv;
 
-    QStringList candidates = PluginScan::getInstance()->getCandidateLibrariesFor
-        (PluginScan::VampPlugin);
-    
-    for (QString soname : candidates) {
-
-        void *libraryHandle = DLOPEN(soname, RTLD_LAZY | RTLD_LOCAL);
-            
-        if (!libraryHandle) {
-            cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to load library " << soname << ": " << DLERROR() << endl;
-            continue;
-        }
-
-        VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction)
-            DLSYM(libraryHandle, "vampGetPluginDescriptor");
-
-        if (!fn) {
-            cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: No descriptor function in " << soname << endl;
-            if (DLCLOSE(libraryHandle) != 0) {
-                cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to unload library " << soname << endl;
-            }
-            continue;
-        }
-
-#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE
-            cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: Vamp descriptor found" << endl;
-#endif
-
-        const VampPluginDescriptor *descriptor = 0;
-        int index = 0;
-
-        map<string, int> known;
-        bool ok = true;
-
-        while ((descriptor = fn(VAMP_API_VERSION, index))) {
-
-            if (known.find(descriptor->identifier) != known.end()) {
-                cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Plugin library "
-                     << soname
-                     << " returns the same plugin identifier \""
-                     << descriptor->identifier << "\" at indices "
-                     << known[descriptor->identifier] << " and "
-                     << index << endl;
-                    cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: Avoiding this library (obsolete API?)" << endl;
-                ok = false;
-                break;
-            } else {
-                known[descriptor->identifier] = index;
-            }
-
-            ++index;
-        }
-
-        if (ok) {
-
-            index = 0;
-
-            while ((descriptor = fn(VAMP_API_VERSION, index))) {
-
-                QString id = PluginIdentifier::createIdentifier
-                    ("vamp", soname, descriptor->identifier);
-                rv.push_back(id);
-#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE
-                cerr << "FeatureExtractionPluginFactory::getPluginIdentifiers: Found plugin id " << id << " at index " << index << endl;
-#endif
-                ++index;
-            }
-        }
-            
-        if (DLCLOSE(libraryHandle) != 0) {
-            cerr << "WARNING: FeatureExtractionPluginFactory::getPluginIdentifiers: Failed to unload library " << soname << endl;
-        }
+    for (const auto &d: m_pluginData) {
+        rv.push_back(QString("vamp:") + QString::fromStdString(d.pluginKey));
     }
 
-    generateTaxonomy();
-
     return rv;
 }
 
-QString
-FeatureExtractionPluginFactory::findPluginFile(QString soname, QString inDir)
-{
-    QString file = "";
-
-#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE
-    cerr << "FeatureExtractionPluginFactory::findPluginFile(\""
-              << soname << "\", \"" << inDir << "\")"
-              << endl;
-#endif
-
-    if (inDir != "") {
-
-        QDir dir(inDir, PLUGIN_GLOB,
-                 QDir::Name | QDir::IgnoreCase,
-                 QDir::Files | QDir::Readable);
-        if (!dir.exists()) return "";
-
-        file = dir.filePath(QFileInfo(soname).fileName());
-
-        if (QFileInfo(file).exists() && QFileInfo(file).isFile()) {
-
-#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE
-            cerr << "FeatureExtractionPluginFactory::findPluginFile: "
-                      << "found trivially at " << file << endl;
-#endif
-
-            return file;
-        }
-
-	for (unsigned int j = 0; j < dir.count(); ++j) {
-            file = dir.filePath(dir[j]);
-            if (QFileInfo(file).baseName() == QFileInfo(soname).baseName()) {
-
-#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE
-                cerr << "FeatureExtractionPluginFactory::findPluginFile: "
-                          << "found \"" << soname << "\" at " << file << endl;
-#endif
-
-                return file;
-            }
-        }
-
-#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE
-        cerr << "FeatureExtractionPluginFactory::findPluginFile (with dir): "
-                  << "not found" << endl;
-#endif
-
-        return "";
-
-    } else {
-
-        QFileInfo fi(soname);
-
-        if (fi.isAbsolute() && fi.exists() && fi.isFile()) {
-#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE
-            cerr << "FeatureExtractionPluginFactory::findPluginFile: "
-                      << "found trivially at " << soname << endl;
-#endif
-            return soname;
-        }
-
-        if (fi.isAbsolute() && fi.absolutePath() != "") {
-            file = findPluginFile(soname, fi.absolutePath());
-            if (file != "") return file;
-        }
-
-        vector<QString> path = getPluginPath();
-        for (vector<QString>::iterator i = path.begin();
-             i != path.end(); ++i) {
-            if (*i != "") {
-                file = findPluginFile(soname, *i);
-                if (file != "") return file;
-            }
-        }
-
-#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE
-        cerr << "FeatureExtractionPluginFactory::findPluginFile: "
-                  << "not found" << endl;
-#endif
-
-        return "";
-    }
-}
-
 Vamp::Plugin *
 FeatureExtractionPluginFactory::instantiatePlugin(QString identifier,
 						  sv_samplerate_t inputSampleRate)
 {
     Profiler profiler("FeatureExtractionPluginFactory::instantiatePlugin");
 
-    Vamp::Plugin *rv = 0;
-    Vamp::PluginHostAdapter *plugin = 0;
-
-    const VampPluginDescriptor *descriptor = 0;
-    int index = 0;
-
     QString type, soname, label;
     PluginIdentifier::parseIdentifier(identifier, type, soname, label);
-    if (type != "vamp") {
-#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE
-        cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Wrong factory for plugin type " << type << endl;
-#endif
-	return 0;
-    }
 
-    QString found = findPluginFile(soname);
+    piper_vamp::LoadRequest request;
+    request.pluginKey = (soname + ":" + label).toStdString();
+    request.inputSampleRate = inputSampleRate;
+    request.adapterFlags = 0;
+    piper_vamp::LoadResponse response = m_client.loadPlugin(request);
 
-    if (found == "") {
-        cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to find library file " << soname << endl;
-        return 0;
-    } else if (found != soname) {
-
-#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE
-        cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Given library name was " << soname << ", found at " << found << endl;
-        cerr << soname << " -> " << found << endl;
-#endif
-
-    }        
-
-    soname = found;
-
-    void *libraryHandle = DLOPEN(soname, RTLD_LAZY | RTLD_LOCAL);
-            
-    if (!libraryHandle) {
-        cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to load library " << soname << ": " << DLERROR() << endl;
-        return 0;
-    }
-
-    VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction)
-        DLSYM(libraryHandle, "vampGetPluginDescriptor");
-    
-    if (!fn) {
-        cerr << "FeatureExtractionPluginFactory::instantiatePlugin: No descriptor function in " << soname << endl;
-        goto done;
-    }
-
-    while ((descriptor = fn(VAMP_API_VERSION, index))) {
-        if (label == descriptor->identifier) break;
-        ++index;
-    }
-
-    if (!descriptor) {
-        cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Failed to find plugin \"" << label << "\" in library " << soname << endl;
-        goto done;
-    }
-
-    plugin = new Vamp::PluginHostAdapter(descriptor, float(inputSampleRate));
-
-    if (plugin) {
-        m_handleMap[plugin] = libraryHandle;
-        rv = new PluginDeletionNotifyAdapter(plugin, this);
-    }
-
-//    SVDEBUG << "FeatureExtractionPluginFactory::instantiatePlugin: Constructed Vamp plugin, rv is " << rv << endl;
-
-    //!!! need to dlclose() when plugins from a given library are unloaded
-
-done:
-    if (!rv) {
-        if (DLCLOSE(libraryHandle) != 0) {
-            cerr << "WARNING: FeatureExtractionPluginFactory::instantiatePlugin: Failed to unload library " << soname << endl;
-        }
-    }
-
-#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE
-    cerr << "FeatureExtractionPluginFactory::instantiatePlugin: Instantiated plugin " << label << " from library " << soname << ": descriptor " << descriptor << ", rv "<< rv << ", label " << rv->getName() << ", outputs " << rv->getOutputDescriptors().size() << endl;
-#endif
-    
-    return rv;
-}
-
-void
-FeatureExtractionPluginFactory::pluginDeleted(Vamp::Plugin *plugin)
-{
-    void *handle = m_handleMap[plugin];
-    if (handle) {
-#ifdef DEBUG_PLUGIN_SCAN_AND_INSTANTIATE
-        cerr << "unloading library " << handle << " for plugin " << plugin << endl;
-#endif
-        DLCLOSE(handle);
-    }
-    m_handleMap.erase(plugin);
+    return response.plugin;
 }
 
 QString
 FeatureExtractionPluginFactory::getPluginCategory(QString identifier)
 {
-    return m_taxonomy[identifier];
+    //!!! (re)implement
+//    return m_taxonomy[identifier];
+    return QString();
 }
 
 void
-FeatureExtractionPluginFactory::generateTaxonomy()
+FeatureExtractionPluginFactory::populate()
 {
-    vector<QString> pluginPath = getPluginPath();
-    vector<QString> path;
+    piper_vamp::ListResponse lr = m_client.listPluginData();
+    m_pluginData = lr.available;
+}
 
-    for (size_t i = 0; i < pluginPath.size(); ++i) {
-	if (pluginPath[i].contains("/lib/")) {
-	    QString p(pluginPath[i]);
-            path.push_back(p);
-	    p.replace("/lib/", "/share/");
-	    path.push_back(p);
-	}
-	path.push_back(pluginPath[i]);
-    }
-
-    for (size_t i = 0; i < path.size(); ++i) {
-
-	QDir dir(path[i], "*.cat");
-
-//	SVDEBUG << "LADSPAPluginFactory::generateFallbackCategories: directory " << path[i] << " has " << dir.count() << " .cat files" << endl;
-	for (unsigned int j = 0; j < dir.count(); ++j) {
-
-	    QFile file(path[i] + "/" + dir[j]);
-
-//	    SVDEBUG << "LADSPAPluginFactory::generateFallbackCategories: about to open " << (path[i]+ "/" + dir[j]) << endl;
-
-	    if (file.open(QIODevice::ReadOnly)) {
-//		    cerr << "...opened" << endl;
-		QTextStream stream(&file);
-		QString line;
-
-		while (!stream.atEnd()) {
-		    line = stream.readLine();
-//		    cerr << "line is: \"" << line << "\"" << endl;
-		    QString id = PluginIdentifier::canonicalise
-                        (line.section("::", 0, 0));
-		    QString cat = line.section("::", 1, 1);
-		    m_taxonomy[id] = cat;
-//		    cerr << "FeatureExtractionPluginFactory: set id \"" << id << "\" to cat \"" << cat << "\"" << endl;
-		}
-	    }
-	}
-    }
-}    
--- a/plugin/FeatureExtractionPluginFactory.h	Tue Sep 20 09:16:13 2016 +0100
+++ b/plugin/FeatureExtractionPluginFactory.h	Fri Oct 14 14:33:43 2016 +0100
@@ -17,6 +17,7 @@
 #define _FEATURE_EXTRACTION_PLUGIN_FACTORY_H_
 
 #include <QString>
+#include <QMutex>
 #include <vector>
 #include <map>
 
@@ -25,20 +26,20 @@
 #include "base/Debug.h"
 #include "base/BaseTypes.h"
 
+#include "vamp-client/ProcessQtTransport.h"
+#include "vamp-client/CapnpRRClient.h"
+
 class FeatureExtractionPluginFactory
 {
 public:
+    FeatureExtractionPluginFactory();
     virtual ~FeatureExtractionPluginFactory() { }
 
     static FeatureExtractionPluginFactory *instance(QString pluginType);
     static FeatureExtractionPluginFactory *instanceFor(QString identifier);
     static std::vector<QString> getAllPluginIdentifiers();
 
-    virtual std::vector<QString> getPluginPath();
-
     virtual std::vector<QString> getPluginIdentifiers();
-    
-    virtual QString findPluginFile(QString soname, QString inDir = "");
 
     // We don't set blockSize or channels on this -- they're
     // negotiated and handled via initialize() on the plugin
@@ -51,14 +52,12 @@
     virtual QString getPluginCategory(QString identifier);
 
 protected:
-    std::vector<QString> m_pluginPath;
-    std::map<QString, QString> m_taxonomy;
+    piper_vamp::client::ProcessQtTransport m_transport;
+    piper_vamp::client::CapnpRRClient m_client;
 
-    friend class PluginDeletionNotifyAdapter;
-    void pluginDeleted(Vamp::Plugin *);
-    std::map<Vamp::Plugin *, void *> m_handleMap;
-    
-    void generateTaxonomy();
+    QMutex m_mutex;
+    std::vector<piper_vamp::PluginStaticData> m_pluginData;
+    void populate();
 };
 
 #endif
--- a/svcore.pro	Tue Sep 20 09:16:13 2016 +0100
+++ b/svcore.pro	Fri Oct 14 14:33:43 2016 +0100
@@ -38,8 +38,8 @@
 
 TARGET = svcore
 
-DEPENDPATH += . data plugin plugin/api/alsa
-INCLUDEPATH += . data plugin plugin/api/alsa ../dataquay ../checker
+DEPENDPATH += . data plugin plugin/api/alsa ../dataquay ../checker ../piper-cpp
+INCLUDEPATH += . data plugin plugin/api/alsa ../dataquay ../checker ../piper-cpp
 OBJECTS_DIR = o
 MOC_DIR = o