comparison transform/TransformFactory.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 19fa7bf208d8
comparison
equal deleted inserted replaced
1829:51fd27fbce9a 1830:5f8fbbde08ff
511 if (!factory) { 511 if (!factory) {
512 cerr << "WARNING: TransformFactory::populateTransforms: No real time plugin factory for instance " << pluginId << endl; 512 cerr << "WARNING: TransformFactory::populateTransforms: No real time plugin factory for instance " << pluginId << endl;
513 continue; 513 continue;
514 } 514 }
515 515
516 const RealTimePluginDescriptor *descriptor = 516 RealTimePluginDescriptor descriptor =
517 factory->getPluginDescriptor(pluginId); 517 factory->getPluginDescriptor(pluginId);
518 518
519 if (!descriptor) { 519 if (descriptor.name == "") {
520 cerr << "WARNING: TransformFactory::populateTransforms: Failed to query plugin " << pluginId << endl; 520 cerr << "WARNING: TransformFactory::populateTransforms: Failed to query plugin " << pluginId << endl;
521 continue; 521 continue;
522 } 522 }
523 523
524 //!!! if (descriptor->controlOutputPortCount == 0 || 524 //!!! if (descriptor.controlOutputPortCount == 0 ||
525 // descriptor->audioInputPortCount == 0) continue; 525 // descriptor.audioInputPortCount == 0) continue;
526 526
527 // cout << "TransformFactory::populateRealTimePlugins: plugin " << pluginId << " has " << descriptor->controlOutputPortCount << " control output ports, " << descriptor->audioOutputPortCount << " audio outputs, " << descriptor->audioInputPortCount << " audio inputs" << endl; 527 // cout << "TransformFactory::populateRealTimePlugins: plugin " << pluginId << " has " << descriptor.controlOutputPortCount << " control output ports, " << descriptor.audioOutputPortCount << " audio outputs, " << descriptor.audioInputPortCount << " audio inputs" << endl;
528 528
529 QString pluginName = descriptor->name.c_str(); 529 QString pluginName = descriptor.name.c_str();
530 QString category = factory->getPluginCategory(pluginId); 530 QString category = factory->getPluginCategory(pluginId);
531 bool configurable = (descriptor->parameterCount > 0); 531 bool configurable = (descriptor.parameterCount > 0);
532 QString maker = descriptor->maker.c_str(); 532 QString maker = descriptor.maker.c_str();
533 if (maker == "") maker = tr("<unknown maker>"); 533 if (maker == "") maker = tr("<unknown maker>");
534 534
535 if (descriptor->audioInputPortCount > 0) { 535 if (descriptor.audioInputPortCount > 0) {
536 536
537 for (int j = 0; j < (int)descriptor->controlOutputPortCount; ++j) { 537 for (int j = 0; j < (int)descriptor.controlOutputPortCount; ++j) {
538 538
539 QString transformId = QString("%1:%2").arg(pluginId).arg(j); 539 QString transformId = QString("%1:%2").arg(pluginId).arg(j);
540 QString userName; 540 QString userName;
541 QString units; 541 QString units;
542 QString portName; 542 QString portName;
543 543
544 if (j < (int)descriptor->controlOutputPortNames.size() && 544 if (j < (int)descriptor.controlOutputPortNames.size() &&
545 descriptor->controlOutputPortNames[j] != "") { 545 descriptor.controlOutputPortNames[j] != "") {
546 546
547 portName = descriptor->controlOutputPortNames[j].c_str(); 547 portName = descriptor.controlOutputPortNames[j].c_str();
548 548
549 userName = tr("%1: %2") 549 userName = tr("%1: %2")
550 .arg(pluginName) 550 .arg(pluginName)
551 .arg(portName); 551 .arg(portName);
552 552
553 if (unitRE.indexIn(portName) >= 0) { 553 if (unitRE.indexIn(portName) >= 0) {
554 units = unitRE.cap(1); 554 units = unitRE.cap(1);
555 } 555 }
556 556
557 } else if (descriptor->controlOutputPortCount > 1) { 557 } else if (descriptor.controlOutputPortCount > 1) {
558 558
559 userName = tr("%1: Output %2") 559 userName = tr("%1: Output %2")
560 .arg(pluginName) 560 .arg(pluginName)
561 .arg(j + 1); 561 .arg(j + 1);
562 562
591 units, 591 units,
592 configurable); 592 configurable);
593 } 593 }
594 } 594 }
595 595
596 if (!descriptor->isSynth || descriptor->audioInputPortCount > 0) { 596 if (!descriptor.isSynth || descriptor.audioInputPortCount > 0) {
597 597
598 if (descriptor->audioOutputPortCount > 0) { 598 if (descriptor.audioOutputPortCount > 0) {
599 599
600 QString transformId = QString("%1:A").arg(pluginId); 600 QString transformId = QString("%1:A").arg(pluginId);
601 TransformDescription::Type type = TransformDescription::Effects; 601 TransformDescription::Type type = TransformDescription::Effects;
602 602
603 QString description = tr("Transform audio signal with \"%1\" effect plugin (from %2)") 603 QString description = tr("Transform audio signal with \"%1\" effect plugin (from %2)")
604 .arg(pluginName) 604 .arg(pluginName)
605 .arg(maker); 605 .arg(maker);
606 606
607 if (descriptor->audioInputPortCount == 0) { 607 if (descriptor.audioInputPortCount == 0) {
608 type = TransformDescription::Generator; 608 type = TransformDescription::Generator;
609 QString description = tr("Generate audio signal using \"%1\" plugin (from %2)") 609 QString description = tr("Generate audio signal using \"%1\" plugin (from %2)")
610 .arg(pluginName) 610 .arg(pluginName)
611 .arg(maker); 611 .arg(maker);
612 } 612 }
751 if (rate != 0) t.setSampleRate(rate); 751 if (rate != 0) t.setSampleRate(rate);
752 752
753 SVDEBUG << "TransformFactory::getDefaultTransformFor: identifier \"" 753 SVDEBUG << "TransformFactory::getDefaultTransformFor: identifier \""
754 << id << "\"" << endl; 754 << id << "\"" << endl;
755 755
756 Vamp::PluginBase *plugin = instantiateDefaultPluginFor(id, rate); 756 std::shared_ptr<Vamp::PluginBase> plugin = instantiateDefaultPluginFor(id, rate);
757 757
758 if (plugin) { 758 if (plugin) {
759 t.setPluginVersion(QString("%1").arg(plugin->getPluginVersion())); 759 t.setPluginVersion(QString("%1").arg(plugin->getPluginVersion()));
760 setParametersFromPlugin(t, plugin); 760 setParametersFromPlugin(t, plugin);
761 makeContextConsistentWithPlugin(t, plugin); 761 makeContextConsistentWithPlugin(t, plugin);
762 delete plugin;
763 } 762 }
764 763
765 return t; 764 return t;
766 } 765 }
767 766
768 Vamp::PluginBase * 767 std::shared_ptr<Vamp::PluginBase>
769 TransformFactory::instantiatePluginFor(const Transform &transform) 768 TransformFactory::instantiatePluginFor(const Transform &transform)
770 { 769 {
771 SVDEBUG << "TransformFactory::instantiatePluginFor: identifier \"" 770 SVDEBUG << "TransformFactory::instantiatePluginFor: identifier \""
772 << transform.getIdentifier() << "\"" << endl; 771 << transform.getIdentifier() << "\"" << endl;
773 772
774 Vamp::PluginBase *plugin = instantiateDefaultPluginFor 773 std::shared_ptr<Vamp::PluginBase> plugin = instantiateDefaultPluginFor
775 (transform.getIdentifier(), transform.getSampleRate()); 774 (transform.getIdentifier(), transform.getSampleRate());
776 775
777 if (plugin) { 776 if (plugin) {
778 setPluginParameters(transform, plugin); 777 setPluginParameters(transform, plugin);
779 } 778 }
780 779
781 return plugin; 780 return plugin;
782 } 781 }
783 782
784 Vamp::PluginBase * 783 std::shared_ptr<Vamp::PluginBase>
785 TransformFactory::instantiateDefaultPluginFor(TransformId identifier, 784 TransformFactory::instantiateDefaultPluginFor(TransformId identifier,
786 sv_samplerate_t rate) 785 sv_samplerate_t rate)
787 { 786 {
788 Transform t; 787 Transform t;
789 t.setIdentifier(identifier); 788 t.setIdentifier(identifier);
790 if (rate == 0) rate = 44100.0; 789 if (rate == 0) rate = 44100.0;
791 QString pluginId = t.getPluginIdentifier(); 790 QString pluginId = t.getPluginIdentifier();
792 791
793 Vamp::PluginBase *plugin = nullptr; 792 std::shared_ptr<Vamp::PluginBase> plugin = nullptr;
794 793
795 if (t.getType() == Transform::FeatureExtraction) { 794 if (t.getType() == Transform::FeatureExtraction) {
796 795
797 SVDEBUG << "TransformFactory::instantiateDefaultPluginFor: identifier \"" 796 SVDEBUG << "TransformFactory::instantiateDefaultPluginFor: identifier \""
798 << identifier << "\" is a feature extraction transform" << endl; 797 << identifier << "\" is a feature extraction transform" << endl;
822 } 821 }
823 822
824 return plugin; 823 return plugin;
825 } 824 }
826 825
827 Vamp::Plugin *
828 TransformFactory::downcastVampPlugin(Vamp::PluginBase *plugin)
829 {
830 Vamp::Plugin *vp = dynamic_cast<Vamp::Plugin *>(plugin);
831 if (!vp) {
832 // cerr << "makeConsistentWithPlugin: not a Vamp::Plugin" << endl;
833 vp = dynamic_cast<Vamp::PluginHostAdapter *>(plugin); //!!! why?
834 }
835 if (!vp) {
836 // cerr << "makeConsistentWithPlugin: not a Vamp::PluginHostAdapter" << endl;
837 vp = dynamic_cast<Vamp::HostExt::PluginWrapper *>(plugin); //!!! no, I mean really why?
838 }
839 if (!vp) {
840 // cerr << "makeConsistentWithPlugin: not a Vamp::HostExt::PluginWrapper" << endl;
841 }
842 return vp;
843 }
844
845 bool 826 bool
846 TransformFactory::haveTransform(TransformId identifier) 827 TransformFactory::haveTransform(TransformId identifier)
847 { 828 {
848 populateTransforms(); 829 populateTransforms();
849 return (m_transforms.find(identifier) != m_transforms.end()); 830 return (m_transforms.find(identifier) != m_transforms.end());
892 873
893 if (transform.getType() != Transform::FeatureExtraction) { 874 if (transform.getType() != Transform::FeatureExtraction) {
894 return Vamp::Plugin::TimeDomain; 875 return Vamp::Plugin::TimeDomain;
895 } 876 }
896 877
897 Vamp::Plugin *plugin = 878 std::shared_ptr<Vamp::Plugin> plugin =
898 downcastVampPlugin(instantiateDefaultPluginFor(identifier, 0)); 879 std::dynamic_pointer_cast<Vamp::Plugin>
880 (instantiateDefaultPluginFor(identifier, 0));
899 881
900 if (plugin) { 882 if (plugin) {
901 Vamp::Plugin::InputDomain d = plugin->getInputDomain(); 883 Vamp::Plugin::InputDomain d = plugin->getInputDomain();
902 delete plugin;
903 return d; 884 return d;
904 } 885 }
905 886
906 return Vamp::Plugin::TimeDomain; 887 return Vamp::Plugin::TimeDomain;
907 } 888 }
920 { 901 {
921 QString id = identifier.section(':', 0, 2); 902 QString id = identifier.section(':', 0, 2);
922 903
923 if (RealTimePluginFactory::instanceFor(id)) { 904 if (RealTimePluginFactory::instanceFor(id)) {
924 905
925 const RealTimePluginDescriptor *descriptor = 906 RealTimePluginDescriptor descriptor =
926 RealTimePluginFactory::instanceFor(id)-> 907 RealTimePluginFactory::instanceFor(id)->
927 getPluginDescriptor(id); 908 getPluginDescriptor(id);
928 if (!descriptor) return false; 909 if (descriptor.name == "") {
929 910 return false;
930 min = descriptor->audioInputPortCount; 911 }
931 max = descriptor->audioInputPortCount; 912
913 min = descriptor.audioInputPortCount;
914 max = descriptor.audioInputPortCount;
932 915
933 return true; 916 return true;
934 917
935 } else { 918 } else {
936 919
947 return false; 930 return false;
948 } 931 }
949 932
950 void 933 void
951 TransformFactory::setParametersFromPlugin(Transform &transform, 934 TransformFactory::setParametersFromPlugin(Transform &transform,
952 Vamp::PluginBase *plugin) 935 std::shared_ptr<Vamp::PluginBase> plugin)
953 { 936 {
954 Transform::ParameterMap pmap; 937 Transform::ParameterMap pmap;
955 938
956 //!!! record plugin & API version 939 //!!! record plugin & API version
957 940
974 transform.setProgram(""); 957 transform.setProgram("");
975 } else { 958 } else {
976 transform.setProgram(plugin->getCurrentProgram().c_str()); 959 transform.setProgram(plugin->getCurrentProgram().c_str());
977 } 960 }
978 961
979 RealTimePluginInstance *rtpi = 962 std::shared_ptr<RealTimePluginInstance> rtpi =
980 dynamic_cast<RealTimePluginInstance *>(plugin); 963 std::dynamic_pointer_cast<RealTimePluginInstance>(plugin);
981 964
982 Transform::ConfigurationMap cmap; 965 Transform::ConfigurationMap cmap;
983 966
984 if (rtpi) { 967 if (rtpi) {
985 968
995 transform.setConfiguration(cmap); 978 transform.setConfiguration(cmap);
996 } 979 }
997 980
998 void 981 void
999 TransformFactory::setPluginParameters(const Transform &transform, 982 TransformFactory::setPluginParameters(const Transform &transform,
1000 Vamp::PluginBase *plugin) 983 std::shared_ptr<Vamp::PluginBase> plugin)
1001 { 984 {
1002 //!!! check plugin & API version (see e.g. PluginXml::setParameters) 985 //!!! check plugin & API version (see e.g. PluginXml::setParameters)
1003 986
1004 //!!! check that this is the right plugin! 987 //!!! check that this is the right plugin!
1005 988
1006 RealTimePluginInstance *rtpi = 989 std::shared_ptr<RealTimePluginInstance> rtpi =
1007 dynamic_cast<RealTimePluginInstance *>(plugin); 990 std::dynamic_pointer_cast<RealTimePluginInstance>(plugin);
1008 991
1009 if (rtpi) { 992 if (rtpi) {
1010 const Transform::ConfigurationMap &cmap = transform.getConfiguration(); 993 const Transform::ConfigurationMap &cmap = transform.getConfiguration();
1011 for (Transform::ConfigurationMap::const_iterator i = cmap.begin(); 994 for (Transform::ConfigurationMap::const_iterator i = cmap.begin();
1012 i != cmap.end(); ++i) { 995 i != cmap.end(); ++i) {
1033 } 1016 }
1034 } 1017 }
1035 1018
1036 void 1019 void
1037 TransformFactory::makeContextConsistentWithPlugin(Transform &transform, 1020 TransformFactory::makeContextConsistentWithPlugin(Transform &transform,
1038 Vamp::PluginBase *plugin) 1021 std::shared_ptr<Vamp::PluginBase> plugin)
1039 { 1022 {
1040 const Vamp::Plugin *vp = downcastVampPlugin(plugin); 1023 std::shared_ptr<Vamp::Plugin> vp =
1024 std::dynamic_pointer_cast<Vamp::Plugin>(plugin);
1041 1025
1042 if (!vp) { 1026 if (!vp) {
1043 // time domain input for real-time effects plugin 1027 // time domain input for real-time effects plugin
1044 if (!transform.getBlockSize()) { 1028 if (!transform.getBlockSize()) {
1045 if (!transform.getStepSize()) transform.setStepSize(1024); 1029 if (!transform.getStepSize()) transform.setStepSize(1024);
1076 QString xml; 1060 QString xml;
1077 1061
1078 SVDEBUG << "TransformFactory::getPluginConfigurationXml: identifier \"" 1062 SVDEBUG << "TransformFactory::getPluginConfigurationXml: identifier \""
1079 << t.getIdentifier() << "\"" << endl; 1063 << t.getIdentifier() << "\"" << endl;
1080 1064
1081 Vamp::PluginBase *plugin = instantiateDefaultPluginFor 1065 auto plugin = instantiateDefaultPluginFor(t.getIdentifier(), 0);
1082 (t.getIdentifier(), 0);
1083 if (!plugin) { 1066 if (!plugin) {
1084 SVDEBUG << "TransformFactory::getPluginConfigurationXml: " 1067 SVDEBUG << "TransformFactory::getPluginConfigurationXml: "
1085 << "Unable to instantiate plugin for transform \"" 1068 << "Unable to instantiate plugin for transform \""
1086 << t.getIdentifier() << "\"" << endl; 1069 << t.getIdentifier() << "\"" << endl;
1087 return xml; 1070 return xml;
1089 1072
1090 setPluginParameters(t, plugin); 1073 setPluginParameters(t, plugin);
1091 1074
1092 QTextStream out(&xml); 1075 QTextStream out(&xml);
1093 PluginXml(plugin).toXml(out); 1076 PluginXml(plugin).toXml(out);
1094 delete plugin;
1095 1077
1096 return xml; 1078 return xml;
1097 } 1079 }
1098 1080
1099 void 1081 void
1101 QString xml) 1083 QString xml)
1102 { 1084 {
1103 SVDEBUG << "TransformFactory::setParametersFromPluginConfigurationXml: identifier \"" 1085 SVDEBUG << "TransformFactory::setParametersFromPluginConfigurationXml: identifier \""
1104 << t.getIdentifier() << "\"" << endl; 1086 << t.getIdentifier() << "\"" << endl;
1105 1087
1106 Vamp::PluginBase *plugin = instantiateDefaultPluginFor 1088 auto plugin = instantiateDefaultPluginFor(t.getIdentifier(), 0);
1107 (t.getIdentifier(), 0);
1108 if (!plugin) { 1089 if (!plugin) {
1109 SVDEBUG << "TransformFactory::setParametersFromPluginConfigurationXml: " 1090 SVDEBUG << "TransformFactory::setParametersFromPluginConfigurationXml: "
1110 << "Unable to instantiate plugin for transform \"" 1091 << "Unable to instantiate plugin for transform \""
1111 << t.getIdentifier() << "\"" << endl; 1092 << t.getIdentifier() << "\"" << endl;
1112 return; 1093 return;
1113 } 1094 }
1114 1095
1115 PluginXml(plugin).setParametersFromXml(xml); 1096 PluginXml(plugin).setParametersFromXml(xml);
1116 setParametersFromPlugin(t, plugin); 1097 setParametersFromPlugin(t, plugin);
1117 delete plugin;
1118 } 1098 }
1119 1099
1120 TransformFactory::SearchResults 1100 TransformFactory::SearchResults
1121 TransformFactory::search(QString keyword) 1101 TransformFactory::search(QString keyword)
1122 { 1102 {