Mercurial > hg > svcore
comparison plugin/LADSPAPluginFactory.cpp @ 0:da6937383da8
initial import
author | Chris Cannam |
---|---|
date | Tue, 10 Jan 2006 16:33:16 +0000 |
parents | |
children | d86891498eef |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:da6937383da8 |
---|---|
1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 A waveform viewer and audio annotation editor. | |
5 Chris Cannam, Queen Mary University of London, 2005 | |
6 | |
7 This is experimental software. Not for distribution. | |
8 */ | |
9 | |
10 /* | |
11 This is a modified version of a source file from the | |
12 Rosegarden MIDI and audio sequencer and notation editor. | |
13 This file copyright 2000-2005 Chris Cannam and Richard Bown. | |
14 */ | |
15 | |
16 #include "LADSPAPluginFactory.h" | |
17 #include <iostream> | |
18 | |
19 #include <QDir> | |
20 #include <QFile> | |
21 #include <QTextStream> | |
22 | |
23 #include <cmath> | |
24 | |
25 #include "LADSPAPluginInstance.h" | |
26 #include "PluginIdentifier.h" | |
27 | |
28 #include "base/System.h" | |
29 | |
30 #ifdef HAVE_LIBLRDF | |
31 #include "lrdf.h" | |
32 #endif // HAVE_LIBLRDF | |
33 | |
34 | |
35 LADSPAPluginFactory::LADSPAPluginFactory() | |
36 { | |
37 } | |
38 | |
39 LADSPAPluginFactory::~LADSPAPluginFactory() | |
40 { | |
41 for (std::set<RealTimePluginInstance *>::iterator i = m_instances.begin(); | |
42 i != m_instances.end(); ++i) { | |
43 (*i)->setFactory(0); | |
44 delete *i; | |
45 } | |
46 m_instances.clear(); | |
47 unloadUnusedLibraries(); | |
48 } | |
49 | |
50 const std::vector<QString> & | |
51 LADSPAPluginFactory::getPluginIdentifiers() const | |
52 { | |
53 return m_identifiers; | |
54 } | |
55 | |
56 void | |
57 LADSPAPluginFactory::enumeratePlugins(std::vector<QString> &list) | |
58 { | |
59 for (std::vector<QString>::iterator i = m_identifiers.begin(); | |
60 i != m_identifiers.end(); ++i) { | |
61 | |
62 const LADSPA_Descriptor *descriptor = getLADSPADescriptor(*i); | |
63 | |
64 if (!descriptor) { | |
65 std::cerr << "WARNING: LADSPAPluginFactory::enumeratePlugins: couldn't get descriptor for identifier " << i->toStdString() << std::endl; | |
66 continue; | |
67 } | |
68 | |
69 list.push_back(*i); | |
70 list.push_back(descriptor->Name); | |
71 list.push_back(QString("%1").arg(descriptor->UniqueID)); | |
72 list.push_back(descriptor->Label); | |
73 list.push_back(descriptor->Maker); | |
74 list.push_back(descriptor->Copyright); | |
75 list.push_back("false"); // is synth | |
76 list.push_back("false"); // is grouped | |
77 | |
78 if (m_taxonomy.find(descriptor->UniqueID) != m_taxonomy.end() && | |
79 m_taxonomy[descriptor->UniqueID] != "") { | |
80 // std::cerr << "LADSPAPluginFactory: cat for " << i->toStdString()<< " found in taxonomy as " << m_taxonomy[descriptor->UniqueID] << std::endl; | |
81 list.push_back(m_taxonomy[descriptor->UniqueID]); | |
82 | |
83 } else if (m_fallbackCategories.find(*i) != | |
84 m_fallbackCategories.end()) { | |
85 list.push_back(m_fallbackCategories[*i]); | |
86 // std::cerr << "LADSPAPluginFactory: cat for " << i->toStdString() <<" found in fallbacks as " << m_fallbackCategories[*i] << std::endl; | |
87 | |
88 } else { | |
89 list.push_back(""); | |
90 // std::cerr << "LADSPAPluginFactory: cat for " << i->toStdString() << " not found (despite having " << m_fallbackCategories.size() << " fallbacks)" << std::endl; | |
91 | |
92 } | |
93 | |
94 list.push_back(QString("%1").arg(descriptor->PortCount)); | |
95 | |
96 for (unsigned long p = 0; p < descriptor->PortCount; ++p) { | |
97 | |
98 int type = 0; | |
99 if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[p])) { | |
100 type |= PortType::Control; | |
101 } else { | |
102 type |= PortType::Audio; | |
103 } | |
104 if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[p])) { | |
105 type |= PortType::Input; | |
106 } else { | |
107 type |= PortType::Output; | |
108 } | |
109 | |
110 list.push_back(QString("%1").arg(p)); | |
111 list.push_back(descriptor->PortNames[p]); | |
112 list.push_back(QString("%1").arg(type)); | |
113 list.push_back(QString("%1").arg(getPortDisplayHint(descriptor, p))); | |
114 list.push_back(QString("%1").arg(getPortMinimum(descriptor, p))); | |
115 list.push_back(QString("%1").arg(getPortMaximum(descriptor, p))); | |
116 list.push_back(QString("%1").arg(getPortDefault(descriptor, p))); | |
117 } | |
118 } | |
119 | |
120 unloadUnusedLibraries(); | |
121 } | |
122 | |
123 float | |
124 LADSPAPluginFactory::getPortMinimum(const LADSPA_Descriptor *descriptor, int port) | |
125 { | |
126 LADSPA_PortRangeHintDescriptor d = | |
127 descriptor->PortRangeHints[port].HintDescriptor; | |
128 | |
129 float minimum = 0.0; | |
130 | |
131 if (LADSPA_IS_HINT_BOUNDED_BELOW(d)) { | |
132 float lb = descriptor->PortRangeHints[port].LowerBound; | |
133 minimum = lb; | |
134 } else if (LADSPA_IS_HINT_BOUNDED_ABOVE(d)) { | |
135 float ub = descriptor->PortRangeHints[port].UpperBound; | |
136 minimum = std::min(0.0, ub - 1.0); | |
137 } | |
138 | |
139 if (LADSPA_IS_HINT_SAMPLE_RATE(d)) { | |
140 minimum *= m_sampleRate; | |
141 } | |
142 | |
143 return minimum; | |
144 } | |
145 | |
146 float | |
147 LADSPAPluginFactory::getPortMaximum(const LADSPA_Descriptor *descriptor, int port) | |
148 { | |
149 LADSPA_PortRangeHintDescriptor d = | |
150 descriptor->PortRangeHints[port].HintDescriptor; | |
151 | |
152 float maximum = 1.0; | |
153 | |
154 if (LADSPA_IS_HINT_BOUNDED_ABOVE(d)) { | |
155 float ub = descriptor->PortRangeHints[port].UpperBound; | |
156 maximum = ub; | |
157 } else { | |
158 float lb = descriptor->PortRangeHints[port].LowerBound; | |
159 maximum = lb + 1.0; | |
160 } | |
161 | |
162 if (LADSPA_IS_HINT_SAMPLE_RATE(d)) { | |
163 maximum *= m_sampleRate; | |
164 } | |
165 | |
166 return maximum; | |
167 } | |
168 | |
169 float | |
170 LADSPAPluginFactory::getPortDefault(const LADSPA_Descriptor *descriptor, int port) | |
171 { | |
172 float minimum = getPortMinimum(descriptor, port); | |
173 float maximum = getPortMaximum(descriptor, port); | |
174 float deft; | |
175 | |
176 if (m_portDefaults.find(descriptor->UniqueID) != | |
177 m_portDefaults.end()) { | |
178 if (m_portDefaults[descriptor->UniqueID].find(port) != | |
179 m_portDefaults[descriptor->UniqueID].end()) { | |
180 | |
181 deft = m_portDefaults[descriptor->UniqueID][port]; | |
182 if (deft < minimum) deft = minimum; | |
183 if (deft > maximum) deft = maximum; | |
184 return deft; | |
185 } | |
186 } | |
187 | |
188 LADSPA_PortRangeHintDescriptor d = | |
189 descriptor->PortRangeHints[port].HintDescriptor; | |
190 | |
191 bool logarithmic = LADSPA_IS_HINT_LOGARITHMIC(d); | |
192 | |
193 if (!LADSPA_IS_HINT_HAS_DEFAULT(d)) { | |
194 | |
195 deft = minimum; | |
196 | |
197 } else if (LADSPA_IS_HINT_DEFAULT_MINIMUM(d)) { | |
198 | |
199 deft = minimum; | |
200 | |
201 } else if (LADSPA_IS_HINT_DEFAULT_LOW(d)) { | |
202 | |
203 if (logarithmic) { | |
204 deft = powf(10, log10(minimum) * 0.75 + | |
205 log10(maximum) * 0.25); | |
206 } else { | |
207 deft = minimum * 0.75 + maximum * 0.25; | |
208 } | |
209 | |
210 } else if (LADSPA_IS_HINT_DEFAULT_MIDDLE(d)) { | |
211 | |
212 if (logarithmic) { | |
213 deft = powf(10, log10(minimum) * 0.5 + | |
214 log10(maximum) * 0.5); | |
215 } else { | |
216 deft = minimum * 0.5 + maximum * 0.5; | |
217 } | |
218 | |
219 } else if (LADSPA_IS_HINT_DEFAULT_HIGH(d)) { | |
220 | |
221 if (logarithmic) { | |
222 deft = powf(10, log10(minimum) * 0.25 + | |
223 log10(maximum) * 0.75); | |
224 } else { | |
225 deft = minimum * 0.25 + maximum * 0.75; | |
226 } | |
227 | |
228 } else if (LADSPA_IS_HINT_DEFAULT_MAXIMUM(d)) { | |
229 | |
230 deft = maximum; | |
231 | |
232 } else if (LADSPA_IS_HINT_DEFAULT_0(d)) { | |
233 | |
234 deft = 0.0; | |
235 | |
236 } else if (LADSPA_IS_HINT_DEFAULT_1(d)) { | |
237 | |
238 deft = 1.0; | |
239 | |
240 } else if (LADSPA_IS_HINT_DEFAULT_100(d)) { | |
241 | |
242 deft = 100.0; | |
243 | |
244 } else if (LADSPA_IS_HINT_DEFAULT_440(d)) { | |
245 | |
246 deft = 440.0; | |
247 | |
248 } else { | |
249 | |
250 deft = minimum; | |
251 } | |
252 | |
253 if (LADSPA_IS_HINT_SAMPLE_RATE(d)) { | |
254 deft *= m_sampleRate; | |
255 } | |
256 | |
257 return deft; | |
258 } | |
259 | |
260 int | |
261 LADSPAPluginFactory::getPortDisplayHint(const LADSPA_Descriptor *descriptor, int port) | |
262 { | |
263 LADSPA_PortRangeHintDescriptor d = | |
264 descriptor->PortRangeHints[port].HintDescriptor; | |
265 int hint = PortHint::NoHint; | |
266 | |
267 if (LADSPA_IS_HINT_TOGGLED(d)) hint |= PortHint::Toggled; | |
268 if (LADSPA_IS_HINT_INTEGER(d)) hint |= PortHint::Integer; | |
269 if (LADSPA_IS_HINT_LOGARITHMIC(d)) hint |= PortHint::Logarithmic; | |
270 | |
271 return hint; | |
272 } | |
273 | |
274 | |
275 RealTimePluginInstance * | |
276 LADSPAPluginFactory::instantiatePlugin(QString identifier, | |
277 int instrument, | |
278 int position, | |
279 unsigned int sampleRate, | |
280 unsigned int blockSize, | |
281 unsigned int channels) | |
282 { | |
283 const LADSPA_Descriptor *descriptor = getLADSPADescriptor(identifier); | |
284 | |
285 if (descriptor) { | |
286 | |
287 LADSPAPluginInstance *instance = | |
288 new LADSPAPluginInstance | |
289 (this, instrument, identifier, position, sampleRate, blockSize, channels, | |
290 descriptor); | |
291 | |
292 m_instances.insert(instance); | |
293 | |
294 return instance; | |
295 } | |
296 | |
297 return 0; | |
298 } | |
299 | |
300 void | |
301 LADSPAPluginFactory::releasePlugin(RealTimePluginInstance *instance, | |
302 QString identifier) | |
303 { | |
304 if (m_instances.find(instance) == m_instances.end()) { | |
305 std::cerr << "WARNING: LADSPAPluginFactory::releasePlugin: Not one of mine!" | |
306 << std::endl; | |
307 return; | |
308 } | |
309 | |
310 QString type, soname, label; | |
311 PluginIdentifier::parseIdentifier(identifier, type, soname, label); | |
312 | |
313 m_instances.erase(instance); | |
314 | |
315 bool stillInUse = false; | |
316 | |
317 for (std::set<RealTimePluginInstance *>::iterator ii = m_instances.begin(); | |
318 ii != m_instances.end(); ++ii) { | |
319 QString itype, isoname, ilabel; | |
320 PluginIdentifier::parseIdentifier((*ii)->getIdentifier(), itype, isoname, ilabel); | |
321 if (isoname == soname) { | |
322 // std::cerr << "LADSPAPluginFactory::releasePlugin: dll " << soname.toStdString() << " is still in use for plugin " << ilabel << std::endl; | |
323 stillInUse = true; | |
324 break; | |
325 } | |
326 } | |
327 | |
328 if (!stillInUse) { | |
329 // std::cerr << "LADSPAPluginFactory::releasePlugin: dll " << soname.toStdString() << " no longer in use, unloading" << std::endl; | |
330 unloadLibrary(soname); | |
331 } | |
332 } | |
333 | |
334 const LADSPA_Descriptor * | |
335 LADSPAPluginFactory::getLADSPADescriptor(QString identifier) | |
336 { | |
337 QString type, soname, label; | |
338 PluginIdentifier::parseIdentifier(identifier, type, soname, label); | |
339 | |
340 if (m_libraryHandles.find(soname) == m_libraryHandles.end()) { | |
341 loadLibrary(soname); | |
342 if (m_libraryHandles.find(soname) == m_libraryHandles.end()) { | |
343 std::cerr << "WARNING: LADSPAPluginFactory::getLADSPADescriptor: loadLibrary failed for " << soname.toStdString() << std::endl; | |
344 return 0; | |
345 } | |
346 } | |
347 | |
348 void *libraryHandle = m_libraryHandles[soname]; | |
349 | |
350 LADSPA_Descriptor_Function fn = (LADSPA_Descriptor_Function) | |
351 DLSYM(libraryHandle, "ladspa_descriptor"); | |
352 | |
353 if (!fn) { | |
354 std::cerr << "WARNING: LADSPAPluginFactory::getLADSPADescriptor: No descriptor function in library " << soname.toStdString() << std::endl; | |
355 return 0; | |
356 } | |
357 | |
358 const LADSPA_Descriptor *descriptor = 0; | |
359 | |
360 int index = 0; | |
361 while ((descriptor = fn(index))) { | |
362 if (descriptor->Label == label) return descriptor; | |
363 ++index; | |
364 } | |
365 | |
366 std::cerr << "WARNING: LADSPAPluginFactory::getLADSPADescriptor: No such plugin as " << label.toStdString() << " in library " << soname.toStdString() << std::endl; | |
367 | |
368 return 0; | |
369 } | |
370 | |
371 void | |
372 LADSPAPluginFactory::loadLibrary(QString soName) | |
373 { | |
374 void *libraryHandle = DLOPEN(soName, RTLD_NOW); | |
375 if (libraryHandle) m_libraryHandles[soName] = libraryHandle; | |
376 } | |
377 | |
378 void | |
379 LADSPAPluginFactory::unloadLibrary(QString soName) | |
380 { | |
381 LibraryHandleMap::iterator li = m_libraryHandles.find(soName); | |
382 if (li != m_libraryHandles.end()) { | |
383 // std::cerr << "unloading " << soname.toStdString() << std::endl; | |
384 DLCLOSE(m_libraryHandles[soName]); | |
385 m_libraryHandles.erase(li); | |
386 } | |
387 } | |
388 | |
389 void | |
390 LADSPAPluginFactory::unloadUnusedLibraries() | |
391 { | |
392 std::vector<QString> toUnload; | |
393 | |
394 for (LibraryHandleMap::iterator i = m_libraryHandles.begin(); | |
395 i != m_libraryHandles.end(); ++i) { | |
396 | |
397 bool stillInUse = false; | |
398 | |
399 for (std::set<RealTimePluginInstance *>::iterator ii = m_instances.begin(); | |
400 ii != m_instances.end(); ++ii) { | |
401 | |
402 QString itype, isoname, ilabel; | |
403 PluginIdentifier::parseIdentifier((*ii)->getIdentifier(), itype, isoname, ilabel); | |
404 if (isoname == i->first) { | |
405 stillInUse = true; | |
406 break; | |
407 } | |
408 } | |
409 | |
410 if (!stillInUse) toUnload.push_back(i->first); | |
411 } | |
412 | |
413 for (std::vector<QString>::iterator i = toUnload.begin(); | |
414 i != toUnload.end(); ++i) { | |
415 unloadLibrary(*i); | |
416 } | |
417 } | |
418 | |
419 | |
420 // It is only later, after they've gone, | |
421 // I realize they have delivered a letter. | |
422 // It's a letter from my wife. "What are you doing | |
423 // there?" my wife asks. "Are you drinking?" | |
424 // I study the postmark for hours. Then it, too, begins to fade. | |
425 // I hope someday to forget all this. | |
426 | |
427 | |
428 std::vector<QString> | |
429 LADSPAPluginFactory::getPluginPath() | |
430 { | |
431 std::vector<QString> pathList; | |
432 std::string path; | |
433 | |
434 char *cpath = getenv("LADSPA_PATH"); | |
435 if (cpath) path = cpath; | |
436 | |
437 if (path == "") { | |
438 path = "/usr/local/lib/ladspa:/usr/lib/ladspa"; | |
439 char *home = getenv("HOME"); | |
440 if (home) path = std::string(home) + "/.ladspa:" + path; | |
441 } | |
442 | |
443 std::string::size_type index = 0, newindex = 0; | |
444 | |
445 while ((newindex = path.find(':', index)) < path.size()) { | |
446 pathList.push_back(path.substr(index, newindex - index).c_str()); | |
447 index = newindex + 1; | |
448 } | |
449 | |
450 pathList.push_back(path.substr(index).c_str()); | |
451 | |
452 return pathList; | |
453 } | |
454 | |
455 | |
456 #ifdef HAVE_LIBLRDF | |
457 std::vector<QString> | |
458 LADSPAPluginFactory::getLRDFPath(QString &baseUri) | |
459 { | |
460 std::vector<QString> pathList = getPluginPath(); | |
461 std::vector<QString> lrdfPaths; | |
462 | |
463 lrdfPaths.push_back("/usr/local/share/ladspa/rdf"); | |
464 lrdfPaths.push_back("/usr/share/ladspa/rdf"); | |
465 | |
466 for (std::vector<QString>::iterator i = pathList.begin(); | |
467 i != pathList.end(); ++i) { | |
468 lrdfPaths.push_back(*i + "/rdf"); | |
469 } | |
470 | |
471 baseUri = LADSPA_BASE; | |
472 return lrdfPaths; | |
473 } | |
474 #endif | |
475 | |
476 void | |
477 LADSPAPluginFactory::discoverPlugins() | |
478 { | |
479 std::vector<QString> pathList = getPluginPath(); | |
480 | |
481 // std::cerr << "LADSPAPluginFactory::discoverPlugins - " | |
482 // << "discovering plugins; path is "; | |
483 for (std::vector<QString>::iterator i = pathList.begin(); | |
484 i != pathList.end(); ++i) { | |
485 std::cerr << "[" << i->toStdString() << "] "; | |
486 } | |
487 std::cerr << std::endl; | |
488 | |
489 #ifdef HAVE_LIBLRDF | |
490 // Initialise liblrdf and read the description files | |
491 // | |
492 lrdf_init(); | |
493 | |
494 QString baseUri; | |
495 std::vector<QString> lrdfPaths = getLRDFPath(baseUri); | |
496 | |
497 bool haveSomething = false; | |
498 | |
499 for (size_t i = 0; i < lrdfPaths.size(); ++i) { | |
500 QDir dir(lrdfPaths[i], "*.rdf;*.rdfs"); | |
501 for (unsigned int j = 0; j < dir.count(); ++j) { | |
502 if (!lrdf_read_file(QString("file:" + lrdfPaths[i] + "/" + dir[j]).toStdString().c_str())) { | |
503 // std::cerr << "LADSPAPluginFactory: read RDF file " << (lrdfPaths[i] + "/" + dir[j]) << std::endl; | |
504 haveSomething = true; | |
505 } | |
506 } | |
507 } | |
508 | |
509 if (haveSomething) { | |
510 generateTaxonomy(baseUri + "Plugin", ""); | |
511 } | |
512 #endif // HAVE_LIBLRDF | |
513 | |
514 generateFallbackCategories(); | |
515 | |
516 for (std::vector<QString>::iterator i = pathList.begin(); | |
517 i != pathList.end(); ++i) { | |
518 | |
519 QDir pluginDir(*i, PLUGIN_GLOB); | |
520 | |
521 for (unsigned int j = 0; j < pluginDir.count(); ++j) { | |
522 discoverPlugins(QString("%1/%2").arg(*i).arg(pluginDir[j])); | |
523 } | |
524 } | |
525 | |
526 #ifdef HAVE_LIBLRDF | |
527 // Cleanup after the RDF library | |
528 // | |
529 lrdf_cleanup(); | |
530 #endif // HAVE_LIBLRDF | |
531 } | |
532 | |
533 void | |
534 LADSPAPluginFactory::discoverPlugins(QString soname) | |
535 { | |
536 void *libraryHandle = DLOPEN(soname, RTLD_LAZY); | |
537 | |
538 if (!libraryHandle) { | |
539 std::cerr << "WARNING: LADSPAPluginFactory::discoverPlugins: couldn't load plugin library " | |
540 << soname.toStdString() << " - " << DLERROR() << std::endl; | |
541 return; | |
542 } | |
543 | |
544 LADSPA_Descriptor_Function fn = (LADSPA_Descriptor_Function) | |
545 DLSYM(libraryHandle, "ladspa_descriptor"); | |
546 | |
547 if (!fn) { | |
548 std::cerr << "WARNING: LADSPAPluginFactory::discoverPlugins: No descriptor function in " << soname.toStdString() << std::endl; | |
549 return; | |
550 } | |
551 | |
552 const LADSPA_Descriptor *descriptor = 0; | |
553 | |
554 int index = 0; | |
555 while ((descriptor = fn(index))) { | |
556 | |
557 #ifdef HAVE_LIBLRDF | |
558 char *def_uri = 0; | |
559 lrdf_defaults *defs = 0; | |
560 | |
561 QString category = m_taxonomy[descriptor->UniqueID]; | |
562 | |
563 if (category == "" && descriptor->Name != 0) { | |
564 std::string name = descriptor->Name; | |
565 if (name.length() > 4 && | |
566 name.substr(name.length() - 4) == " VST") { | |
567 category = "VST effects"; | |
568 m_taxonomy[descriptor->UniqueID] = category; | |
569 } | |
570 } | |
571 | |
572 // std::cerr << "Plugin id is " << descriptor->UniqueID | |
573 // << ", category is \"" << (category ? category : QString("(none)")) | |
574 // << "\", name is " << descriptor->Name | |
575 // << ", label is " << descriptor->Label | |
576 // << std::endl; | |
577 | |
578 def_uri = lrdf_get_default_uri(descriptor->UniqueID); | |
579 if (def_uri) { | |
580 defs = lrdf_get_setting_values(def_uri); | |
581 } | |
582 | |
583 int controlPortNumber = 1; | |
584 | |
585 for (unsigned long i = 0; i < descriptor->PortCount; i++) { | |
586 | |
587 if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[i])) { | |
588 | |
589 if (def_uri && defs) { | |
590 | |
591 for (int j = 0; j < defs->count; j++) { | |
592 if (defs->items[j].pid == controlPortNumber) { | |
593 // std::cerr << "Default for this port (" << defs->items[j].pid << ", " << defs->items[j].label << ") is " << defs->items[j].value << "; applying this to port number " << i << " with name " << descriptor->PortNames[i] << std::endl; | |
594 m_portDefaults[descriptor->UniqueID][i] = | |
595 defs->items[j].value; | |
596 } | |
597 } | |
598 } | |
599 | |
600 ++controlPortNumber; | |
601 } | |
602 } | |
603 #endif // HAVE_LIBLRDF | |
604 | |
605 QString identifier = PluginIdentifier::createIdentifier | |
606 ("ladspa", soname, descriptor->Label); | |
607 m_identifiers.push_back(identifier); | |
608 | |
609 ++index; | |
610 } | |
611 | |
612 if (DLCLOSE(libraryHandle) != 0) { | |
613 std::cerr << "WARNING: LADSPAPluginFactory::discoverPlugins - can't unload " << libraryHandle << std::endl; | |
614 return; | |
615 } | |
616 } | |
617 | |
618 void | |
619 LADSPAPluginFactory::generateFallbackCategories() | |
620 { | |
621 std::vector<QString> pluginPath = getPluginPath(); | |
622 std::vector<QString> path; | |
623 | |
624 for (size_t i = 0; i < pluginPath.size(); ++i) { | |
625 if (pluginPath[i].contains("/lib/")) { | |
626 QString p(pluginPath[i]); | |
627 p.replace("/lib/", "/share/"); | |
628 path.push_back(p); | |
629 // std::cerr << "LADSPAPluginFactory::generateFallbackCategories: path element " << p << std::endl; | |
630 } | |
631 path.push_back(pluginPath[i]); | |
632 // std::cerr << "LADSPAPluginFactory::generateFallbackCategories: path element " << pluginPath[i] << std::endl; | |
633 } | |
634 | |
635 for (size_t i = 0; i < path.size(); ++i) { | |
636 | |
637 QDir dir(path[i], "*.cat"); | |
638 | |
639 // std::cerr << "LADSPAPluginFactory::generateFallbackCategories: directory " << path[i] << " has " << dir.count() << " .cat files" << std::endl; | |
640 for (unsigned int j = 0; j < dir.count(); ++j) { | |
641 | |
642 QFile file(path[i] + "/" + dir[j]); | |
643 | |
644 // std::cerr << "LADSPAPluginFactory::generateFallbackCategories: about to open " << (path[i] + "/" + dir[j]) << std::endl; | |
645 | |
646 if (file.open(QIODevice::ReadOnly)) { | |
647 // std::cerr << "...opened" << std::endl; | |
648 QTextStream stream(&file); | |
649 QString line; | |
650 | |
651 while (!stream.atEnd()) { | |
652 line = stream.readLine(); | |
653 // std::cerr << "line is: \"" << line << "\"" << std::endl; | |
654 QString id = line.section("::", 0, 0); | |
655 QString cat = line.section("::", 1, 1); | |
656 m_fallbackCategories[id] = cat; | |
657 // std::cerr << "set id \"" << id << "\" to cat \"" << cat << "\"" << std::endl; | |
658 } | |
659 } | |
660 } | |
661 } | |
662 } | |
663 | |
664 void | |
665 LADSPAPluginFactory::generateTaxonomy(QString uri, QString base) | |
666 { | |
667 #ifdef HAVE_LIBLRDF | |
668 lrdf_uris *uris = lrdf_get_instances(uri.toStdString().c_str()); | |
669 | |
670 if (uris != NULL) { | |
671 for (int i = 0; i < uris->count; ++i) { | |
672 m_taxonomy[lrdf_get_uid(uris->items[i])] = base; | |
673 } | |
674 lrdf_free_uris(uris); | |
675 } | |
676 | |
677 uris = lrdf_get_subclasses(uri.toStdString().c_str()); | |
678 | |
679 if (uris != NULL) { | |
680 for (int i = 0; i < uris->count; ++i) { | |
681 char *label = lrdf_get_label(uris->items[i]); | |
682 generateTaxonomy(uris->items[i], | |
683 base + (base.length() > 0 ? " > " : "") + label); | |
684 } | |
685 lrdf_free_uris(uris); | |
686 } | |
687 #endif | |
688 } | |
689 | |
690 |