为了简化同时编写所有API的插件,我们将需要一些对象来处理音频信号处理和GUI设计与实现的杂事。这是通过ASPiK PluginKernel完成的。ASPiK是音频专用插件内核的意思。内核实际上是三个主要对象的集合:PluginCore、PluginGUI和PluginParameter。PluginCore(或简称 "core")对象实现了音频信号处理组件,并包含一个PluginParameter对象的列表,每个对象代表一个GUI控制或其他参数,可以存储或加载DAW项目。PluginGUI对象创建了GUI以及每个插件项目携带的拖放式GUI设计器。此外,我们将需要一个能够为MacOS和Windows生成新的(空白)项目的系统,编译器项目文件已经设置为包含我们需要的所有相关文件,以便立即开始编码PluginCore对象。ASPiK是创建编译器项目和安装PluginKernel文件的插件系统的名称。PluginKernel是独立的C++组件,也是你将花费大部分时间的地方。当使用ASPiK时,你也可以设置一些标志,这些标志将一次性包括所有书中的C++对象,和/或启用与FFTW库的链接,这对于第20章和第22章中基于FFT的高级插件来说是必需的。
PluginKernel 插件内核
- 是一组C++对象,旨在处理所有API中常见的主要插件事务
- 完全可移植,可以复制到任何API中的任何项目和任何平台上(Windows或MacOS),几乎不需要修改。
- 是独立于平台的
- 完整但可扩展
- 100%免费使用,无需为您的商业或非商业插件开发提供许可
PluginParameter 插件参数
- 将插件参数存储为原子变量,用于线程安全操作
- 将每个特定于插件的参数封装为一个C++对象
- 可以存储所有类型的输入参数;ints, floats, doubles, string list, 和自定义用户类型。
- 可以实现音频仪表,具有完整的仪表弹道(攻击和释放时间)和各种包络检测方案:峰值、MS、RMS,以及线性或对数格式。
- 实现可选的自动变量绑定,以完全线程安全的方式在所有API中连接GUI参数变化和插件变量
- 有一个可选的辅助存储系统,以维护其他信息和任何插件参数,允许你轻松地定制和扩展该对象
- 实现可选的参数平滑,以实现无故障的GUI控制,有两种类型的平滑可用:线性和指数。
自动实现四种类型的控制渐变:线性、对数、反对数和伏特/倍频。
为VST3插件实现可选的SAA(VST3是唯一有SAA规范的API)。
PluginCore
- 处理音频信号处理并实现DSP功能
- 直接采用C++语言,不包含任何API特定代码,也不需要任何API特定文件或SDK组件
- 不与任何预编译的库相连接
- 定义并维护一组PluginParameter对象,每个对象都对应一个GUI控制或其他插件参数,可与DAW会话和预置一起存储和加载。
- 为AU、VST和RAFX2插件定义工厂预置(AAX工厂预置是以完全不同的方式完成的,将在第5章讨论)。
- 独立于PluginGUI而存在,不知道或不需要知道PluginGUI的存在
- 不创建PluginGUI对象
- 不持有指向PluginGUI对象的指针,也不与它共享任何资源
插件GUI
- 处理所有的GUI功能,包括GUI设计器
- 使用VSTGUI4库构建
- 是独立于平台的
- 不与任何预编译的库连接
- 在一个单一的XML文件中编码整个GUI,包括图形文件数据;这个文件可以从一个项目移动或复制到另一个项目,允许整个GUI在其他项目中轻松移动或重复使用;高级用户可以在多个XML文件中定义多个GUI,这些文件可以被交换使用
- 在绝对需要的少数地方(即AU事件监听器系统)包含API特定代码
- 支持VTSGUI4自定义视图和子控制器范式以扩展其功能
- 独立于PluginCore而存在,不知道或不需要知道PluginCore的存在
- 不持有指向PluginCore对象的指针,也不与它共享任何资源
6.1 插件内核可移植性和Native 插件外壳
所有的插件框架都要求你获得你想支持的每个插件API的SDK,并且你要用正确的编译器为每个目标操作系统编译插件。例如,一个AAX插件必须被编译为AAX插件,并与作为AAX SDK一部分的AAX库链接。插件内核的设计是为了解决在Windows和MacOS上支持多个API和SDK的问题。内核文件可以很容易地从一个项目移动或复制到另一个项目,几乎不需要修改。
内核的设计是为了实现插件项目和API之间的最大可移植性。图6.1a显示了这个概念。每个插件产品(AAX、AU、VST)都由一个本地插件外壳组成,其中包括一个插件的内核。本机插件shell(或简称 "shell")是针对API的插件项目代码,它包括内核对象作为其设计的一部分。我们已经使支持所有的API变得非常容易,也可以在类似的编译器上组合插件项目。例如,你可以很容易地为Xcode创建一个插件项目,在一个项目中创建MacOS AAX、AU和VST插件,并使用一组插件的内核文件,如图6.1b所示。你只需建立一次项目,它就会连续产生所有三个插件。如果你修改了插件的内核代码,你只需要再次重建项目就可以将你的修改传播到所有三个目标插件产品中。你也可以很容易地针对单个插件的API:例如,你可能只对MacOS上的AU插件感兴趣。如果你后来决定要支持另一个API,很简单就可以为该API生成项目,并简单地将你的内核移到新项目中,而不需要修改任何代码。
图6.1:(a)正如该图所示,每个本地插件壳都包含API特定代码以及插件内核。(b) 在合并的API项目中,多个插件外壳共享相同的插件内核代码--因此对内核的修改很容易传播到其他的外壳。内核对象可以在所有产品和项目中自由移动。
本地插件外壳在实例化时创建PluginCore对象。核心对象在shell的生命周期内存在,并且只被创建一次和销毁一次。用户可以随意打开和关闭插件的GUI。shell对象同样也会在每次创建和销毁PluginGUI对象。插件外壳不协调这两个对象,也不在它们之间形成任何形式的关系;这两个对象从不互相交换指针。对象的生命周期如图6.2所示。
图6.2:PluginCore和PluginGUI的生命周期;GUI对象在用户每次打开和关闭时被创建和销毁。
根据你喜欢的操作系统和API,你有几个选项可以作为你的插件设计模式使用。对于初级插件程序员来说,一个特别好的选择是使用RackAFX;然而,这不是必须的,你不需要RackAFX软件来使用本书或其项目代码。如果你使用这种设计范式,那么你使用RackAFX软件来创建一个RAFX2插件项目,添加插件参数,并测试你的代码。当你对结果满意时,你就可以使用导出功能来生成AAX、AU和VST的单独或组合项目,然后针对AAX、AU和VST SDK进行编译。这些导出的项目不包含任何RackAFX代码。在导出过程中,只有你的PluginKernel对象(以及任何包括和用于处理的对象)被复制到导出的项目中。在这之后,你运行CMake,就像你在这里对AAX、AU和VST项目所做的那样。
另一个选择是直接从插件模板项目代码中开发你的插件,这非常简单。你也可以轻松地复制和重用旧的插件项目,而不需要改变任何代码。你可以使用你选择的任何API和平台的组合进行开发。你的插件内核代码不是针对API的,所以你不会为任何特定的平台浪费任何开发时间。
6.2 组织SDK。AAX, AU, 和 VST
开发AAX、AU和VST插件项目有两种选择,你可以在任何时候轻松地在两种设计模式之间来回翻转。在第一种方法中,你以单个插件的API为目标,在该插件的SDK中开发你的项目。在第二种方法中,你同时针对一个或多个API,你的插件项目存在于任何SDK之外。在这两种模式中,你的插件项目代码都不会干扰或改变你的SDK文件。当一个新的SDK可用时,你只需安装它并将你的项目文件夹放到相应的位置。如果你想改变SDK的相对位置,那么你也可以通过修改CMake文件来实现(后面会有更多关于CMake的内容)。我们把这个系统设计得很灵活,也很容易改变。对于你的第一个项目,你应该坚持使用相同的默认SDK安排。之后,你可以尝试使用不同的SDK文件夹位置和其他选项。
6.2.1 你的C++编译器
您将需要一个合适的编译器用于MacOS和Windows。对于Xcode,您至少需要Xcode 8;对于Visual Studio,您至少需要VS2015 Community。这两个编译器都可以从苹果和微软免费下载。VSTGUI库在MacOS和Windows都需要C++11扩展,在MacOS需要C++14扩展。此外,你应该查看Avid公司的AAX插件的编译器认证列表。在写这篇文章的时候,Visual Studio 2017还没有被正式支持。在进行任何插件开发之前,你需要为你的目标操作系统下载并安装所选择的编译器。作为一个酸性测试,你可能想创建一个简单的C++项目并构建它,以确保一切准备就绪。
6.2.2 设置AAX SDK
按照第5章的说明来安装SDK并编译基础类库。SDK外部文件夹的装饰是为了告诉你编译器的版本(例如2p3p0指的是2.3.0版本)。然而,当你使用CMake生成你的编译器项目文件时,这些数字可能会出现问题,这与浏览SDK位置以运行CMake有关。为了克服这个问题,并使我们的SDK命名标准化,请将根文件夹重命名为简单的AAX_SDK(记住,你以后可以随时改变你的命名规则)。一旦这样做了,你就会有一个类似于图6.3a的SDK文件夹层次结构。请注意名为myprojects的文件夹位于顶级SDK文件夹中,与其他子文件夹一起。这是你需要创建的文件夹,它将包含你所有的AAX特定项目。你可以随心所欲地命名这个文件夹,不过你应该保持这个名字的简单性和对CMake的友好性,不要有空格、数字或特殊字符。我们将对所有插件项目文件夹专门使用myprojects这个名字。开始吧,把这个空文件夹添加到你的SDK中去吧。
图6.3: 以下SDK的文件夹层次:(a) AAX, (b) AU, (c) VST, 和 (d) 通用(合并)。
6.2.3 设置AU SDK
按照第4章的说明,下载AU SDK的子文件夹。接下来,将这两个文件夹合并到一个名为AU_SDK的外部文件夹,如图6.3b所示。你需要在AU_SDK文件夹内创建myprojects子文件夹,就像你为AAX所做的那样,再次注意你可以为这个文件夹命名,只要它是合法的CMake文件夹名称。没有库需要构建,所以在添加完这个文件夹后,你就完成了。
6.2.4 设置VST SDK
按照第3章的说明,安装VST3 SDK并构建样本项目。完成这些后,你只需要像AAX和AU那样添加myprojects子文件夹(遵循同样的规则)。然后你应该有一个如图6.3c所示的文件夹层次结构。
6.2.5 创建通用SDK文件夹层次结构
你可以将所有的SDK合并到一个外部文件夹中,并创建针对任何你希望的API组合的通用项目。在这种情况下,你需要创建一个名为ALL_SDK的外部容器文件夹,然后将我们刚才讨论的三个SDK文件夹填充到其中。与这三个子文件夹并行,创建myprojects子文件夹来容纳你的通用项目。因为你可以针对任何单一的API或任何API的组合,这可能是你设计范式的最简单的选择。因为我是用CMake打包项目的,你可以在任何时候把通用项目重新定位到不同的API组合上,所以这里没有什么是固定的。如果你想使用这个选项,你应该最终得到图6.3d所示的ALL_SDK文件夹层次结构。你还应该记住,你可以自由地移动项目,并为特定的API或通用组合重新定位它们。在这个过程中,你不需要做出任何承诺!
6.2.6 添加VSTGUI4库
我们的PluginGUI对象是围绕VSTGUI4库建立的。这个包是免费开放的,你可以从Sternberg VST的网页上下载:https://github.com/steinbergmedia/vstgui 只需使用VST3 SDK附带的文件夹,或者从RackAFX上安装它。新的VSTGUI4版本是与新的VST3 SDK一起发布的,所以如果你升级你的VST3 SDK,你会自动得到最新的VSTGUI4库。VSTGUI4的工程师们正在不断地更新和改进这个很棒的库。然而,在更新过程中,他们可能会改变对象和功能的方式,有时需要在我们这边进行调整。为了使我们的插件项目文件夹与SDK完全隔离和分开,我们将复制一个vstgui4文件夹,并将其放在每个myprojects子文件夹内。这个库不包含预编译的代码,而且大小相当小(不到40MB),所以把这个文件夹复制到我们的各个myprojects子文件夹里并不是一个负担。请注意,我们将在所有情况下遵循这一规则,包括VST3 SDK。原因与更新有关:如果一个新的VST3 SDK问世,对VSTGUI4库做了重大改变,我们不会受到影响,因为我们将使用我们自己的、本地的独立文件夹。当然,我们会尽一切努力使PluginGUI对象更新到VSTGUI4的最新版本,但是如果需要的话,我们会一直有自己的完整功能版本在手。VSTGUI4库像其他的SDK一样被打包,有一个充满子文件夹的根文件夹。根文件夹被命名为vstgui4,我们将不会为我们的使用而修改这个名字。但是和其他东西一样,如果你愿意,你可以通过稍微修改CMake文件来改变这个名字。
6.2.7 CMake
简单地说,CMake是一个工具,可以从一个或多个脚本文件中生成Visual Studio和Xcode项目,每个脚本文件都被命名为CMakeLists.txt。你可以从CMake网站(http://cmake.org)免费下载它,并在MacOS和/或Windows上安装它。经验丰富的程序员可能已经熟悉这个产品了。所有的CMake脚本文件都是为你编写的,但你需要修改几行文字来设置你的项目名称,以及以你喜欢的任何组合构建各种插件的选项。进行这些修改是非常容易的,只需要修改几行文字。如果你想重新命名你的SDK根文件夹或改变它们之间的关系或相对位置,你将需要做更多的编辑。虽然这也很简单,但它需要更深入的CMake知识。CMake通常是直接从命令提示符(Windows)或终端(MacOS)运行的,这也是我们将使用它的方式。你将需要导航到你的项目文件夹,然后执行一条CMake命令。这将生成你的编译器项目文件(Visual Studio为.sln,Xcode为.xcodeproj),包括所有API以及PluginKernel所需的所有文件。然后你可以打开编译器项目,并直接重建它,开始工作。通常情况下,导航到项目文件夹是这个过程中最困难的部分。命令提示符和终端可能对你的项目文件夹命名很挑剔,所以一定要避免使用空格、数字或其他特殊字符的名称--必要时使用下划线(_)符号来代替空格。
在安装CMake时,有一件事非常重要:你需要确保CMake可执行文件的路径被添加到你的操作系统中,这样你就可以用一个简单的 "cmake "命令来运行它,而不需要输入整个可执行文件的路径。对于Windows,这是在CMake安装过程中完成的,当时你选中了一个选项,将CMake的路径添加到你的系统路径变量中。对于MacOS来说,这要复杂一些,需要在usr/local/bin文件夹中为CMake创建一个SymLink(快捷方式)。如果你不知道如何做,你可以找到许多包含说明的教程网站:这是一项常见的任务,特别是对程序员来说。我们将在第6.3.2节讨论使用CMake的细节。
6.3 用ASPiKreator创建一个插件项目。IIRFilters
ASPiK系统有大量的文档,可以通过各种渠道获得,包括www.willpirkle.com,以及GitHub。我将在第11章中介绍一个名为IIRFilters的例子项目--第一本插件项目,而不是对每一个细节都进行详细的阐述。你可能想参考那一章,或者把这一章收藏起来再回来。如果你使用RackAFX,你将使用第7章的说明创建你的RAFX2项目,然后使用Export ASPiK功能来生成ASPiK项目。RackAFX会自动用你的项目细节修改CMakeLists.txt文件。你也可以在以后手动修改该文件并重新运行CMake以启用其他选项或针对其他API。
你也可以使用内置的ASPiKreator软件,该软件包含在ASPiK SDK中,在根文件夹ASPIK_SDK/ASPiKreator中可以找到。Windows和MacOS都有预编译的版本,只需为你的操作系统启动相应的应用程序。ASPiKreator由两个面板组成:ASPiK项目创建器用于生成新的项目,而GUI代码创建器则用于快速、轻松地将GUI控制代码添加到你的项目中。虽然所有这些都可以手动完成--从创建项目到编写GUI代码--这个应用程序将为你节省大量的时间,因为它为你处理繁琐的杂事。如果你需要手动创建你的项目,请参阅ASPiK SDK中的文档,了解关于编辑CMakeLists.txt文件和编写GUI代码的逐步说明。第一步是设置您的默认项目文件夹,它被命名为myprojects,可以位于您选择的SDK中,也可以位于外部的ALL_SDK文件夹中。接下来设置你的公司名称、四个字符的公司代码、URL和电子邮件地址。ASPiKreator将记住这些设置,以便今后软件运行。然后,将项目名称设为IIRFilters。该插件可以被命名为任何你喜欢的东西,你可以使用与项目本身相同的名字--这里我们将使用Filterizer。如果你的项目以AAX为目标,记得设置AAX特定的名称以及选择AAX类别。图6.4显示了ASPiK项目创建者面板和本例中选择的选项。
-- 未翻译完