如何扫描/枚举VST插件DLL?

10

我正在尝试构建一个小程序,用于托管VST效果,我想扫描一个包含插件DLL的文件夹。
我知道如何找到所有的DLLs,但现在我有以下问题:

  • 确定给定的DLL是否是VST插件的最佳方法是什么?
    我尝试了简单地查看DLL是否导出正确的函数,对于使用较新版本的VST SDK制作的插件来说这很有效,因为它导出了名为“VstPluginMain” 的方法,但旧版本则导出了一个相当通用的“main”函数。
  • 如何确定插件是效果器还是乐器?
  • 如何扫描VST Shell插件?
    Shell插件基本上是包含多个效果器的DLL。 Waves Audio 制作的插件就是一个例子 http://www.waves.com/

附注:如果有一个库可以为我完成所有这些,请告诉我。


你愿意分享一些主机代码吗?我正在尝试创建一个VST主机,但不知道从哪里开始。 - Daniel Rodrigues
@DanielRodrigues 我在 http://github.com/teragonaudio/MrsWatson/ 上有一个开源的VST主机。 - Nik Reiman
3个回答

9
如何确定一个VST插件?
一旦找到了main/VSTPluginMain...,就调用它!如果返回的是NULL,则不是VST。如果返回的是指向字节"VstP"的指针(请参见aeffect.h中的VstInt32 magic; ///< must be #kEffectMagic ('VstP')),则您拥有一个VST。
VSTPluginMain返回一个指向AEffect结构的指针。您需要查看这个结构。
效果或乐器?AEffect::flags | (effFlagsIsSynth = 1 << 8) Shell VST更加复杂:
类别将是kPlugCategShell
支持“shellCategory”canDo。
使用effShellGetNextPlugin进行枚举。
要实例化,请在回调中响应audioMasterCurrentId并使用所需的ID。

谢谢你的回答。 有一些东西我还没有完全理解。 假设我找到了一个不是插件但是导出了“main”(这似乎是一个非常常见的名称...)然后从中返回了一些内容的dll。如果我尝试引用该值以寻找“VstP”,那么我难道不会遇到麻烦吗? - Roald
1
可能的话,你肯定会检查指针是否为非零。你还可以考虑检查回调函数是否被调用。对于用户在他们的VSTPlugIns文件夹中存储恶意DLL文件是没有多少意义的。 - Dave Gamble
@DaveGamble 是的,我的主要关注点是恶意代码。回答得很好! - Qix - MONICA WAS MISTREATED

3

@Dave Gamble说的很准确了,但是关于VST外壳插件,我想补充一些东西,因为它们有点难以处理。

要确定一个VST是否是一个外壳插件,请向插件分派器发送effGetPlugCategory操作码。如果返回kPlugCategShell,那么它就是一个外壳插件。要获取外壳中子插件的列表,你基本上调用effShellGetNextPlugin直到它返回0。示例代码片段(改编自工作中的VST host):

// All this stuff should probably be set up far earlier in your code...
// This assumes that you have already opened the plugin and called VSTPluginMain()
typedef VstIntPtr (*Vst2xPluginDispatcherFunc)(AEffect *effect, VstInt32 opCode, VstInt32 index, VstIntPtr value, void *ptr, float opt);
Vst2xPluginDispatcherFunc dispatcher;
AEffect* plugin;
char nameBuffer[40];

while(true) {
  memset(nameBuffer, 0, 40);
  VstInt32 shellPluginId = dispatcher(pluginHandle, effShellGetNextPlugin, 0, 0, nameBuffer, 0.0f);
  if(shellPluginId == 0 || nameBuffer[0] == '\0') {
    break;
  }
  else {
    // Do something with the name and ID
  }
}

如果您想在VST shell中加载插件,可能需要一些技巧。首先,您的主机需要处理主机回调中的操作码。当您调用VST的方法来实例化插件时,它将使用此操作码调用主机回调,并要求加载应该的唯一ID。
由于此回调是在主函数返回之前(因此,在向主机传递之前)进行的,这意味着您可能需要将要加载的shell插件ID存储在全局变量中,因为您将无法保存指向任何有意义的数据的指针到AEffect结构体的字段中,以便在主机回调中将其传回给您。

1

如果您想使用.NET开发VST宿主应用程序,请查看VST.NET


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接