changeset 1242:c401e738793f piper

Merge from branch 3.0-integration
author Chris Cannam
date Tue, 01 Nov 2016 14:08:57 +0000
parents dd49630e0d70 (current diff) c6bdf247016a (diff)
children c7a710f806a1
files
diffstat 5 files changed, 105 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/files.pri	Fri Oct 28 15:19:12 2016 +0100
+++ b/files.pri	Tue Nov 01 14:08:57 2016 +0000
@@ -7,6 +7,7 @@
            base/Command.h \
            base/Debug.h \
            base/Exceptions.h \
+           base/HelperExecPath.h \
            base/LogRange.h \
            base/MagnitudeRange.h \
            base/Pitch.h \
@@ -144,6 +145,7 @@
            base/Command.cpp \
            base/Debug.cpp \
            base/Exceptions.cpp \
+           base/HelperExecPath.cpp \
            base/LogRange.cpp \
            base/Pitch.cpp \
            base/PlayParameterRepository.cpp \
--- a/plugin/PiperVampPluginFactory.cpp	Fri Oct 28 15:19:12 2016 +0100
+++ b/plugin/PiperVampPluginFactory.cpp	Tue Nov 01 14:08:57 2016 +0000
@@ -4,7 +4,7 @@
     Sonic Visualiser
     An audio file viewer and annotation editor.
     Centre for Digital Music, Queen Mary, University of London.
-    This file copyright 2006 Chris Cannam and QMUL.
+    This file copyright 2006-2016 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
@@ -37,6 +37,7 @@
 #include <iostream>
 
 #include "base/Profiler.h"
+#include "base/HelperExecPath.h"
 
 #include "vamp-client/ProcessQtTransport.h"
 #include "vamp-client/CapnpRRClient.h"
@@ -45,30 +46,28 @@
 
 //#define DEBUG_PLUGIN_SCAN_AND_INSTANTIATE 1
 
-PiperVampPluginFactory::PiperVampPluginFactory() :
-    // No server unless we find one - don't run arbitrary stuff from the path:
-    m_serverName()
+PiperVampPluginFactory::PiperVampPluginFactory()
 {
-    // Server must exist either in the same directory as this one or
-    // (preferably) a subdirectory called "piper-bin".
-    //!!! todo: merge this with plugin scan checker thingy used in main.cpp?
-    QString myDir = QCoreApplication::applicationDirPath();
-    QString name = "piper-vamp-simple-server";
-    QString path = myDir + "/piper-bin/" + name;
-    QString suffix = "";
-#ifdef _WIN32
-    suffix = ".exe";
-#endif
-    if (!QFile(path + suffix).exists()) {
-        cerr << "NOTE: Piper Vamp server not found at " << (path + suffix)
-             << ", trying in my own directory" << endl;
-        path = myDir + "/" + name;
+    QString serverName = "piper-vamp-simple-server";
+
+    m_servers = HelperExecPath::getHelperExecutables(serverName);
+
+    if (m_servers.empty()) {
+        cerr << "NOTE: No Piper Vamp servers found in installation;"
+             << " found none of the following:" << endl;
+        for (auto d: HelperExecPath::getHelperCandidatePaths(serverName)) {
+            cerr << "NOTE: " << d << endl;
+        }
     }
-    if (!QFile(path + suffix).exists()) {
-        cerr << "NOTE: Piper Vamp server not found at " << (path + suffix)
-             << endl;
+}
+
+QStringList
+PiperVampPluginFactory::getServerSuffixes()
+{
+    if (sizeof(void *) == 8) {
+        return { "-64", "", "-32" };
     } else {
-        m_serverName = (path + suffix).toStdString();
+        return { "", "-32" };
     }
 }
 
@@ -79,7 +78,7 @@
 
     QMutexLocker locker(&m_mutex);
 
-    if (m_serverName == "") {
+    if (m_servers.empty()) {
         errorMessage = QObject::tr("External plugin host executable does not appear to be installed");
         return {};
     }
@@ -103,13 +102,20 @@
 {
     Profiler profiler("PiperVampPluginFactory::instantiatePlugin");
 
+    if (m_origins.find(identifier) == m_origins.end()) {
+        cerr << "ERROR: No known server for identifier " << identifier << endl;
+        return 0;
+    }
+    
     auto psd = getPluginStaticData(identifier);
     if (psd.pluginKey == "") {
         return 0;
     }
     
     auto ap = new piper_vamp::client::AutoPlugin
-        (m_serverName, psd.pluginKey, float(inputSampleRate), 0);
+        (m_origins[identifier].toStdString(),
+         psd.pluginKey, float(inputSampleRate), 0);
+    
     if (!ap->isOK()) {
         delete ap;
         return 0;
@@ -141,9 +147,23 @@
 void
 PiperVampPluginFactory::populate(QString &errorMessage)
 {
-    if (m_serverName == "") return;
+    QString someError;
 
-    piper_vamp::client::ProcessQtTransport transport(m_serverName, "capnp");
+    for (QString s: m_servers) {
+
+        populateFrom(s, someError);
+
+        if (someError != "" && errorMessage == "") {
+            errorMessage = someError;
+        }
+    }
+}
+
+void
+PiperVampPluginFactory::populateFrom(QString server, QString &errorMessage)
+{
+    piper_vamp::client::ProcessQtTransport transport(server.toStdString(),
+                                                     "capnp");
     if (!transport.isOK()) {
         errorMessage = QObject::tr("Could not start external plugin host");
         return;
@@ -165,10 +185,18 @@
     }
 
     for (const auto &pd: lr.available) {
-
+        
         QString identifier =
             QString("vamp:") + QString::fromStdString(pd.pluginKey);
 
+        if (m_origins.find(identifier) != m_origins.end()) {
+            // have it already, from a higher-priority server
+            // (e.g. 64-bit instead of 32-bit)
+            continue;
+        }
+
+        m_origins[identifier] = server;
+        
         m_pluginData[identifier] = pd;
 
         QStringList catlist;
--- a/plugin/PiperVampPluginFactory.h	Fri Oct 28 15:19:12 2016 +0100
+++ b/plugin/PiperVampPluginFactory.h	Tue Nov 01 14:08:57 2016 +0000
@@ -49,10 +49,15 @@
 
 protected:
     QMutex m_mutex;
-    std::string m_serverName;
+    QStringList m_servers; // executable file paths
+    std::map<QString, QString> m_origins; // plugin identifier -> server path
     std::map<QString, piper_vamp::PluginStaticData> m_pluginData; // identifier -> data
     std::map<QString, QString> m_taxonomy; // identifier -> category string
+
     void populate(QString &errorMessage);
+    void populateFrom(QString server, QString &errorMessage);
+
+    static QStringList getServerSuffixes();
 };
 
 #endif
--- a/plugin/PluginScan.cpp	Fri Oct 28 15:19:12 2016 +0100
+++ b/plugin/PluginScan.cpp	Tue Nov 01 14:08:57 2016 +0000
@@ -15,6 +15,7 @@
 #include "PluginScan.h"
 
 #include "base/Debug.h"
+#include "base/HelperExecPath.h"
 
 #include "checker/knownplugins.h"
 
@@ -50,22 +51,36 @@
 }
 
 PluginScan::~PluginScan() {
-    delete m_kp;
+    clear();
     delete m_logger;
 }
 
 void
-PluginScan::scan(QString helperExecutablePath)
+PluginScan::scan()
 {
-    delete m_kp;
+    QStringList helperPaths =
+        HelperExecPath::getHelperExecutables("plugin-checker-helper");
+
+    clear();
+
+    for (auto p: helperPaths) {
+        try {
+            KnownPlugins *kp = new KnownPlugins(p.toStdString(), m_logger);
+            m_kp.push_back(kp);
+            m_succeeded = true;
+        } catch (const std::exception &e) {
+            cerr << "ERROR: PluginScan::scan: " << e.what()
+                 << " (with helper path = " << p << ")" << endl;
+        }
+    }
+}
+
+void
+PluginScan::clear()
+{
+    for (auto &p: m_kp) delete p;
+    m_kp.clear();
     m_succeeded = false;
-    try {
-	m_kp = new KnownPlugins(helperExecutablePath.toStdString(), m_logger);
-	m_succeeded = true;
-    } catch (const std::exception &e) {
-	cerr << "ERROR: PluginScan::scan: " << e.what() << endl;
-	m_kp = 0;
-    }
 }
 
 QStringList
@@ -80,9 +95,10 @@
     }
     
     QStringList candidates;
-    if (!m_kp) return candidates;
-    auto c = m_kp->getCandidateLibrariesFor(kpt);
-    for (auto s: c) candidates.push_back(s.c_str());
+    for (auto kp: m_kp) {
+        auto c = kp->getCandidateLibrariesFor(kpt);
+        for (auto s: c) candidates.push_back(s.c_str());
+    }
     return candidates;
 }
 
@@ -96,20 +112,23 @@
                            "installed alongside %1?</p>")
             .arg(QCoreApplication::applicationName());
     }
-    if (!m_kp) {
+    if (m_kp.empty()) {
 	return QObject::tr("<b>Did not scan for plugins</b>"
 			   "<p>Apparently no scan for plugins was attempted "
 			   "(internal error?)</p>");
     }
 
-    string report = m_kp->getFailureReport();
+    QString report;
+    for (auto kp: m_kp) {
+        report += QString::fromStdString(kp->getFailureReport());
+    }
     if (report == "") {
-	return QString(report.c_str());
+	return report;
     }
 
     return QObject::tr("<b>Failed to load plugins</b>"
 		       "<p>Failed to load one or more plugin libraries:</p>")
-	+ QString(report.c_str())
+	+ report
         + QObject::tr("<p>These plugins may be incompatible with the system, "
                       "and will be ignored during this run of %1.</p>")
         .arg(QCoreApplication::applicationName());
--- a/plugin/PluginScan.h	Fri Oct 28 15:19:12 2016 +0100
+++ b/plugin/PluginScan.h	Tue Nov 01 14:08:57 2016 +0000
@@ -16,6 +16,7 @@
 #define PLUGIN_SCAN_H
 
 #include <QStringList>
+#include <vector>
 
 class KnownPlugins;
 
@@ -24,7 +25,7 @@
 public:
     static PluginScan *getInstance();
 
-    void scan(QString helperExecutablePath);
+    void scan();
 
     bool scanSucceeded() const;
     
@@ -40,7 +41,10 @@
 private:
     PluginScan();
     ~PluginScan();
-    KnownPlugins *m_kp;
+
+    void clear();
+    
+    std::vector<KnownPlugins *> m_kp;
     bool m_succeeded;
 
     class Logger;