# HG changeset patch # User Chris Cannam # Date 1478009337 0 # Node ID c401e738793f2de89d7b63a7948c7831966a44e6 # Parent dd49630e0d7070276e33465db43269363df06c18# Parent c6bdf247016a9f264a05082f9725b93171d17dac Merge from branch 3.0-integration diff -r dd49630e0d70 -r c401e738793f files.pri --- 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 \ diff -r dd49630e0d70 -r c401e738793f plugin/PiperVampPluginFactory.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 #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; diff -r dd49630e0d70 -r c401e738793f plugin/PiperVampPluginFactory.h --- 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 m_origins; // plugin identifier -> server path std::map m_pluginData; // identifier -> data std::map m_taxonomy; // identifier -> category string + void populate(QString &errorMessage); + void populateFrom(QString server, QString &errorMessage); + + static QStringList getServerSuffixes(); }; #endif diff -r dd49630e0d70 -r c401e738793f plugin/PluginScan.cpp --- 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?

") .arg(QCoreApplication::applicationName()); } - if (!m_kp) { + if (m_kp.empty()) { return QObject::tr("Did not scan for plugins" "

Apparently no scan for plugins was attempted " "(internal error?)

"); } - 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("Failed to load plugins" "

Failed to load one or more plugin libraries:

") - + QString(report.c_str()) + + report + QObject::tr("

These plugins may be incompatible with the system, " "and will be ignored during this run of %1.

") .arg(QCoreApplication::applicationName()); diff -r dd49630e0d70 -r c401e738793f plugin/PluginScan.h --- 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 +#include 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 m_kp; bool m_succeeded; class Logger;