changeset 1240:42a4b058f8ba 3.0-integration

Support for multiple servers
author Chris Cannam
date Tue, 01 Nov 2016 12:09:05 +0000
parents 5261a7791f1c
children c6bdf247016a
files plugin/PiperVampPluginFactory.cpp plugin/PiperVampPluginFactory.h
diffstat 2 files changed, 77 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/plugin/PiperVampPluginFactory.cpp	Fri Oct 28 15:20:58 2016 +0100
+++ b/plugin/PiperVampPluginFactory.cpp	Tue Nov 01 12:09:05 2016 +0000
@@ -45,30 +45,53 @@
 
 //#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 = "";
+    QStringList suffixes = getServerSuffixes();
+    QString extension = "";
 #ifdef _WIN32
-    suffix = ".exe";
+    extension = ".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;
+
+    for (QString s: suffixes) {
+    
+        QString path = myDir + "/piper-bin/" + name + s + extension;
+        
+        if (QFile(path).exists()) {
+            m_servers.push_back(path);
+        } else {
+            cerr << "NOTE: Piper Vamp server " << name << s
+                 << " not found at " << path
+                 << ", trying in my own directory" << endl;
+            path = myDir + "/" + name + s + extension;
+
+            if (QFile(path).exists()) {
+                m_servers.push_back(path);
+            } else {
+                cerr << "NOTE: Piper Vamp server " << name << s
+                     << " not found at " << path << endl;
+            }
+        }
     }
-    if (!QFile(path + suffix).exists()) {
-        cerr << "NOTE: Piper Vamp server not found at " << (path + suffix)
-             << endl;
+
+    if (m_servers.empty()) {
+        cerr << "NOTE: No Piper Vamp servers found" << endl;
+    }
+}
+
+QStringList
+PiperVampPluginFactory::getServerSuffixes()
+{
+    if (sizeof(void *) == 8) {
+        return { "-64", "", "-32" };
     } else {
-        m_serverName = (path + suffix).toStdString();
+        return { "", "-32" };
     }
 }
 
@@ -79,7 +102,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 +126,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 +171,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 +209,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:20:58 2016 +0100
+++ b/plugin/PiperVampPluginFactory.h	Tue Nov 01 12:09:05 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