简体   繁体   English

如何扫描/枚举vst插件dll?

[英]How do I scan/enumerate vst plugin dlls?

I'm trying to build a small program that hosts vst effects and I would like to scan a folder for plugin dlls. 我正在尝试构建一个托管vst效果的小程序,我想扫描一个文件夹中的插件dll。
I know how to find all the dlls but now I have the following questions: 我知道如何找到所有的dll,但现在我有以下问题:

  • What is the best way to determine if a given dll is a vst plugin? 确定给定dll是否为vst插件的最佳方法是什么?
    I tried to just see if the ddl exports the proper function and this works fine for plugins made with the more recent versions of the vst sdk since it exports a method called "VstPluginMain" but older versions export a rather generic "main" function. 我试着看看ddl是否导出了正确的函数,这适用于使用更新版本的vst sdk制作的插件,因为它导出了一个名为“VstPluginMain”的方法,但旧版本导出了一个相当通用的“main”函数。
  • How do I determine if the plugin is an effect or an instrument? 如何确定插件是效果还是乐器?
  • How do I scan vst shell plugins? 我如何扫描vst shell插件?
    Shell plugins are basically dlls that somehow contain multiple effects. Shell插件基本上是以某种方式包含多种效果的dll。 An example of this are the plugins made by Waves Audio http://www.waves.com/ 一个例子是Waves Audio制作的插件http://www.waves.com/

ps: If there is a library that can do all of this for me please let me know. ps:如果有一个库可以为我做所有这些,请告诉我。

How to determine a VST plugin? 如何确定VST插件?

Once you've found main/VSTPluginMain... call it! 一旦找到main / VSTPluginMain ......就叫它! If what's returned is NULL, it's not a VST. 如果返回的是NULL,则它不是VST。 If what's returned is a pointer to the bytes "VstP" (see VstInt32 magic; ///< must be #kEffectMagic ('VstP') in aeffect.h), then you have a VST. 如果返回的是指向字节“VstP”的指针(请参阅VstInt32 magic; ///< must be #kEffectMagic ('VstP') ),那么您有一个VST。

The VSTPluginMain returns a pointer to an AEffect structure. VSTPluginMain返回指向AEffect结构的指针。 You will need to look at this structure. 您需要查看此结构。

Effect or instrument? 效果还是仪器? AEffect::flags | (effFlagsIsSynth = 1 << 8)

Shell VSTs are more complex: Shell VST更复杂:

Category will be kPlugCategShell 类别将是kPlugCategShell

Support the "shellCategory" canDo. 支持“shellCategory”canDo。

Use effShellGetNextPlugin to enumerate. 使用effShellGetNextPlugin枚举。

To instance, respond to audioMasterCurrentId in your callback with the ID you want. 例如,使用您想要的ID响应回调中的audioMasterCurrentId。

@Dave Gamble nailed it, but I wanted to add a few things on VST shell plugins, since they are a bit tricky to work with. @Dave Gamble对此进行了修改,但我想在VST shell插件上添加一些内容,因为它们使用起来有点棘手。

To determine if a VST is a shell plugin, send the effGetPlugCategory opcode to the plugin dispatcher. 要确定VST是否为shell插件,请将effGetPlugCategory操作码发送到插件调度程序。 If it returns kPlugCategShell , then it's a shell plugin. 如果它返回kPlugCategShell ,那么它是一个shell插件。 To get the list of sub-plugins in the shell, you basically call effShellGetNextPlugin until it returns 0. Example code snippit (adapted from a working VST host ): 要获取shell中的子插件列表,基本上调用effShellGetNextPlugin直到它返回0.示例代码snippit(改编自工作的VST主机 ):

// 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
  }
}

If you actually want to load a plugin in a VST shell, it's a bit trickier. 如果你真的想在VST shell中加载一个插件,那就有点棘手了。 First, your host needs to handle the audioMasterCurrentId opcode in the host callback. 首先,您的主机需要在主机回调中处理audioMasterCurrentId操作码。 When you call the VST's VSTPluginMain() method to instantiate the plugin, it will call the host callback with this opcode and ask for the unique ID which should be loaded. 当您调用VST的VSTPluginMain()方法来实例化插件时,它将使用此操作码调用主机回调并询问应加载的唯一ID。

Because this callback is made before the main function returns (and hence, before it delivers an AEffect* to your host), that means that you probably will need to store the shell plugin ID to load in a global variable, since you will not be able to save a pointer to any meaningful data in void* user field of the AEffect struct in time for it to be passed back to you in the host callback. 因为这个回调是 main函数返回之前进行的(因此,在它向你的主机发送一个AEffect*之前),这意味着你可能需要存储shell插件ID来加载一个全局变量,因为你不会能够及时保存指向AEffect结构的void* user字段中任何有意义数据的指针,以便在主机回调中将其传递给您。

如果要在.NET中开发VST Host应用程序,请查看VST.NET

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM