annotate plugin/PiperVampPluginFactory.cpp @ 1235:7f4230e7d83a project-file-rework

Error handling
author Chris Cannam
date Thu, 27 Oct 2016 16:13:25 +0100
parents 2d9e2771805a
children fe391a7b8376
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@202 7 This file copyright 2006 Chris Cannam and QMUL.
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@1225 16 #include "PiperVampPluginFactory.h"
Chris@0 17 #include "PluginIdentifier.h"
Chris@0 18
Chris@150 19 #include "system/System.h"
Chris@66 20
Chris@1179 21 #include "PluginScan.h"
Chris@1179 22
Chris@1224 23 #ifdef _WIN32
Chris@1224 24 #undef VOID
Chris@1224 25 #undef ERROR
Chris@1224 26 #define CAPNP_LITE 1
Chris@1224 27 #endif
Chris@1225 28
Chris@1210 29 #include "vamp-client/AutoPlugin.h"
Chris@1210 30
Chris@66 31 #include <QDir>
Chris@66 32 #include <QFile>
Chris@66 33 #include <QFileInfo>
Chris@165 34 #include <QTextStream>
Chris@1227 35 #include <QCoreApplication>
Chris@66 36
Chris@0 37 #include <iostream>
Chris@0 38
Chris@408 39 #include "base/Profiler.h"
Chris@408 40
Chris@1223 41 #include "vamp-client/ProcessQtTransport.h"
Chris@1223 42 #include "vamp-client/CapnpRRClient.h"
Chris@1223 43
Chris@1164 44 using namespace std;
Chris@1164 45
Chris@249 46 //#define DEBUG_PLUGIN_SCAN_AND_INSTANTIATE 1
Chris@249 47
Chris@1225 48 PiperVampPluginFactory::PiperVampPluginFactory() :
Chris@1227 49 // No server unless we find one - don't run arbitrary stuff from the path:
Chris@1227 50 m_serverName()
Chris@66 51 {
Chris@1227 52 // Server must exist either in the same directory as this one or
Chris@1227 53 // (preferably) a subdirectory called "piper-bin".
Chris@1227 54 //!!! todo: merge this with plugin scan checker thingy used in main.cpp?
Chris@1227 55 QString myDir = QCoreApplication::applicationDirPath();
Chris@1227 56 QString name = "piper-vamp-server";
Chris@1227 57 QString path = myDir + "/piper-bin/" + name;
Chris@1227 58 QString suffix = "";
Chris@1227 59 #ifdef _WIN32
Chris@1227 60 suffix = ".exe";
Chris@1227 61 #endif
Chris@1227 62 if (!QFile(path + suffix).exists()) {
Chris@1227 63 cerr << "NOTE: Piper Vamp server not found at " << (path + suffix)
Chris@1227 64 << ", trying in my own directory" << endl;
Chris@1227 65 path = myDir + "/" + name;
Chris@1227 66 }
Chris@1227 67 if (!QFile(path + suffix).exists()) {
Chris@1227 68 cerr << "NOTE: Piper Vamp server not found at " << (path + suffix)
Chris@1227 69 << endl;
Chris@1227 70 } else {
Chris@1227 71 m_serverName = (path + suffix).toStdString();
Chris@1227 72 }
Chris@66 73 }
Chris@66 74
Chris@1164 75 vector<QString>
Chris@1227 76 PiperVampPluginFactory::getPluginIdentifiers(QString &errorMessage)
Chris@0 77 {
Chris@1225 78 Profiler profiler("PiperVampPluginFactory::getPluginIdentifiers");
Chris@408 79
Chris@1209 80 QMutexLocker locker(&m_mutex);
Chris@1209 81
Chris@1227 82 if (m_serverName == "") {
Chris@1227 83 errorMessage = QObject::tr("External plugin host executable does not appear to be installed");
Chris@1227 84 return {};
Chris@1227 85 }
Chris@1227 86
Chris@1209 87 if (m_pluginData.empty()) {
Chris@1227 88 populate(errorMessage);
Chris@1209 89 }
Chris@1209 90
Chris@1164 91 vector<QString> rv;
Chris@1179 92
Chris@1209 93 for (const auto &d: m_pluginData) {
Chris@1225 94 rv.push_back(QString("vamp:") + QString::fromStdString(d.second.pluginKey));
Chris@66 95 }
Chris@66 96
Chris@0 97 return rv;
Chris@0 98 }
Chris@0 99
Chris@66 100 Vamp::Plugin *
Chris@1225 101 PiperVampPluginFactory::instantiatePlugin(QString identifier,
Chris@1225 102 sv_samplerate_t inputSampleRate)
Chris@0 103 {
Chris@1225 104 Profiler profiler("PiperVampPluginFactory::instantiatePlugin");
Chris@1225 105
Chris@1225 106 auto psd = getPluginStaticData(identifier);
Chris@1225 107 if (psd.pluginKey == "") {
Chris@1225 108 return 0;
Chris@1225 109 }
Chris@1210 110
Chris@1210 111 auto ap = new piper_vamp::client::AutoPlugin
Chris@1225 112 (m_serverName, psd.pluginKey, float(inputSampleRate), 0);
Chris@1210 113 if (!ap->isOK()) {
Chris@1210 114 delete ap;
Chris@1210 115 return 0;
Chris@1225 116 }
Chris@1225 117
Chris@1225 118 return ap;
Chris@1225 119 }
Chris@1225 120
Chris@1225 121 piper_vamp::PluginStaticData
Chris@1225 122 PiperVampPluginFactory::getPluginStaticData(QString identifier)
Chris@1225 123 {
Chris@1225 124 if (m_pluginData.find(identifier) != m_pluginData.end()) {
Chris@1225 125 return m_pluginData[identifier];
Chris@1210 126 } else {
Chris@1225 127 return {};
Chris@1210 128 }
Chris@298 129 }
Chris@298 130
Chris@165 131 QString
Chris@1225 132 PiperVampPluginFactory::getPluginCategory(QString identifier)
Chris@165 133 {
Chris@1223 134 if (m_taxonomy.find(identifier) != m_taxonomy.end()) {
Chris@1223 135 return m_taxonomy[identifier];
Chris@1223 136 } else {
Chris@1223 137 return {};
Chris@1223 138 }
Chris@165 139 }
Chris@165 140
Chris@165 141 void
Chris@1227 142 PiperVampPluginFactory::populate(QString &errorMessage)
Chris@165 143 {
Chris@1227 144 if (m_serverName == "") return;
Chris@1227 145
Chris@1233 146 piper_vamp::client::ProcessQtTransport transport(m_serverName, "capnp");
Chris@1227 147 if (!transport.isOK()) {
Chris@1227 148 errorMessage = QObject::tr("Could not start external plugin host");
Chris@1227 149 return;
Chris@1227 150 }
Chris@1234 151
Chris@1223 152 piper_vamp::client::CapnpRRClient client(&transport);
Chris@1234 153 piper_vamp::ListResponse lr;
Chris@1234 154
Chris@1234 155 try {
Chris@1234 156 lr = client.listPluginData();
Chris@1234 157 } catch (piper_vamp::client::ServerCrashed) {
Chris@1234 158 errorMessage = QObject::tr
Chris@1234 159 ("External plugin host exited unexpectedly while listing plugins");
Chris@1234 160 return;
Chris@1235 161 } catch (const std::exception &e) {
Chris@1235 162 errorMessage = QObject::tr("External plugin host invocation failed: %1")
Chris@1235 163 .arg(e.what());
Chris@1235 164 return;
Chris@1234 165 }
Chris@1213 166
Chris@1225 167 for (const auto &pd: lr.available) {
Chris@1213 168
Chris@1213 169 QString identifier =
Chris@1213 170 QString("vamp:") + QString::fromStdString(pd.pluginKey);
Chris@1213 171
Chris@1225 172 m_pluginData[identifier] = pd;
Chris@1225 173
Chris@1213 174 QStringList catlist;
Chris@1213 175 for (const auto &cs: pd.category) {
Chris@1213 176 catlist.push_back(QString::fromStdString(cs));
Chris@1213 177 }
Chris@1223 178
Chris@1213 179 m_taxonomy[identifier] = catlist.join(" > ");
Chris@1213 180 }
Chris@1209 181 }
Chris@165 182