Chris@4
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@5
|
2 /*
|
Chris@20
|
3 Copyright (c) 2016 Queen Mary, University of London
|
Chris@5
|
4
|
Chris@20
|
5 Permission is hereby granted, free of charge, to any person
|
Chris@20
|
6 obtaining a copy of this software and associated documentation
|
Chris@20
|
7 files (the "Software"), to deal in the Software without
|
Chris@20
|
8 restriction, including without limitation the rights to use, copy,
|
Chris@20
|
9 modify, merge, publish, distribute, sublicense, and/or sell copies
|
Chris@20
|
10 of the Software, and to permit persons to whom the Software is
|
Chris@20
|
11 furnished to do so, subject to the following conditions:
|
Chris@5
|
12
|
Chris@20
|
13 The above copyright notice and this permission notice shall be
|
Chris@20
|
14 included in all copies or substantial portions of the Software.
|
Chris@5
|
15
|
Chris@20
|
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
Chris@20
|
17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
Chris@20
|
18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
Chris@20
|
19 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
Chris@20
|
20 CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
Chris@20
|
21 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
Chris@20
|
22 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
Chris@5
|
23
|
Chris@20
|
24 Except as contained in this notice, the names of the Centre for
|
Chris@20
|
25 Digital Music and Queen Mary, University of London shall not be
|
Chris@20
|
26 used in advertising or otherwise to promote the sale, use or other
|
Chris@20
|
27 dealings in this Software without prior written authorization.
|
Chris@5
|
28 */
|
Chris@4
|
29
|
Chris@4
|
30 #include "knownplugins.h"
|
Chris@4
|
31
|
Chris@4
|
32 #include <sstream>
|
Chris@4
|
33
|
Chris@4
|
34 using namespace std;
|
Chris@4
|
35
|
Chris@4
|
36 #if defined(_WIN32)
|
Chris@4
|
37 #define PATH_SEPARATOR ';'
|
Chris@4
|
38 #else
|
Chris@4
|
39 #define PATH_SEPARATOR ':'
|
Chris@4
|
40 #endif
|
Chris@4
|
41
|
Chris@6
|
42 KnownPlugins::KnownPlugins(string helperExecutableName,
|
Chris@6
|
43 PluginCandidates::LogCallback *cb) :
|
Chris@20
|
44 m_candidates(helperExecutableName),
|
Chris@20
|
45 m_helperExecutableName(helperExecutableName)
|
Chris@4
|
46 {
|
Chris@6
|
47 m_candidates.setLogCallback(cb);
|
Chris@6
|
48
|
Chris@4
|
49 m_known = {
|
Chris@19
|
50 {
|
Chris@19
|
51 VampPlugin,
|
Chris@19
|
52 {
|
Chris@19
|
53 "vamp",
|
Chris@19
|
54 expandConventionalPath(VampPlugin, "VAMP_PATH"),
|
Chris@19
|
55 "vampGetPluginDescriptor"
|
Chris@19
|
56 },
|
Chris@19
|
57 }, {
|
Chris@19
|
58 LADSPAPlugin,
|
Chris@19
|
59 {
|
Chris@19
|
60 "ladspa",
|
Chris@19
|
61 expandConventionalPath(LADSPAPlugin, "LADSPA_PATH"),
|
Chris@19
|
62 "ladspa_descriptor"
|
Chris@19
|
63 },
|
Chris@19
|
64 }, {
|
Chris@19
|
65 DSSIPlugin,
|
Chris@19
|
66 {
|
Chris@19
|
67 "dssi",
|
Chris@19
|
68 expandConventionalPath(DSSIPlugin, "DSSI_PATH"),
|
Chris@19
|
69 "dssi_descriptor"
|
Chris@19
|
70 }
|
Chris@19
|
71 }
|
Chris@4
|
72 };
|
Chris@4
|
73
|
Chris@4
|
74 for (const auto &k: m_known) {
|
Chris@19
|
75 m_candidates.scan(k.second.tag, k.second.path, k.second.descriptor);
|
Chris@4
|
76 }
|
Chris@4
|
77 }
|
Chris@4
|
78
|
Chris@20
|
79 bool
|
Chris@20
|
80 KnownPlugins::is32bit() const
|
Chris@20
|
81 {
|
Chris@20
|
82 return m_helperExecutableName.find("-32") != std::string::npos;
|
Chris@20
|
83 }
|
Chris@20
|
84
|
Chris@4
|
85 string
|
Chris@4
|
86 KnownPlugins::getDefaultPath(PluginType type)
|
Chris@4
|
87 {
|
Chris@4
|
88 switch (type) {
|
Chris@4
|
89
|
Chris@4
|
90 #if defined(_WIN32)
|
Chris@4
|
91
|
Chris@4
|
92 case VampPlugin:
|
Chris@19
|
93 return "%ProgramFiles%\\Vamp Plugins";
|
Chris@4
|
94 case LADSPAPlugin:
|
Chris@19
|
95 return "%ProgramFiles%\\LADSPA Plugins;%ProgramFiles%\\Audacity\\Plug-Ins";
|
Chris@4
|
96 case DSSIPlugin:
|
Chris@19
|
97 return "%ProgramFiles%\\DSSI Plugins";
|
Chris@19
|
98
|
Chris@4
|
99 #elif defined(__APPLE__)
|
Chris@19
|
100
|
Chris@4
|
101 case VampPlugin:
|
Chris@19
|
102 return "$HOME/Library/Audio/Plug-Ins/Vamp:/Library/Audio/Plug-Ins/Vamp";
|
Chris@4
|
103 case LADSPAPlugin:
|
Chris@19
|
104 return "$HOME/Library/Audio/Plug-Ins/LADSPA:/Library/Audio/Plug-Ins/LADSPA";
|
Chris@4
|
105 case DSSIPlugin:
|
Chris@19
|
106 return "$HOME/Library/Audio/Plug-Ins/DSSI:/Library/Audio/Plug-Ins/DSSI";
|
Chris@19
|
107
|
Chris@4
|
108 #else /* Linux, BSDs, etc */
|
Chris@19
|
109
|
Chris@4
|
110 case VampPlugin:
|
Chris@19
|
111 return "$HOME/vamp:$HOME/.vamp:/usr/local/lib/vamp:/usr/lib/vamp";
|
Chris@4
|
112 case LADSPAPlugin:
|
Chris@19
|
113 return "$HOME/ladspa:$HOME/.ladspa:/usr/local/lib/ladspa:/usr/lib/ladspa";
|
Chris@4
|
114 case DSSIPlugin:
|
Chris@19
|
115 return "$HOME/dssi:$HOME/.dssi:/usr/local/lib/dssi:/usr/lib/dssi";
|
Chris@4
|
116 #endif
|
Chris@4
|
117 }
|
Chris@4
|
118
|
Chris@4
|
119 throw logic_error("unknown or unhandled plugin type");
|
Chris@4
|
120 }
|
Chris@4
|
121
|
Chris@4
|
122 vector<string>
|
Chris@4
|
123 KnownPlugins::expandConventionalPath(PluginType type, string var)
|
Chris@4
|
124 {
|
Chris@4
|
125 vector<string> pathList;
|
Chris@4
|
126 string path;
|
Chris@4
|
127
|
Chris@4
|
128 char *cpath = getenv(var.c_str());
|
Chris@4
|
129 if (cpath) path = cpath;
|
Chris@4
|
130
|
Chris@20
|
131 #ifdef _WIN32
|
Chris@20
|
132 bool is32 = is32bit();
|
Chris@20
|
133 #endif
|
Chris@20
|
134
|
Chris@4
|
135 if (path == "") {
|
Chris@4
|
136
|
Chris@4
|
137 path = getDefaultPath(type);
|
Chris@4
|
138
|
Chris@19
|
139 if (path != "") {
|
Chris@4
|
140
|
Chris@19
|
141 char *home = getenv("HOME");
|
Chris@19
|
142 if (home) {
|
Chris@19
|
143 string::size_type f;
|
Chris@19
|
144 while ((f = path.find("$HOME")) != string::npos &&
|
Chris@19
|
145 f < path.length()) {
|
Chris@19
|
146 path.replace(f, 5, home);
|
Chris@19
|
147 }
|
Chris@19
|
148 }
|
Chris@4
|
149
|
Chris@4
|
150 #ifdef _WIN32
|
Chris@20
|
151 const char *pfiles = 0;
|
Chris@20
|
152 if (is32) {
|
Chris@20
|
153 pfiles = getenv("ProgramFiles(x86)");
|
Chris@20
|
154 }
|
Chris@20
|
155 if (!pfiles) {
|
Chris@20
|
156 pfiles = getenv("ProgramFiles");
|
Chris@20
|
157 }
|
Chris@20
|
158 if (!pfiles) {
|
Chris@20
|
159 if (is32) {
|
Chris@20
|
160 pfiles = "C:\\Program Files (x86)";
|
Chris@20
|
161 } else {
|
Chris@20
|
162 pfiles = "C:\\Program Files";
|
Chris@19
|
163 }
|
Chris@19
|
164 }
|
Chris@20
|
165 string::size_type f;
|
Chris@20
|
166 while ((f = path.find("%ProgramFiles%")) != string::npos &&
|
Chris@20
|
167 f < path.length()) {
|
Chris@20
|
168 path.replace(f, 14, pfiles);
|
Chris@20
|
169 }
|
Chris@4
|
170 #endif
|
Chris@19
|
171 }
|
Chris@4
|
172 }
|
Chris@4
|
173
|
Chris@4
|
174 string::size_type index = 0, newindex = 0;
|
Chris@4
|
175
|
Chris@4
|
176 while ((newindex = path.find(PATH_SEPARATOR, index)) < path.size()) {
|
Chris@19
|
177 pathList.push_back(path.substr(index, newindex - index).c_str());
|
Chris@19
|
178 index = newindex + 1;
|
Chris@4
|
179 }
|
Chris@4
|
180
|
Chris@4
|
181 pathList.push_back(path.substr(index));
|
Chris@4
|
182
|
Chris@4
|
183 return pathList;
|
Chris@4
|
184 }
|
Chris@4
|
185
|
Chris@4
|
186 string
|
Chris@4
|
187 KnownPlugins::getFailureReport() const
|
Chris@4
|
188 {
|
Chris@4
|
189 vector<PluginCandidates::FailureRec> failures;
|
Chris@4
|
190
|
Chris@4
|
191 for (auto t: getKnownPluginTypes()) {
|
Chris@19
|
192 auto ff = m_candidates.getFailedLibrariesFor(getTagFor(t));
|
Chris@19
|
193 failures.insert(failures.end(), ff.begin(), ff.end());
|
Chris@4
|
194 }
|
Chris@4
|
195
|
Chris@4
|
196 if (failures.empty()) return "";
|
Chris@4
|
197
|
Chris@15
|
198 int n = int(failures.size());
|
Chris@4
|
199 int i = 0;
|
Chris@4
|
200
|
Chris@4
|
201 ostringstream os;
|
Chris@4
|
202
|
Chris@4
|
203 os << "<ul>";
|
Chris@4
|
204 for (auto f: failures) {
|
Chris@19
|
205 os << "<li>" + f.library;
|
Chris@19
|
206 if (f.message != "") {
|
Chris@19
|
207 os << "<br><i>" + f.message + "</i>";
|
Chris@19
|
208 } else {
|
Chris@19
|
209 os << "<br><i>unknown error</i>";
|
Chris@19
|
210 }
|
Chris@19
|
211 os << "</li>";
|
Chris@4
|
212
|
Chris@19
|
213 if (n > 10) {
|
Chris@19
|
214 if (++i == 5) {
|
Chris@19
|
215 os << "<li>(... and " << (n - i) << " further failures)</li>";
|
Chris@19
|
216 break;
|
Chris@19
|
217 }
|
Chris@19
|
218 }
|
Chris@4
|
219 }
|
Chris@4
|
220 os << "</ul>";
|
Chris@4
|
221
|
Chris@4
|
222 return os.str();
|
Chris@4
|
223 }
|