Об инициализации модуля.
Модуль * .vst3 может потребовать дополнительной инициализации.
Если модуль экспортирует некоторые предопределенные функции, вы должны вызвать его до получения IPluginFactory.
Имена экспортируемых функций - «InitDll» и «ExitDll» для платформы Windows.
// after the module is loaded.
auto initDll = (bool(*)())GetFunction(hmodule, "InitDll");
if(initDll) { initDll(); }
auto proc = (GetFactoryProc)GetFunction(hmodule, "GetPluginFactory");
Steinberg::IPluginFactory* rawFactory = proc();
// before the module is unloaded.
auto exitDll = (bool(*)())GetFunction(hmodule, "ExitDll");
if(exitDll) { exitDll(); }
Вы также можете использовать VST3::Hosting::Module
класс, определенный в public.sdk/source/vst/hosting/module.h
для этой цели.
Об идентификаторах.
CID - это идентификатор класса (a.k.a. component-id), который используется для идентификации фактического класса компонента плагина в файле модуля vst3.
Файл модуля * .vst3 может содержать несколько плагинов, однако хост-приложение не может идентифицировать плагин по его фактическому имени класса C ++ (потому что хост никогда не знает его).
Вот почему VST3 SDK позволяет идентифицировать фактический класс компонентов плагина с помощью CID.
IID - это идентификатор интерфейса, который используется для указания класса интерфейса.
В контексте загрузки плагина IID представляет, какой тип интерфейса интерфейса вы хотите получить созданный плагин, как правило, это будет Vst :: IComponent.
VST3 SDK основан на модульной архитектуре VST (VST-MA), которая очень похожа на объектную модель компонентов (COM) от Microsoft.
Изучение COM поможет вам понять VST-MA.
Кроме того, каждый плагин в файле модуля * .vst3 обычно состоит из двух компонентов: компонента Processor и компонента EditController.
- Компонент Processor предоставляет базовые API плагинов и DSP API.
- Компонент Processor выводит два интерфейсных класса: класс Vst :: IComponent и класс Vst :: IAudioProcessor.
- Компонент EditController предоставляет API-интерфейсы управления параметрами и пользовательский интерфейс.
Основная концепция
Аудиоэффект или инструмент VST 3 в основном состоит из двух частей: части обработки и части контроллера редактирования.
Соответствующие интерфейсы:
Процессор: Steinberg :: Vst :: IAudioProcessor + Steinberg :: Vst :: IComponent
Контроллер: Steinberg :: Vst :: IEditController
Конструкция VST 3 предполагает полное разделение процессора и контроллера редактирования путем реализации двух компонентов. Разбиение эффекта на эти две части требует, конечно, дополнительных усилий для реализации.
Но это разделение позволяет хосту запускать каждый компонент в другом контексте. Он даже может запускать их на разных компьютерах. Еще одним преимуществом является то, что изменения параметров могут быть разделены, когда дело доходит до автоматизации. В то время как для обработки эти изменения должны быть переданы точным способом выборки, часть GUI может быть обновлена с гораздо более низкой частотой, и она может быть смещена на величину, которая является результатом любой компенсации задержки или другого смещения обработки.
Подключаемый модуль, поддерживающий это разделение, должен установить флаг Steinberg :: Vst :: kDistributable в информации о классе компонента процессора (Steinberg :: PClassInfo2 :: classFlags). Конечно, не каждый плагин может поддерживать это, например, если он сильно зависит от ресурсов, которые нельзя легко перенести на другой компьютер. Поэтому, если этот флаг не установлен, хост не должен пытаться разделить компоненты каким-либо образом.
Хотя это и не рекомендуется, в одном классе компонентов можно реализовать как часть обработки, так и часть контроллера. Хост пытается запросить интерфейс Steinberg :: Vst :: IEditController после создания Steinberg :: Vst :: IAudioProcessor и в случае успеха использует его в качестве контроллера.
- Документация по API VST3 (VST_SDK 3.6.13)
Плагин состоит из двух компонентов, поэтому вы будете вызывать createInstance () дважды.
Это шаг для загрузки плагина из файла модуля * .vst3:
- Создайте компонент Processor плагина из файла модуля в виде класса Vst :: IComponent.
- Инициализировать компонент Процессор.
- Получите CID компонента EditController, соответствующего компоненту Processor.
- Создайте компонент EditController из файла модуля с CID.
- Инициализируйте компонент EditController.
- Подключите и настройте их.
// Get classes.
for (size_t i = 0; i < rawFactory->countClasses(); i++)
{
Steinberg::PClassInfo info;
rawFactory->getClassInfo(i, &info);
// info.category will be kVstAudioEffectClass for Processor component.
// skip this component if not.
if(info.category != kVstAudioEffectClass) {
continue;
}
Vst::IComponent *comp(nullptr);
Steinberg::tresult result
= rawFactory->createInstance(info.cid, // tell factory which plugin to be created.
Vst::IComponent::iid, // tell factory which type of interface you want.
(void **)&comp // get the pointer to `comp`, and pass it as (void **)
);
if(result != kResultTrue) {
// TODO: error handling
return;
}
// now `comp` shall be valid pointer of Vst::IComponent.
// initialize comp
comp->setIoMode(Vst::IoModes::kAdvanced);
// you should define host context object before and pass it here as `FUnknown *`.
// the host context object is the class which normally derives Vst::IHostApplication,
// Vst::IComponentHandler, Vst::IPluginInterfaceSupport, etc.
comp->initialize(host_context);
TUID edit_cid;
comp->getControllerClassId(edit_cid);
// (in detail, IEditController interface may be obtained from IComponent directly if the plugin
// derives SingleComponentEffect.
// For such plugins, do not use this method and obtain IEditController with `comp->queryInstance()`
// )
Vst::IEditController *edit(nullptr);
result = rawFactory->createInstance(edit_cid,
Vst::IEditController::iid,
(void **)&edit);
if(result != kResultTrue) {
// TODO: error handling
return;
}
// initialize the EditController component too.
edit->initialize(host_context);
//...
// now the two components are created.
// connect and setup them.
// use the plugin.
// ...
// don't forget destruction after using it.
edit->terminate();
comp->terminate();
edit->release();
comp->release();
}
К вашему сведению, я разрабатываю VST3-приложение с открытым исходным кодом, которое называется Terra
.
https://github.com/hotwatermorning/Terra
Это все еще альфа-версия.Но это может быть полезно для вас.
Спасибо.