-
Notifications
You must be signed in to change notification settings - Fork 3.1k
allow loading multi-component vst3 effects #32908
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -109,14 +109,18 @@ void VstPluginInstance::load() | |
|
|
||
| const auto& factory = m_module->getFactory(); | ||
|
|
||
| //! NOTE: For multi-component bundles, the resource ID is the component name or UID. | ||
| //! Match by name or UID against the factory's audio effect components. | ||
| for (const ClassInfo& classInfo : factory.classInfos()) { | ||
| if (classInfo.category() != kVstAudioEffectClass) { | ||
| continue; | ||
| } | ||
|
|
||
| m_pluginProvider = std::make_unique<VstPluginProvider>(factory, classInfo); | ||
| m_classInfo = classInfo; | ||
| break; | ||
| if (classInfo.name() == m_resourceId || classInfo.ID().toString() == m_resourceId) { | ||
| m_pluginProvider = std::make_unique<VstPluginProvider>(factory, classInfo); | ||
| m_classInfo = classInfo; | ||
| break; | ||
| } | ||
|
Comment on lines
+112
to
+123
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This selector no longer matches every ID that
🧰 Tools🪛 Cppcheck (2.20.0)[style] 121-121: The function 'createModule' is never used. (unusedFunction) |
||
| } | ||
|
|
||
| if (!m_pluginProvider) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,26 +49,49 @@ RetVal<AudioResourceMetaList> VstPluginMetaReader::readMeta(const io::path_t& pl | |
| } | ||
|
|
||
| const auto& factory = module->getFactory(); | ||
| AudioResourceMetaList result; | ||
|
|
||
| std::vector<ClassInfo> audioEffects; | ||
| for (const ClassInfo& classInfo : factory.classInfos()) { | ||
| if (classInfo.category() != kVstAudioEffectClass) { | ||
| continue; | ||
| if (classInfo.category() == kVstAudioEffectClass) { | ||
| audioEffects.push_back(classInfo); | ||
| } | ||
| } | ||
|
|
||
| if (audioEffects.empty()) { | ||
| return make_ret(Err::NoAudioEffect); | ||
| } | ||
|
|
||
| std::string baseName = io::completeBasename(pluginPath).toStdString(); | ||
| bool multiComponent = audioEffects.size() > 1; | ||
|
|
||
| AudioResourceMetaList result; | ||
| std::set<std::string> usedIds; | ||
|
|
||
| for (size_t i = 0; i < audioEffects.size(); ++i) { | ||
| const ClassInfo& classInfo = audioEffects[i]; | ||
|
|
||
| std::string id; | ||
| if (multiComponent) { | ||
| id = classInfo.name(); | ||
| if (id.empty()) { | ||
| id = baseName + " " + std::to_string(i + 1); | ||
| } | ||
| if (muse::contains(usedIds, id)) { | ||
| id = classInfo.ID().toString(); | ||
| } | ||
| usedIds.insert(id); | ||
| } else { | ||
| id = baseName; | ||
| } | ||
|
Comment on lines
+73
to
85
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
For multi-component bundles, Line 75 turns the lookup key into the bare class name unless there is an intra-bundle duplicate. Two different VST bundles can both expose IDs like 🤖 Prompt for AI Agents |
||
|
|
||
| muse::audio::AudioResourceMeta meta; | ||
| meta.id = io::completeBasename(pluginPath).toStdString(); | ||
| meta.id = std::move(id); | ||
| meta.type = muse::audio::AudioResourceType::VstPlugin; | ||
| meta.attributes.emplace(muse::audio::CATEGORIES_ATTRIBUTE, String::fromStdString(classInfo.subCategoriesString())); | ||
| meta.vendor = classInfo.vendor(); | ||
| meta.hasNativeEditorSupport = true; | ||
|
|
||
| result.emplace_back(std::move(meta)); | ||
| break; | ||
| } | ||
|
|
||
| if (result.empty()) { | ||
| return make_ret(Err::NoAudioEffect); | ||
| } | ||
|
|
||
| return RetVal<AudioResourceMetaList>::make_ok(result); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rescans can't detect component churn inside an existing bundle.
Line 68 removes the whole entry as soon as the bundle path is seen, but
IAudioPluginsScanner::scanPlugins()andsrc/framework/vst/internal/vstpluginsscanner.cpponly report paths. If a registered bundle at the same path changes from[A, B]to[A, C], this code treats it as unchanged, soBstays registered andCis never added. Matched paths need a metadata refresh/diff instead of being considered fully reconciled by path presence alone.🤖 Prompt for AI Agents