Mercurial > hg > svcore
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); |