comparison plugin/PiperVampPluginFactory.cpp @ 1242:c401e738793f piper

Merge from branch 3.0-integration
author Chris Cannam
date Tue, 01 Nov 2016 14:08:57 +0000
parents c6bdf247016a
children 604b0b2a58e1
comparison
equal deleted inserted replaced
1238:dd49630e0d70 1242:c401e738793f
2 2
3 /* 3 /*
4 Sonic Visualiser 4 Sonic Visualiser
5 An audio file viewer and annotation editor. 5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London. 6 Centre for Digital Music, Queen Mary, University of London.
7 This file copyright 2006 Chris Cannam and QMUL. 7 This file copyright 2006-2016 Chris Cannam and QMUL.
8 8
9 This program is free software; you can redistribute it and/or 9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as 10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the 11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file 12 License, or (at your option) any later version. See the file
35 #include <QCoreApplication> 35 #include <QCoreApplication>
36 36
37 #include <iostream> 37 #include <iostream>
38 38
39 #include "base/Profiler.h" 39 #include "base/Profiler.h"
40 #include "base/HelperExecPath.h"
40 41
41 #include "vamp-client/ProcessQtTransport.h" 42 #include "vamp-client/ProcessQtTransport.h"
42 #include "vamp-client/CapnpRRClient.h" 43 #include "vamp-client/CapnpRRClient.h"
43 44
44 using namespace std; 45 using namespace std;
45 46
46 //#define DEBUG_PLUGIN_SCAN_AND_INSTANTIATE 1 47 //#define DEBUG_PLUGIN_SCAN_AND_INSTANTIATE 1
47 48
48 PiperVampPluginFactory::PiperVampPluginFactory() : 49 PiperVampPluginFactory::PiperVampPluginFactory()
49 // No server unless we find one - don't run arbitrary stuff from the path: 50 {
50 m_serverName() 51 QString serverName = "piper-vamp-simple-server";
51 { 52
52 // Server must exist either in the same directory as this one or 53 m_servers = HelperExecPath::getHelperExecutables(serverName);
53 // (preferably) a subdirectory called "piper-bin". 54
54 //!!! todo: merge this with plugin scan checker thingy used in main.cpp? 55 if (m_servers.empty()) {
55 QString myDir = QCoreApplication::applicationDirPath(); 56 cerr << "NOTE: No Piper Vamp servers found in installation;"
56 QString name = "piper-vamp-simple-server"; 57 << " found none of the following:" << endl;
57 QString path = myDir + "/piper-bin/" + name; 58 for (auto d: HelperExecPath::getHelperCandidatePaths(serverName)) {
58 QString suffix = ""; 59 cerr << "NOTE: " << d << endl;
59 #ifdef _WIN32 60 }
60 suffix = ".exe"; 61 }
61 #endif 62 }
62 if (!QFile(path + suffix).exists()) { 63
63 cerr << "NOTE: Piper Vamp server not found at " << (path + suffix) 64 QStringList
64 << ", trying in my own directory" << endl; 65 PiperVampPluginFactory::getServerSuffixes()
65 path = myDir + "/" + name; 66 {
66 } 67 if (sizeof(void *) == 8) {
67 if (!QFile(path + suffix).exists()) { 68 return { "-64", "", "-32" };
68 cerr << "NOTE: Piper Vamp server not found at " << (path + suffix)
69 << endl;
70 } else { 69 } else {
71 m_serverName = (path + suffix).toStdString(); 70 return { "", "-32" };
72 } 71 }
73 } 72 }
74 73
75 vector<QString> 74 vector<QString>
76 PiperVampPluginFactory::getPluginIdentifiers(QString &errorMessage) 75 PiperVampPluginFactory::getPluginIdentifiers(QString &errorMessage)
77 { 76 {
78 Profiler profiler("PiperVampPluginFactory::getPluginIdentifiers"); 77 Profiler profiler("PiperVampPluginFactory::getPluginIdentifiers");
79 78
80 QMutexLocker locker(&m_mutex); 79 QMutexLocker locker(&m_mutex);
81 80
82 if (m_serverName == "") { 81 if (m_servers.empty()) {
83 errorMessage = QObject::tr("External plugin host executable does not appear to be installed"); 82 errorMessage = QObject::tr("External plugin host executable does not appear to be installed");
84 return {}; 83 return {};
85 } 84 }
86 85
87 if (m_pluginData.empty()) { 86 if (m_pluginData.empty()) {
101 PiperVampPluginFactory::instantiatePlugin(QString identifier, 100 PiperVampPluginFactory::instantiatePlugin(QString identifier,
102 sv_samplerate_t inputSampleRate) 101 sv_samplerate_t inputSampleRate)
103 { 102 {
104 Profiler profiler("PiperVampPluginFactory::instantiatePlugin"); 103 Profiler profiler("PiperVampPluginFactory::instantiatePlugin");
105 104
105 if (m_origins.find(identifier) == m_origins.end()) {
106 cerr << "ERROR: No known server for identifier " << identifier << endl;
107 return 0;
108 }
109
106 auto psd = getPluginStaticData(identifier); 110 auto psd = getPluginStaticData(identifier);
107 if (psd.pluginKey == "") { 111 if (psd.pluginKey == "") {
108 return 0; 112 return 0;
109 } 113 }
110 114
111 auto ap = new piper_vamp::client::AutoPlugin 115 auto ap = new piper_vamp::client::AutoPlugin
112 (m_serverName, psd.pluginKey, float(inputSampleRate), 0); 116 (m_origins[identifier].toStdString(),
117 psd.pluginKey, float(inputSampleRate), 0);
118
113 if (!ap->isOK()) { 119 if (!ap->isOK()) {
114 delete ap; 120 delete ap;
115 return 0; 121 return 0;
116 } 122 }
117 123
139 } 145 }
140 146
141 void 147 void
142 PiperVampPluginFactory::populate(QString &errorMessage) 148 PiperVampPluginFactory::populate(QString &errorMessage)
143 { 149 {
144 if (m_serverName == "") return; 150 QString someError;
145 151
146 piper_vamp::client::ProcessQtTransport transport(m_serverName, "capnp"); 152 for (QString s: m_servers) {
153
154 populateFrom(s, someError);
155
156 if (someError != "" && errorMessage == "") {
157 errorMessage = someError;
158 }
159 }
160 }
161
162 void
163 PiperVampPluginFactory::populateFrom(QString server, QString &errorMessage)
164 {
165 piper_vamp::client::ProcessQtTransport transport(server.toStdString(),
166 "capnp");
147 if (!transport.isOK()) { 167 if (!transport.isOK()) {
148 errorMessage = QObject::tr("Could not start external plugin host"); 168 errorMessage = QObject::tr("Could not start external plugin host");
149 return; 169 return;
150 } 170 }
151 171
163 .arg(e.what()); 183 .arg(e.what());
164 return; 184 return;
165 } 185 }
166 186
167 for (const auto &pd: lr.available) { 187 for (const auto &pd: lr.available) {
168 188
169 QString identifier = 189 QString identifier =
170 QString("vamp:") + QString::fromStdString(pd.pluginKey); 190 QString("vamp:") + QString::fromStdString(pd.pluginKey);
171 191
192 if (m_origins.find(identifier) != m_origins.end()) {
193 // have it already, from a higher-priority server
194 // (e.g. 64-bit instead of 32-bit)
195 continue;
196 }
197
198 m_origins[identifier] = server;
199
172 m_pluginData[identifier] = pd; 200 m_pluginData[identifier] = pd;
173 201
174 QStringList catlist; 202 QStringList catlist;
175 for (const auto &cs: pd.category) { 203 for (const auto &cs: pd.category) {
176 catlist.push_back(QString::fromStdString(cs)); 204 catlist.push_back(QString::fromStdString(cs));