comparison plugin/LADSPAPluginFactory.cpp @ 1830:5f8fbbde08ff audio-source-refactor

Use shared_ptr for plugin instances throughout
author Chris Cannam
date Fri, 20 Mar 2020 16:30:33 +0000
parents 70e172e6cc59
children 1adbeb52d761
comparison
equal deleted inserted replaced
1829:51fd27fbce9a 1830:5f8fbbde08ff
49 #endif 49 #endif
50 } 50 }
51 51
52 LADSPAPluginFactory::~LADSPAPluginFactory() 52 LADSPAPluginFactory::~LADSPAPluginFactory()
53 { 53 {
54 for (std::set<RealTimePluginInstance *>::iterator i = m_instances.begin();
55 i != m_instances.end(); ++i) {
56 (*i)->setFactory(nullptr);
57 delete *i;
58 }
59 m_instances.clear();
60 unloadUnusedLibraries(); 54 unloadUnusedLibraries();
61 55
62 #ifdef HAVE_LRDF 56 #ifdef HAVE_LRDF
63 lrdf_cleanup(); 57 lrdf_cleanup();
64 #endif // HAVE_LRDF 58 #endif // HAVE_LRDF
136 } 130 }
137 131
138 unloadUnusedLibraries(); 132 unloadUnusedLibraries();
139 } 133 }
140 134
141 const RealTimePluginDescriptor * 135 RealTimePluginDescriptor
142 LADSPAPluginFactory::getPluginDescriptor(QString identifier) const 136 LADSPAPluginFactory::getPluginDescriptor(QString identifier) const
143 { 137 {
144 std::map<QString, RealTimePluginDescriptor *>::const_iterator i = 138 std::map<QString, RealTimePluginDescriptor>::const_iterator i =
145 m_rtDescriptors.find(identifier); 139 m_rtDescriptors.find(identifier);
146 140
147 if (i != m_rtDescriptors.end()) { 141 if (i != m_rtDescriptors.end()) {
148 return i->second; 142 return i->second;
149 } 143 }
150 144
151 return nullptr; 145 return {};
152 } 146 }
153 147
154 float 148 float
155 LADSPAPluginFactory::getPortMinimum(const LADSPA_Descriptor *descriptor, int port) 149 LADSPAPluginFactory::getPortMinimum(const LADSPA_Descriptor *descriptor, int port)
156 { 150 {
332 326
333 return hint; 327 return hint;
334 } 328 }
335 329
336 330
337 RealTimePluginInstance * 331 std::shared_ptr<RealTimePluginInstance>
338 LADSPAPluginFactory::instantiatePlugin(QString identifier, 332 LADSPAPluginFactory::instantiatePlugin(QString identifier,
339 int instrument, 333 int instrument,
340 int position, 334 int position,
341 sv_samplerate_t sampleRate, 335 sv_samplerate_t sampleRate,
342 int blockSize, 336 int blockSize,
346 340
347 const LADSPA_Descriptor *descriptor = getLADSPADescriptor(identifier); 341 const LADSPA_Descriptor *descriptor = getLADSPADescriptor(identifier);
348 342
349 if (descriptor) { 343 if (descriptor) {
350 344
351 LADSPAPluginInstance *instance = 345 auto instance =
352 new LADSPAPluginInstance 346 std::shared_ptr<RealTimePluginInstance>
353 (this, instrument, identifier, position, sampleRate, blockSize, channels, 347 (new LADSPAPluginInstance
354 descriptor); 348 (this, instrument, identifier, position,
349 sampleRate, blockSize, channels, descriptor));
355 350
356 m_instances.insert(instance); 351 m_instances.insert(instance);
357 352
358 #ifdef DEBUG_LADSPA_PLUGIN_FACTORY 353 #ifdef DEBUG_LADSPA_PLUGIN_FACTORY
359 SVDEBUG << "LADSPAPluginFactory::instantiatePlugin(" 354 SVDEBUG << "LADSPAPluginFactory::instantiatePlugin("
362 357
363 return instance; 358 return instance;
364 } 359 }
365 360
366 return nullptr; 361 return nullptr;
367 }
368
369 void
370 LADSPAPluginFactory::releasePlugin(RealTimePluginInstance *instance,
371 QString identifier)
372 {
373 Profiler profiler("LADSPAPluginFactory::releasePlugin");
374
375 if (m_instances.find(instance) == m_instances.end()) {
376 cerr << "WARNING: LADSPAPluginFactory::releasePlugin: Not one of mine!"
377 << endl;
378 return;
379 }
380
381 QString type, soname, label;
382 PluginIdentifier::parseIdentifier(identifier, type, soname, label);
383
384 m_instances.erase(instance);
385
386 bool stillInUse = false;
387
388 for (std::set<RealTimePluginInstance *>::iterator ii = m_instances.begin();
389 ii != m_instances.end(); ++ii) {
390 QString itype, isoname, ilabel;
391 PluginIdentifier::parseIdentifier((*ii)->getPluginIdentifier(), itype, isoname, ilabel);
392 if (isoname == soname) {
393 #ifdef DEBUG_LADSPA_PLUGIN_FACTORY
394 SVDEBUG << "LADSPAPluginFactory::releasePlugin: dll " << soname << " is still in use for plugin " << ilabel << endl;
395 #endif
396 stillInUse = true;
397 break;
398 }
399 }
400
401 if (!stillInUse) {
402 if (soname != PluginIdentifier::BUILTIN_PLUGIN_SONAME) {
403 #ifdef DEBUG_LADSPA_PLUGIN_FACTORY
404 SVDEBUG << "LADSPAPluginFactory::releasePlugin: dll " << soname << " no longer in use, unloading" << endl;
405 #endif
406 unloadLibrary(soname);
407 }
408 }
409
410 #ifdef DEBUG_LADSPA_PLUGIN_FACTORY
411 SVDEBUG << "LADSPAPluginFactory::releasePlugin("
412 << identifier << ": now have " << m_instances.size() << " instances" << endl;
413 #endif
414 } 362 }
415 363
416 const LADSPA_Descriptor * 364 const LADSPA_Descriptor *
417 LADSPAPluginFactory::getLADSPADescriptor(QString identifier) 365 LADSPAPluginFactory::getLADSPADescriptor(QString identifier)
418 { 366 {
523 } 471 }
524 472
525 void 473 void
526 LADSPAPluginFactory::unloadUnusedLibraries() 474 LADSPAPluginFactory::unloadUnusedLibraries()
527 { 475 {
476 std::set<std::weak_ptr<RealTimePluginInstance>,
477 std::owner_less<std::weak_ptr<RealTimePluginInstance>>> toRemove;
478
479 std::set<QString> soNamesInUse;
480
481 for (auto wp: m_instances) {
482 if (auto p = wp.lock()) {
483 QString itype, isoname, ilabel;
484 PluginIdentifier::parseIdentifier(p->getPluginIdentifier(),
485 itype, isoname, ilabel);
486 soNamesInUse.insert(isoname);
487 } else {
488 toRemove.insert(wp);
489 }
490 }
491
492 for (auto wp: toRemove) {
493 m_instances.erase(wp);
494 }
495
528 std::vector<QString> toUnload; 496 std::vector<QString> toUnload;
529 497
530 for (LibraryHandleMap::iterator i = m_libraryHandles.begin(); 498 for (auto i = m_libraryHandles.begin();
531 i != m_libraryHandles.end(); ++i) { 499 i != m_libraryHandles.end(); ++i) {
532 500
533 bool stillInUse = false; 501 if (soNamesInUse.find(i->first) == soNamesInUse.end()) {
534 502 toUnload.push_back(i->first);
535 for (std::set<RealTimePluginInstance *>::iterator ii = m_instances.begin(); 503 }
536 ii != m_instances.end(); ++ii) { 504 }
537 505
538 QString itype, isoname, ilabel; 506 for (auto soname: toUnload) {
539 PluginIdentifier::parseIdentifier((*ii)->getPluginIdentifier(), itype, isoname, ilabel); 507 if (soname != PluginIdentifier::BUILTIN_PLUGIN_SONAME) {
540 if (isoname == i->first) { 508 unloadLibrary(soname);
541 stillInUse = true;
542 break;
543 }
544 }
545
546 if (!stillInUse) toUnload.push_back(i->first);
547 }
548
549 for (std::vector<QString>::iterator i = toUnload.begin();
550 i != toUnload.end(); ++i) {
551 if (*i != PluginIdentifier::BUILTIN_PLUGIN_SONAME) {
552 unloadLibrary(*i);
553 } 509 }
554 } 510 }
555 } 511 }
556 512
557 513
705 const LADSPA_Descriptor *descriptor = nullptr; 661 const LADSPA_Descriptor *descriptor = nullptr;
706 662
707 int index = 0; 663 int index = 0;
708 while ((descriptor = fn(index))) { 664 while ((descriptor = fn(index))) {
709 665
710 RealTimePluginDescriptor *rtd = new RealTimePluginDescriptor; 666 RealTimePluginDescriptor rtd;
711 rtd->name = descriptor->Name; 667 rtd.name = descriptor->Name;
712 rtd->label = descriptor->Label; 668 rtd.label = descriptor->Label;
713 rtd->maker = descriptor->Maker; 669 rtd.maker = descriptor->Maker;
714 rtd->copyright = descriptor->Copyright; 670 rtd.copyright = descriptor->Copyright;
715 rtd->category = ""; 671 rtd.category = "";
716 rtd->isSynth = false; 672 rtd.isSynth = false;
717 rtd->parameterCount = 0; 673 rtd.parameterCount = 0;
718 rtd->audioInputPortCount = 0; 674 rtd.audioInputPortCount = 0;
719 rtd->audioOutputPortCount = 0; 675 rtd.audioOutputPortCount = 0;
720 rtd->controlOutputPortCount = 0; 676 rtd.controlOutputPortCount = 0;
721 677
722 QString identifier = PluginIdentifier::createIdentifier 678 QString identifier = PluginIdentifier::createIdentifier
723 ("ladspa", soname, descriptor->Label); 679 ("ladspa", soname, descriptor->Label);
724 680
725 #ifdef HAVE_LRDF 681 #ifdef HAVE_LRDF
733 } 689 }
734 690
735 QString category = m_taxonomy[identifier]; 691 QString category = m_taxonomy[identifier];
736 692
737 if (category == "") { 693 if (category == "") {
738 string name = rtd->name; 694 string name = rtd.name;
739 if (name.length() > 4 && 695 if (name.length() > 4 &&
740 name.substr(name.length() - 4) == " VST") { 696 name.substr(name.length() - 4) == " VST") {
741 category = "VST effects"; 697 category = "VST effects";
742 m_taxonomy[identifier] = category; 698 m_taxonomy[identifier] = category;
743 } 699 }
744 } 700 }
745 701
746 rtd->category = category.toStdString(); 702 rtd.category = category.toStdString();
747 703
748 // cerr << "Plugin id is " << descriptor->UniqueID 704 // cerr << "Plugin id is " << descriptor->UniqueID
749 // << ", category is \"" << (category ? category : QString("(none)")) 705 // << ", category is \"" << (category ? category : QString("(none)"))
750 // << "\", name is " << descriptor->Name 706 // << "\", name is " << descriptor->Name
751 // << ", label is " << descriptor->Label 707 // << ", label is " << descriptor->Label
779 #endif // HAVE_LRDF 735 #endif // HAVE_LRDF
780 736
781 for (int i = 0; i < (int)descriptor->PortCount; i++) { 737 for (int i = 0; i < (int)descriptor->PortCount; i++) {
782 if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[i])) { 738 if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[i])) {
783 if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[i])) { 739 if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[i])) {
784 ++rtd->parameterCount; 740 ++rtd.parameterCount;
785 } else { 741 } else {
786 if (strcmp(descriptor->PortNames[i], "latency") && 742 if (strcmp(descriptor->PortNames[i], "latency") &&
787 strcmp(descriptor->PortNames[i], "_latency")) { 743 strcmp(descriptor->PortNames[i], "_latency")) {
788 ++rtd->controlOutputPortCount; 744 ++rtd.controlOutputPortCount;
789 rtd->controlOutputPortNames.push_back 745 rtd.controlOutputPortNames.push_back
790 (descriptor->PortNames[i]); 746 (descriptor->PortNames[i]);
791 } 747 }
792 } 748 }
793 } else { 749 } else {
794 if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[i])) { 750 if (LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[i])) {
795 ++rtd->audioInputPortCount; 751 ++rtd.audioInputPortCount;
796 } else if (LADSPA_IS_PORT_OUTPUT(descriptor->PortDescriptors[i])) { 752 } else if (LADSPA_IS_PORT_OUTPUT(descriptor->PortDescriptors[i])) {
797 ++rtd->audioOutputPortCount; 753 ++rtd.audioOutputPortCount;
798 } 754 }
799 } 755 }
800 } 756 }
801 757
802 m_identifiers.push_back(identifier); 758 m_identifiers.push_back(identifier);