mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-10 04:30:12 +02:00
Move all casted VST3 plugin interfaces to struct
To make Waves plugins happy we're going to have to replace this after calling `IPluginBase::initialize()`.
This commit is contained in:
+218
-191
@@ -48,10 +48,9 @@ Vst3PlugViewInterfaces::Vst3PlugViewInterfaces(
|
|||||||
parameter_finder(plug_view),
|
parameter_finder(plug_view),
|
||||||
plug_view_content_scale_support(plug_view) {}
|
plug_view_content_scale_support(plug_view) {}
|
||||||
|
|
||||||
Vst3PluginInstance::Vst3PluginInstance(
|
Vst3PluginInterfaces::Vst3PluginInterfaces(
|
||||||
Steinberg::IPtr<Steinberg::FUnknown> object) noexcept
|
Steinberg::IPtr<Steinberg::FUnknown> object) noexcept
|
||||||
: object(object),
|
: audio_presentation_latency(object),
|
||||||
audio_presentation_latency(object),
|
|
||||||
audio_processor(object),
|
audio_processor(object),
|
||||||
automation_state(object),
|
automation_state(object),
|
||||||
component(object),
|
component(object),
|
||||||
@@ -72,11 +71,16 @@ Vst3PluginInstance::Vst3PluginInstance(
|
|||||||
process_context_requirements(object),
|
process_context_requirements(object),
|
||||||
program_list_data(object),
|
program_list_data(object),
|
||||||
unit_info(object),
|
unit_info(object),
|
||||||
xml_representation_controller(object),
|
xml_representation_controller(object) {}
|
||||||
|
|
||||||
|
Vst3PluginInstance::Vst3PluginInstance(
|
||||||
|
Steinberg::IPtr<Steinberg::FUnknown> object) noexcept
|
||||||
|
: object(object),
|
||||||
|
interfaces(object),
|
||||||
// If the object doesn't support `IPlugBase` then the object cannot be
|
// If the object doesn't support `IPlugBase` then the object cannot be
|
||||||
// uninitialized (this isn't possible right now, but, who knows what the
|
// uninitialized (this isn't possible right now, but, who knows what the
|
||||||
// future might bring)
|
// future might bring)
|
||||||
is_initialized(!plugin_base) {}
|
is_initialized(!interfaces.plugin_base) {}
|
||||||
|
|
||||||
Vst3Bridge::Vst3Bridge(MainContext& main_context,
|
Vst3Bridge::Vst3Bridge(MainContext& main_context,
|
||||||
std::string plugin_dll_path,
|
std::string plugin_dll_path,
|
||||||
@@ -221,6 +225,9 @@ void Vst3Bridge::run() {
|
|||||||
},
|
},
|
||||||
[&](Vst3PluginProxy::SetState& request)
|
[&](Vst3PluginProxy::SetState& request)
|
||||||
-> Vst3PluginProxy::SetState::Response {
|
-> Vst3PluginProxy::SetState::Response {
|
||||||
|
const Vst3PluginInterfaces& interfaces =
|
||||||
|
object_instances.at(request.instance_id).interfaces;
|
||||||
|
|
||||||
// We need to run `getState()` from the main thread, so we might
|
// We need to run `getState()` from the main thread, so we might
|
||||||
// as well do the same thing with `setState()`. See below.
|
// as well do the same thing with `setState()`. See below.
|
||||||
// NOTE: We also try to handle mutual recursion here, in case
|
// NOTE: We also try to handle mutual recursion here, in case
|
||||||
@@ -229,17 +236,19 @@ void Vst3Bridge::run() {
|
|||||||
// This same function is defined in both `IComponent` and
|
// This same function is defined in both `IComponent` and
|
||||||
// `IEditController`, so the host is calling one or the
|
// `IEditController`, so the host is calling one or the
|
||||||
// other
|
// other
|
||||||
if (object_instances.at(request.instance_id).component) {
|
if (interfaces.component) {
|
||||||
return object_instances.at(request.instance_id)
|
return interfaces.component->setState(&request.state);
|
||||||
.component->setState(&request.state);
|
|
||||||
} else {
|
} else {
|
||||||
return object_instances.at(request.instance_id)
|
return interfaces.edit_controller->setState(
|
||||||
.edit_controller->setState(&request.state);
|
&request.state);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[&](Vst3PluginProxy::GetState& request)
|
[&](Vst3PluginProxy::GetState& request)
|
||||||
-> Vst3PluginProxy::GetState::Response {
|
-> Vst3PluginProxy::GetState::Response {
|
||||||
|
const Vst3PluginInterfaces& interfaces =
|
||||||
|
object_instances.at(request.instance_id).interfaces;
|
||||||
|
|
||||||
// NOTE: The VST3 version of Algonaut Atlas doesn't restore
|
// NOTE: The VST3 version of Algonaut Atlas doesn't restore
|
||||||
// state unless this function is run from the GUI thread
|
// state unless this function is run from the GUI thread
|
||||||
// NOTE: This also requires mutual recursion because REAPER will
|
// NOTE: This also requires mutual recursion because REAPER will
|
||||||
@@ -249,13 +258,12 @@ void Vst3Bridge::run() {
|
|||||||
// This same function is defined in both `IComponent`
|
// This same function is defined in both `IComponent`
|
||||||
// and `IEditController`, so the host is calling one or
|
// and `IEditController`, so the host is calling one or
|
||||||
// the other
|
// the other
|
||||||
if (object_instances.at(request.instance_id)
|
if (interfaces.component) {
|
||||||
.component) {
|
return interfaces.component->getState(
|
||||||
return object_instances.at(request.instance_id)
|
&request.state);
|
||||||
.component->getState(&request.state);
|
|
||||||
} else {
|
} else {
|
||||||
return object_instances.at(request.instance_id)
|
return interfaces.edit_controller->getState(
|
||||||
.edit_controller->getState(&request.state);
|
&request.state);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -267,7 +275,7 @@ void Vst3Bridge::run() {
|
|||||||
SetAudioPresentationLatencySamples::Response {
|
SetAudioPresentationLatencySamples::Response {
|
||||||
return object_instances
|
return object_instances
|
||||||
.at(request.instance_id)
|
.at(request.instance_id)
|
||||||
.audio_presentation_latency
|
.interfaces.audio_presentation_latency
|
||||||
->setAudioPresentationLatencySamples(
|
->setAudioPresentationLatencySamples(
|
||||||
request.dir, request.bus_index,
|
request.dir, request.bus_index,
|
||||||
request.latency_in_samples);
|
request.latency_in_samples);
|
||||||
@@ -275,10 +283,14 @@ void Vst3Bridge::run() {
|
|||||||
[&](YaAutomationState::SetAutomationState& request)
|
[&](YaAutomationState::SetAutomationState& request)
|
||||||
-> YaAutomationState::SetAutomationState::Response {
|
-> YaAutomationState::SetAutomationState::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.automation_state->setAutomationState(request.state);
|
.interfaces.automation_state->setAutomationState(
|
||||||
|
request.state);
|
||||||
},
|
},
|
||||||
[&](YaConnectionPoint::Connect& request)
|
[&](YaConnectionPoint::Connect& request)
|
||||||
-> YaConnectionPoint::Connect::Response {
|
-> YaConnectionPoint::Connect::Response {
|
||||||
|
Vst3PluginInstance& this_instance =
|
||||||
|
object_instances.at(request.instance_id);
|
||||||
|
|
||||||
// If the host directly connected the underlying objects then we
|
// If the host directly connected the underlying objects then we
|
||||||
// can directly connect them as well. Some hosts, like Ardour
|
// can directly connect them as well. Some hosts, like Ardour
|
||||||
// and Mixbus, will place a proxy between the two plugins This
|
// and Mixbus, will place a proxy between the two plugins This
|
||||||
@@ -292,49 +304,55 @@ void Vst3Bridge::run() {
|
|||||||
return std::visit(
|
return std::visit(
|
||||||
overload{
|
overload{
|
||||||
[&](const native_size_t& other_instance_id) -> tresult {
|
[&](const native_size_t& other_instance_id) -> tresult {
|
||||||
return object_instances.at(request.instance_id)
|
const Vst3PluginInstance& other_instance =
|
||||||
.connection_point->connect(
|
object_instances.at(other_instance_id);
|
||||||
object_instances.at(other_instance_id)
|
|
||||||
.connection_point);
|
return this_instance.interfaces.connection_point
|
||||||
|
->connect(
|
||||||
|
other_instance.interfaces.connection_point);
|
||||||
},
|
},
|
||||||
[&](Vst3ConnectionPointProxy::ConstructArgs& args)
|
[&](Vst3ConnectionPointProxy::ConstructArgs& args)
|
||||||
-> tresult {
|
-> tresult {
|
||||||
object_instances.at(request.instance_id)
|
this_instance.connection_point_proxy =
|
||||||
.connection_point_proxy = Steinberg::owned(
|
Steinberg::owned(
|
||||||
new Vst3ConnectionPointProxyImpl(
|
new Vst3ConnectionPointProxyImpl(
|
||||||
*this, std::move(args)));
|
*this, std::move(args)));
|
||||||
|
|
||||||
return object_instances.at(request.instance_id)
|
return this_instance.interfaces.connection_point
|
||||||
.connection_point->connect(
|
->connect(this_instance.connection_point_proxy);
|
||||||
object_instances.at(request.instance_id)
|
|
||||||
.connection_point_proxy);
|
|
||||||
}},
|
}},
|
||||||
request.other);
|
request.other);
|
||||||
},
|
},
|
||||||
[&](const YaConnectionPoint::Disconnect& request)
|
[&](const YaConnectionPoint::Disconnect& request)
|
||||||
-> YaConnectionPoint::Disconnect::Response {
|
-> YaConnectionPoint::Disconnect::Response {
|
||||||
|
Vst3PluginInstance& this_instance =
|
||||||
|
object_instances.at(request.instance_id);
|
||||||
|
|
||||||
// If the objects were connected directly we can also disconnect
|
// If the objects were connected directly we can also disconnect
|
||||||
// them directly. Otherwise we'll disconnect them from our proxy
|
// them directly. Otherwise we'll disconnect them from our proxy
|
||||||
// object and then destroy that proxy object.
|
// object and then destroy that proxy object.
|
||||||
if (request.other_instance_id) {
|
if (request.other_instance_id) {
|
||||||
return object_instances.at(request.instance_id)
|
const Vst3PluginInstance& other_instance =
|
||||||
.connection_point->disconnect(
|
object_instances.at(*request.other_instance_id);
|
||||||
object_instances.at(*request.other_instance_id)
|
|
||||||
.connection_point);
|
return this_instance.interfaces.connection_point
|
||||||
|
->disconnect(
|
||||||
|
other_instance.interfaces.connection_point);
|
||||||
} else {
|
} else {
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
this_instance.interfaces.connection_point->disconnect(
|
||||||
.connection_point->disconnect(
|
|
||||||
object_instances.at(*request.other_instance_id)
|
object_instances.at(*request.other_instance_id)
|
||||||
.connection_point_proxy);
|
.connection_point_proxy);
|
||||||
object_instances.at(*request.other_instance_id)
|
this_instance.connection_point_proxy.reset();
|
||||||
.connection_point_proxy.reset();
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[&](const YaConnectionPoint::Notify& request)
|
[&](const YaConnectionPoint::Notify& request)
|
||||||
-> YaConnectionPoint::Notify::Response {
|
-> YaConnectionPoint::Notify::Response {
|
||||||
|
const Vst3PluginInstance& this_instance =
|
||||||
|
object_instances.at(request.instance_id);
|
||||||
|
|
||||||
// NOTE: We're using a few tricks here to pass through a pointer
|
// NOTE: We're using a few tricks here to pass through a pointer
|
||||||
// to the _original_ `IMessage` object passed to a
|
// to the _original_ `IMessage` object passed to a
|
||||||
// connection proxy. This is needed because some plugins
|
// connection proxy. This is needed because some plugins
|
||||||
@@ -351,8 +369,7 @@ void Vst3Bridge::run() {
|
|||||||
// solution for this (and bypassing Ardour's connection
|
// solution for this (and bypassing Ardour's connection
|
||||||
// proxies sort of goes against the idea behind yabridge)
|
// proxies sort of goes against the idea behind yabridge)
|
||||||
return do_mutual_recursion_on_gui_thread([&]() -> tresult {
|
return do_mutual_recursion_on_gui_thread([&]() -> tresult {
|
||||||
return object_instances.at(request.instance_id)
|
return this_instance.interfaces.connection_point->notify(
|
||||||
.connection_point->notify(
|
|
||||||
request.message_ptr.get_original());
|
request.message_ptr.get_original());
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -367,18 +384,20 @@ void Vst3Bridge::run() {
|
|||||||
[&](YaEditController::SetComponentState& request)
|
[&](YaEditController::SetComponentState& request)
|
||||||
-> YaEditController::SetComponentState::Response {
|
-> YaEditController::SetComponentState::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.edit_controller->setComponentState(&request.state);
|
.interfaces.edit_controller->setComponentState(
|
||||||
|
&request.state);
|
||||||
},
|
},
|
||||||
[&](const YaEditController::GetParameterCount& request)
|
[&](const YaEditController::GetParameterCount& request)
|
||||||
-> YaEditController::GetParameterCount::Response {
|
-> YaEditController::GetParameterCount::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.edit_controller->getParameterCount();
|
.interfaces.edit_controller->getParameterCount();
|
||||||
},
|
},
|
||||||
[&](YaEditController::GetParameterInfo& request)
|
[&](YaEditController::GetParameterInfo& request)
|
||||||
-> YaEditController::GetParameterInfo::Response {
|
-> YaEditController::GetParameterInfo::Response {
|
||||||
Steinberg::Vst::ParameterInfo info{};
|
Steinberg::Vst::ParameterInfo info{};
|
||||||
const tresult result = object_instances.at(request.instance_id)
|
const tresult result =
|
||||||
.edit_controller->getParameterInfo(
|
object_instances.at(request.instance_id)
|
||||||
|
.interfaces.edit_controller->getParameterInfo(
|
||||||
request.param_index, info);
|
request.param_index, info);
|
||||||
|
|
||||||
return YaEditController::GetParameterInfoResponse{
|
return YaEditController::GetParameterInfoResponse{
|
||||||
@@ -389,7 +408,7 @@ void Vst3Bridge::run() {
|
|||||||
Steinberg::Vst::String128 string{0};
|
Steinberg::Vst::String128 string{0};
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.edit_controller->getParamStringByValue(
|
.interfaces.edit_controller->getParamStringByValue(
|
||||||
request.id, request.value_normalized, string);
|
request.id, request.value_normalized, string);
|
||||||
|
|
||||||
return YaEditController::GetParamStringByValueResponse{
|
return YaEditController::GetParamStringByValueResponse{
|
||||||
@@ -401,7 +420,7 @@ void Vst3Bridge::run() {
|
|||||||
Steinberg::Vst::ParamValue value_normalized;
|
Steinberg::Vst::ParamValue value_normalized;
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.edit_controller->getParamValueByString(
|
.interfaces.edit_controller->getParamValueByString(
|
||||||
request.id,
|
request.id,
|
||||||
const_cast<Steinberg::Vst::TChar*>(
|
const_cast<Steinberg::Vst::TChar*>(
|
||||||
u16string_to_tchar_pointer(request.string)),
|
u16string_to_tchar_pointer(request.string)),
|
||||||
@@ -413,19 +432,19 @@ void Vst3Bridge::run() {
|
|||||||
[&](const YaEditController::NormalizedParamToPlain& request)
|
[&](const YaEditController::NormalizedParamToPlain& request)
|
||||||
-> YaEditController::NormalizedParamToPlain::Response {
|
-> YaEditController::NormalizedParamToPlain::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.edit_controller->normalizedParamToPlain(
|
.interfaces.edit_controller->normalizedParamToPlain(
|
||||||
request.id, request.value_normalized);
|
request.id, request.value_normalized);
|
||||||
},
|
},
|
||||||
[&](const YaEditController::PlainParamToNormalized& request)
|
[&](const YaEditController::PlainParamToNormalized& request)
|
||||||
-> YaEditController::PlainParamToNormalized::Response {
|
-> YaEditController::PlainParamToNormalized::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.edit_controller->plainParamToNormalized(
|
.interfaces.edit_controller->plainParamToNormalized(
|
||||||
request.id, request.plain_value);
|
request.id, request.plain_value);
|
||||||
},
|
},
|
||||||
[&](const YaEditController::GetParamNormalized& request)
|
[&](const YaEditController::GetParamNormalized& request)
|
||||||
-> YaEditController::GetParamNormalized::Response {
|
-> YaEditController::GetParamNormalized::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.edit_controller->getParamNormalized(request.id);
|
.interfaces.edit_controller->getParamNormalized(request.id);
|
||||||
},
|
},
|
||||||
[&](const YaEditController::SetParamNormalized& request)
|
[&](const YaEditController::SetParamNormalized& request)
|
||||||
-> YaEditController::SetParamNormalized::Response {
|
-> YaEditController::SetParamNormalized::Response {
|
||||||
@@ -436,48 +455,48 @@ void Vst3Bridge::run() {
|
|||||||
// announced.
|
// announced.
|
||||||
return do_mutual_recursion_on_off_thread([&]() -> tresult {
|
return do_mutual_recursion_on_off_thread([&]() -> tresult {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.edit_controller->setParamNormalized(request.id,
|
.interfaces.edit_controller->setParamNormalized(
|
||||||
request.value);
|
request.id, request.value);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[&](YaEditController::SetComponentHandler& request)
|
[&](YaEditController::SetComponentHandler& request)
|
||||||
-> YaEditController::SetComponentHandler::Response {
|
-> YaEditController::SetComponentHandler::Response {
|
||||||
|
Vst3PluginInstance& instance =
|
||||||
|
object_instances.at(request.instance_id);
|
||||||
|
|
||||||
// If the host passed a valid component handler, then we'll
|
// If the host passed a valid component handler, then we'll
|
||||||
// create a proxy object for the component handler and pass that
|
// create a proxy object for the component handler and pass that
|
||||||
// to the initialize function. The lifetime of this object is
|
// to the initialize function. The lifetime of this object is
|
||||||
// tied to that of the actual plugin object we're proxying for.
|
// tied to that of the actual plugin object we're proxying for.
|
||||||
// Otherwise we'll also pass a null pointer. This often happens
|
// Otherwise we'll also pass a null pointer. This often happens
|
||||||
// just before the host terminates the plugin.
|
// just before the host terminates the plugin.
|
||||||
object_instances.at(request.instance_id)
|
instance.component_handler_proxy =
|
||||||
.component_handler_proxy =
|
|
||||||
request.component_handler_proxy_args
|
request.component_handler_proxy_args
|
||||||
? Steinberg::owned(new Vst3ComponentHandlerProxyImpl(
|
? Steinberg::owned(new Vst3ComponentHandlerProxyImpl(
|
||||||
*this,
|
*this,
|
||||||
std::move(*request.component_handler_proxy_args)))
|
std::move(*request.component_handler_proxy_args)))
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
|
||||||
return object_instances.at(request.instance_id)
|
return instance.interfaces.edit_controller->setComponentHandler(
|
||||||
.edit_controller->setComponentHandler(
|
instance.component_handler_proxy);
|
||||||
object_instances.at(request.instance_id)
|
|
||||||
.component_handler_proxy);
|
|
||||||
},
|
},
|
||||||
[&](const YaEditController::CreateView& request)
|
[&](const YaEditController::CreateView& request)
|
||||||
-> YaEditController::CreateView::Response {
|
-> YaEditController::CreateView::Response {
|
||||||
|
Vst3PluginInstance& instance =
|
||||||
|
object_instances.at(request.instance_id);
|
||||||
|
|
||||||
// Instantiate the object from the GUI thread
|
// Instantiate the object from the GUI thread
|
||||||
main_context
|
main_context
|
||||||
.run_in_context([&]() -> void {
|
.run_in_context([&]() -> void {
|
||||||
Steinberg::IPtr<Steinberg::IPlugView> plug_view(
|
Steinberg::IPtr<Steinberg::IPlugView> plug_view(
|
||||||
Steinberg::owned(
|
Steinberg::owned(
|
||||||
object_instances.at(request.instance_id)
|
instance.interfaces.edit_controller->createView(
|
||||||
.edit_controller->createView(
|
|
||||||
request.name.c_str())));
|
request.name.c_str())));
|
||||||
|
|
||||||
if (plug_view) {
|
if (plug_view) {
|
||||||
object_instances.at(request.instance_id)
|
instance.plug_view_instance.emplace(plug_view);
|
||||||
.plug_view_instance.emplace(plug_view);
|
|
||||||
} else {
|
} else {
|
||||||
object_instances.at(request.instance_id)
|
instance.plug_view_instance.reset();
|
||||||
.plug_view_instance.reset()
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.wait();
|
.wait();
|
||||||
@@ -486,40 +505,39 @@ void Vst3Bridge::run() {
|
|||||||
// `IPlugView` object
|
// `IPlugView` object
|
||||||
return YaEditController::CreateViewResponse{
|
return YaEditController::CreateViewResponse{
|
||||||
.plug_view_args =
|
.plug_view_args =
|
||||||
(object_instances.at(request.instance_id)
|
(instance.plug_view_instance
|
||||||
.plug_view_instance
|
|
||||||
? std::make_optional<
|
? std::make_optional<
|
||||||
Vst3PlugViewProxy::ConstructArgs>(
|
Vst3PlugViewProxy::ConstructArgs>(
|
||||||
object_instances.at(request.instance_id)
|
instance.plug_view_instance->plug_view,
|
||||||
.plug_view_instance->plug_view,
|
|
||||||
request.instance_id)
|
request.instance_id)
|
||||||
: std::nullopt)};
|
: std::nullopt)};
|
||||||
},
|
},
|
||||||
[&](const YaEditController2::SetKnobMode& request)
|
[&](const YaEditController2::SetKnobMode& request)
|
||||||
-> YaEditController2::SetKnobMode::Response {
|
-> YaEditController2::SetKnobMode::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.edit_controller_2->setKnobMode(request.mode);
|
.interfaces.edit_controller_2->setKnobMode(request.mode);
|
||||||
},
|
},
|
||||||
[&](const YaEditController2::OpenHelp& request)
|
[&](const YaEditController2::OpenHelp& request)
|
||||||
-> YaEditController2::OpenHelp::Response {
|
-> YaEditController2::OpenHelp::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.edit_controller_2->openHelp(request.only_check);
|
.interfaces.edit_controller_2->openHelp(request.only_check);
|
||||||
},
|
},
|
||||||
[&](const YaEditController2::OpenAboutBox& request)
|
[&](const YaEditController2::OpenAboutBox& request)
|
||||||
-> YaEditController2::OpenAboutBox::Response {
|
-> YaEditController2::OpenAboutBox::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.edit_controller_2->openAboutBox(request.only_check);
|
.interfaces.edit_controller_2->openAboutBox(
|
||||||
|
request.only_check);
|
||||||
},
|
},
|
||||||
[&](const YaEditControllerHostEditing::BeginEditFromHost& request)
|
[&](const YaEditControllerHostEditing::BeginEditFromHost& request)
|
||||||
-> YaEditControllerHostEditing::BeginEditFromHost::Response {
|
-> YaEditControllerHostEditing::BeginEditFromHost::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.edit_controller_host_editing->beginEditFromHost(
|
.interfaces.edit_controller_host_editing->beginEditFromHost(
|
||||||
request.param_id);
|
request.param_id);
|
||||||
},
|
},
|
||||||
[&](const YaEditControllerHostEditing::EndEditFromHost& request)
|
[&](const YaEditControllerHostEditing::EndEditFromHost& request)
|
||||||
-> YaEditControllerHostEditing::EndEditFromHost::Response {
|
-> YaEditControllerHostEditing::EndEditFromHost::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.edit_controller_host_editing->endEditFromHost(
|
.interfaces.edit_controller_host_editing->endEditFromHost(
|
||||||
request.param_id);
|
request.param_id);
|
||||||
},
|
},
|
||||||
[&](YaInfoListener::SetChannelContextInfos& request)
|
[&](YaInfoListener::SetChannelContextInfos& request)
|
||||||
@@ -530,7 +548,7 @@ void Vst3Bridge::run() {
|
|||||||
return main_context
|
return main_context
|
||||||
.run_in_context([&]() -> tresult {
|
.run_in_context([&]() -> tresult {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.info_listener->setChannelContextInfos(
|
.interfaces.info_listener->setChannelContextInfos(
|
||||||
&request.list);
|
&request.list);
|
||||||
})
|
})
|
||||||
.get();
|
.get();
|
||||||
@@ -538,15 +556,15 @@ void Vst3Bridge::run() {
|
|||||||
[&](const YaKeyswitchController::GetKeyswitchCount& request)
|
[&](const YaKeyswitchController::GetKeyswitchCount& request)
|
||||||
-> YaKeyswitchController::GetKeyswitchCount::Response {
|
-> YaKeyswitchController::GetKeyswitchCount::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.keyswitch_controller->getKeyswitchCount(request.bus_index,
|
.interfaces.keyswitch_controller->getKeyswitchCount(
|
||||||
request.channel);
|
request.bus_index, request.channel);
|
||||||
},
|
},
|
||||||
[&](const YaKeyswitchController::GetKeyswitchInfo& request)
|
[&](const YaKeyswitchController::GetKeyswitchInfo& request)
|
||||||
-> YaKeyswitchController::GetKeyswitchInfo::Response {
|
-> YaKeyswitchController::GetKeyswitchInfo::Response {
|
||||||
Steinberg::Vst::KeyswitchInfo info{};
|
Steinberg::Vst::KeyswitchInfo info{};
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.keyswitch_controller->getKeyswitchInfo(
|
.interfaces.keyswitch_controller->getKeyswitchInfo(
|
||||||
request.bus_index, request.channel,
|
request.bus_index, request.channel,
|
||||||
request.key_switch_index, info);
|
request.key_switch_index, info);
|
||||||
|
|
||||||
@@ -556,7 +574,7 @@ void Vst3Bridge::run() {
|
|||||||
[&](const YaMidiLearn::OnLiveMIDIControllerInput& request)
|
[&](const YaMidiLearn::OnLiveMIDIControllerInput& request)
|
||||||
-> YaMidiLearn::OnLiveMIDIControllerInput::Response {
|
-> YaMidiLearn::OnLiveMIDIControllerInput::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.midi_learn->onLiveMIDIControllerInput(
|
.interfaces.midi_learn->onLiveMIDIControllerInput(
|
||||||
request.bus_index, request.channel, request.midi_cc);
|
request.bus_index, request.channel, request.midi_cc);
|
||||||
},
|
},
|
||||||
[&](const YaMidiMapping::GetMidiControllerAssignment& request)
|
[&](const YaMidiMapping::GetMidiControllerAssignment& request)
|
||||||
@@ -564,7 +582,7 @@ void Vst3Bridge::run() {
|
|||||||
Steinberg::Vst::ParamID id;
|
Steinberg::Vst::ParamID id;
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.midi_mapping->getMidiControllerAssignment(
|
.interfaces.midi_mapping->getMidiControllerAssignment(
|
||||||
request.bus_index, request.channel,
|
request.bus_index, request.channel,
|
||||||
request.midi_controller_number, id);
|
request.midi_controller_number, id);
|
||||||
|
|
||||||
@@ -572,12 +590,14 @@ void Vst3Bridge::run() {
|
|||||||
.result = result, .id = id};
|
.result = result, .id = id};
|
||||||
},
|
},
|
||||||
[&](const YaNoteExpressionController::GetNoteExpressionCount&
|
[&](const YaNoteExpressionController::GetNoteExpressionCount&
|
||||||
request)
|
request) -> YaNoteExpressionController::
|
||||||
-> YaNoteExpressionController::GetNoteExpressionCount::
|
GetNoteExpressionCount::Response {
|
||||||
Response {
|
return object_instances
|
||||||
return object_instances.at(request.instance_id)
|
.at(request.instance_id)
|
||||||
.note_expression_controller->getNoteExpressionCount(
|
.interfaces.note_expression_controller
|
||||||
request.bus_index, request.channel);
|
->getNoteExpressionCount(
|
||||||
|
request.bus_index,
|
||||||
|
request.channel);
|
||||||
},
|
},
|
||||||
[&](const YaNoteExpressionController::GetNoteExpressionInfo&
|
[&](const YaNoteExpressionController::GetNoteExpressionInfo&
|
||||||
request)
|
request)
|
||||||
@@ -585,7 +605,8 @@ void Vst3Bridge::run() {
|
|||||||
Steinberg::Vst::NoteExpressionTypeInfo info{};
|
Steinberg::Vst::NoteExpressionTypeInfo info{};
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.note_expression_controller->getNoteExpressionInfo(
|
.interfaces.note_expression_controller
|
||||||
|
->getNoteExpressionInfo(
|
||||||
request.bus_index, request.channel,
|
request.bus_index, request.channel,
|
||||||
request.note_expression_index, info);
|
request.note_expression_index, info);
|
||||||
|
|
||||||
@@ -600,7 +621,7 @@ void Vst3Bridge::run() {
|
|||||||
Steinberg::Vst::String128 string{0};
|
Steinberg::Vst::String128 string{0};
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.note_expression_controller
|
.interfaces.note_expression_controller
|
||||||
->getNoteExpressionStringByValue(
|
->getNoteExpressionStringByValue(
|
||||||
request.bus_index, request.channel,
|
request.bus_index, request.channel,
|
||||||
request.id, request.value_normalized,
|
request.id, request.value_normalized,
|
||||||
@@ -618,7 +639,7 @@ void Vst3Bridge::run() {
|
|||||||
Steinberg::Vst::NoteExpressionValue value_normalized;
|
Steinberg::Vst::NoteExpressionValue value_normalized;
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.note_expression_controller
|
.interfaces.note_expression_controller
|
||||||
->getNoteExpressionValueByString(
|
->getNoteExpressionValueByString(
|
||||||
request.bus_index, request.channel,
|
request.bus_index, request.channel,
|
||||||
request.id,
|
request.id,
|
||||||
@@ -638,7 +659,7 @@ void Vst3Bridge::run() {
|
|||||||
request.list.get();
|
request.list.get();
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.note_expression_physical_ui_mapping
|
.interfaces.note_expression_physical_ui_mapping
|
||||||
->getPhysicalUIMapping(request.bus_index,
|
->getPhysicalUIMapping(request.bus_index,
|
||||||
request.channel,
|
request.channel,
|
||||||
reconstructed_list);
|
reconstructed_list);
|
||||||
@@ -660,22 +681,20 @@ void Vst3Bridge::run() {
|
|||||||
.result = result, .result_tag = result_tag};
|
.result = result, .result_tag = result_tag};
|
||||||
},
|
},
|
||||||
[&](const YaParameterFunctionName::GetParameterIDFromFunctionName&
|
[&](const YaParameterFunctionName::GetParameterIDFromFunctionName&
|
||||||
request) -> YaParameterFunctionName::
|
request)
|
||||||
GetParameterIDFromFunctionName::Response {
|
-> YaParameterFunctionName::GetParameterIDFromFunctionName::
|
||||||
|
Response {
|
||||||
Steinberg::Vst::ParamID param_id;
|
Steinberg::Vst::ParamID param_id;
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances
|
object_instances.at(request.instance_id)
|
||||||
.at(request.instance_id)
|
.interfaces.parameter_function_name
|
||||||
.parameter_function_name
|
|
||||||
->getParameterIDFromFunctionName(
|
->getParameterIDFromFunctionName(
|
||||||
request.unit_id,
|
request.unit_id,
|
||||||
request.function_name.c_str(),
|
request.function_name.c_str(), param_id);
|
||||||
param_id);
|
|
||||||
|
|
||||||
return YaParameterFunctionName::
|
return YaParameterFunctionName::
|
||||||
GetParameterIDFromFunctionNameResponse{
|
GetParameterIDFromFunctionNameResponse{
|
||||||
.result = result,
|
.result = result, .param_id = param_id};
|
||||||
.param_id = param_id};
|
|
||||||
},
|
},
|
||||||
[&](const YaPlugView::IsPlatformTypeSupported& request)
|
[&](const YaPlugView::IsPlatformTypeSupported& request)
|
||||||
-> YaPlugView::IsPlatformTypeSupported::Response {
|
-> YaPlugView::IsPlatformTypeSupported::Response {
|
||||||
@@ -889,11 +908,14 @@ void Vst3Bridge::run() {
|
|||||||
},
|
},
|
||||||
[&](YaPluginBase::Initialize& request)
|
[&](YaPluginBase::Initialize& request)
|
||||||
-> YaPluginBase::Initialize::Response {
|
-> YaPluginBase::Initialize::Response {
|
||||||
|
Vst3PluginInstance& instance =
|
||||||
|
object_instances.at(request.instance_id);
|
||||||
|
|
||||||
// We'll create a proxy object for the host context passed by
|
// We'll create a proxy object for the host context passed by
|
||||||
// the host and pass that to the initialize function. The
|
// the host and pass that to the initialize function. The
|
||||||
// lifetime of this object is tied to that of the actual plugin
|
// lifetime of this object is tied to that of the actual plugin
|
||||||
// object we're proxying for.
|
// object we're proxying for.
|
||||||
object_instances.at(request.instance_id).host_context_proxy =
|
instance.host_context_proxy =
|
||||||
Steinberg::owned(new Vst3HostContextProxyImpl(
|
Steinberg::owned(new Vst3HostContextProxyImpl(
|
||||||
*this, std::move(request.host_context_args)));
|
*this, std::move(request.host_context_args)));
|
||||||
|
|
||||||
@@ -907,18 +929,15 @@ void Vst3Bridge::run() {
|
|||||||
set_realtime_priority(true);
|
set_realtime_priority(true);
|
||||||
// This static cast is required to upcast to `FUnknown*`
|
// This static cast is required to upcast to `FUnknown*`
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
instance.interfaces.plugin_base->initialize(
|
||||||
.plugin_base->initialize(
|
|
||||||
static_cast<YaHostApplication*>(
|
static_cast<YaHostApplication*>(
|
||||||
object_instances.at(request.instance_id)
|
instance.host_context_proxy));
|
||||||
.host_context_proxy));
|
|
||||||
set_realtime_priority(false);
|
set_realtime_priority(false);
|
||||||
|
|
||||||
// The Win32 message loop will not be run up to this
|
// The Win32 message loop will not be run up to this
|
||||||
// point to prevent plugins with partially initialized
|
// point to prevent plugins with partially initialized
|
||||||
// states from misbehaving
|
// states from misbehaving
|
||||||
object_instances.at(request.instance_id)
|
instance.is_initialized = true;
|
||||||
.is_initialized = true;
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
})
|
})
|
||||||
@@ -929,28 +948,29 @@ void Vst3Bridge::run() {
|
|||||||
return main_context
|
return main_context
|
||||||
.run_in_context([&]() -> tresult {
|
.run_in_context([&]() -> tresult {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.plugin_base->terminate();
|
.interfaces.plugin_base->terminate();
|
||||||
})
|
})
|
||||||
.get();
|
.get();
|
||||||
},
|
},
|
||||||
[&](const YaProgramListData::ProgramDataSupported& request)
|
[&](const YaProgramListData::ProgramDataSupported& request)
|
||||||
-> YaProgramListData::ProgramDataSupported::Response {
|
-> YaProgramListData::ProgramDataSupported::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.program_list_data->programDataSupported(request.list_id);
|
.interfaces.program_list_data->programDataSupported(
|
||||||
|
request.list_id);
|
||||||
},
|
},
|
||||||
[&](const YaProcessContextRequirements::
|
[&](const YaProcessContextRequirements::
|
||||||
GetProcessContextRequirements& request)
|
GetProcessContextRequirements& request)
|
||||||
-> YaProcessContextRequirements::GetProcessContextRequirements::
|
-> YaProcessContextRequirements::GetProcessContextRequirements::
|
||||||
Response {
|
Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.process_context_requirements
|
.interfaces.process_context_requirements
|
||||||
->getProcessContextRequirements();
|
->getProcessContextRequirements();
|
||||||
},
|
},
|
||||||
[&](YaProgramListData::GetProgramData& request)
|
[&](YaProgramListData::GetProgramData& request)
|
||||||
-> YaProgramListData::GetProgramData::Response {
|
-> YaProgramListData::GetProgramData::Response {
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.program_list_data->getProgramData(
|
.interfaces.program_list_data->getProgramData(
|
||||||
request.list_id, request.program_index,
|
request.list_id, request.program_index,
|
||||||
&request.data);
|
&request.data);
|
||||||
|
|
||||||
@@ -960,19 +980,19 @@ void Vst3Bridge::run() {
|
|||||||
[&](YaProgramListData::SetProgramData& request)
|
[&](YaProgramListData::SetProgramData& request)
|
||||||
-> YaProgramListData::SetProgramData::Response {
|
-> YaProgramListData::SetProgramData::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.program_list_data->setProgramData(
|
.interfaces.program_list_data->setProgramData(
|
||||||
request.list_id, request.program_index, &request.data);
|
request.list_id, request.program_index, &request.data);
|
||||||
},
|
},
|
||||||
[&](const YaUnitData::UnitDataSupported& request)
|
[&](const YaUnitData::UnitDataSupported& request)
|
||||||
-> YaUnitData::UnitDataSupported::Response {
|
-> YaUnitData::UnitDataSupported::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.unit_data->unitDataSupported(request.unit_id);
|
.interfaces.unit_data->unitDataSupported(request.unit_id);
|
||||||
},
|
},
|
||||||
[&](YaUnitData::GetUnitData& request)
|
[&](YaUnitData::GetUnitData& request)
|
||||||
-> YaUnitData::GetUnitData::Response {
|
-> YaUnitData::GetUnitData::Response {
|
||||||
const tresult result =
|
const tresult result = object_instances.at(request.instance_id)
|
||||||
object_instances.at(request.instance_id)
|
.interfaces.unit_data->getUnitData(
|
||||||
.unit_data->getUnitData(request.unit_id, &request.data);
|
request.unit_id, &request.data);
|
||||||
|
|
||||||
return YaUnitData::GetUnitDataResponse{
|
return YaUnitData::GetUnitDataResponse{
|
||||||
.result = result, .data = std::move(request.data)};
|
.result = result, .data = std::move(request.data)};
|
||||||
@@ -980,7 +1000,8 @@ void Vst3Bridge::run() {
|
|||||||
[&](YaUnitData::SetUnitData& request)
|
[&](YaUnitData::SetUnitData& request)
|
||||||
-> YaUnitData::SetUnitData::Response {
|
-> YaUnitData::SetUnitData::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.unit_data->setUnitData(request.unit_id, &request.data);
|
.interfaces.unit_data->setUnitData(request.unit_id,
|
||||||
|
&request.data);
|
||||||
},
|
},
|
||||||
[&](YaPluginFactory3::SetHostContext& request)
|
[&](YaPluginFactory3::SetHostContext& request)
|
||||||
-> YaPluginFactory3::SetHostContext::Response {
|
-> YaPluginFactory3::SetHostContext::Response {
|
||||||
@@ -1000,14 +1021,14 @@ void Vst3Bridge::run() {
|
|||||||
[&](const YaUnitInfo::GetUnitCount& request)
|
[&](const YaUnitInfo::GetUnitCount& request)
|
||||||
-> YaUnitInfo::GetUnitCount::Response {
|
-> YaUnitInfo::GetUnitCount::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.unit_info->getUnitCount();
|
.interfaces.unit_info->getUnitCount();
|
||||||
},
|
},
|
||||||
[&](const YaUnitInfo::GetUnitInfo& request)
|
[&](const YaUnitInfo::GetUnitInfo& request)
|
||||||
-> YaUnitInfo::GetUnitInfo::Response {
|
-> YaUnitInfo::GetUnitInfo::Response {
|
||||||
Steinberg::Vst::UnitInfo info{};
|
Steinberg::Vst::UnitInfo info{};
|
||||||
const tresult result =
|
const tresult result = object_instances.at(request.instance_id)
|
||||||
object_instances.at(request.instance_id)
|
.interfaces.unit_info->getUnitInfo(
|
||||||
.unit_info->getUnitInfo(request.unit_index, info);
|
request.unit_index, info);
|
||||||
|
|
||||||
return YaUnitInfo::GetUnitInfoResponse{.result = result,
|
return YaUnitInfo::GetUnitInfoResponse{.result = result,
|
||||||
.info = std::move(info)};
|
.info = std::move(info)};
|
||||||
@@ -1015,13 +1036,14 @@ void Vst3Bridge::run() {
|
|||||||
[&](const YaUnitInfo::GetProgramListCount& request)
|
[&](const YaUnitInfo::GetProgramListCount& request)
|
||||||
-> YaUnitInfo::GetProgramListCount::Response {
|
-> YaUnitInfo::GetProgramListCount::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.unit_info->getProgramListCount();
|
.interfaces.unit_info->getProgramListCount();
|
||||||
},
|
},
|
||||||
[&](const YaUnitInfo::GetProgramListInfo& request)
|
[&](const YaUnitInfo::GetProgramListInfo& request)
|
||||||
-> YaUnitInfo::GetProgramListInfo::Response {
|
-> YaUnitInfo::GetProgramListInfo::Response {
|
||||||
Steinberg::Vst::ProgramListInfo info{};
|
Steinberg::Vst::ProgramListInfo info{};
|
||||||
const tresult result = object_instances.at(request.instance_id)
|
const tresult result =
|
||||||
.unit_info->getProgramListInfo(
|
object_instances.at(request.instance_id)
|
||||||
|
.interfaces.unit_info->getProgramListInfo(
|
||||||
request.list_index, info);
|
request.list_index, info);
|
||||||
|
|
||||||
return YaUnitInfo::GetProgramListInfoResponse{
|
return YaUnitInfo::GetProgramListInfoResponse{
|
||||||
@@ -1037,7 +1059,7 @@ void Vst3Bridge::run() {
|
|||||||
const tresult result =
|
const tresult result =
|
||||||
do_mutual_recursion_on_off_thread([&]() -> tresult {
|
do_mutual_recursion_on_off_thread([&]() -> tresult {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.unit_info->getProgramName(
|
.interfaces.unit_info->getProgramName(
|
||||||
request.list_id, request.program_index, name);
|
request.list_id, request.program_index, name);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1049,7 +1071,7 @@ void Vst3Bridge::run() {
|
|||||||
Steinberg::Vst::String128 attribute_value{0};
|
Steinberg::Vst::String128 attribute_value{0};
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.unit_info->getProgramInfo(
|
.interfaces.unit_info->getProgramInfo(
|
||||||
request.list_id, request.program_index,
|
request.list_id, request.program_index,
|
||||||
request.attribute_id.c_str(), attribute_value);
|
request.attribute_id.c_str(), attribute_value);
|
||||||
|
|
||||||
@@ -1061,15 +1083,15 @@ void Vst3Bridge::run() {
|
|||||||
[&](const YaUnitInfo::HasProgramPitchNames& request)
|
[&](const YaUnitInfo::HasProgramPitchNames& request)
|
||||||
-> YaUnitInfo::HasProgramPitchNames::Response {
|
-> YaUnitInfo::HasProgramPitchNames::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.unit_info->hasProgramPitchNames(request.list_id,
|
.interfaces.unit_info->hasProgramPitchNames(
|
||||||
request.program_index);
|
request.list_id, request.program_index);
|
||||||
},
|
},
|
||||||
[&](const YaUnitInfo::GetProgramPitchName& request)
|
[&](const YaUnitInfo::GetProgramPitchName& request)
|
||||||
-> YaUnitInfo::GetProgramPitchName::Response {
|
-> YaUnitInfo::GetProgramPitchName::Response {
|
||||||
Steinberg::Vst::String128 name{0};
|
Steinberg::Vst::String128 name{0};
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.unit_info->getProgramPitchName(
|
.interfaces.unit_info->getProgramPitchName(
|
||||||
request.list_id, request.program_index,
|
request.list_id, request.program_index,
|
||||||
request.midi_pitch, name);
|
request.midi_pitch, name);
|
||||||
|
|
||||||
@@ -1079,20 +1101,20 @@ void Vst3Bridge::run() {
|
|||||||
[&](const YaUnitInfo::GetSelectedUnit& request)
|
[&](const YaUnitInfo::GetSelectedUnit& request)
|
||||||
-> YaUnitInfo::GetSelectedUnit::Response {
|
-> YaUnitInfo::GetSelectedUnit::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.unit_info->getSelectedUnit();
|
.interfaces.unit_info->getSelectedUnit();
|
||||||
},
|
},
|
||||||
[&](const YaUnitInfo::SelectUnit& request)
|
[&](const YaUnitInfo::SelectUnit& request)
|
||||||
-> YaUnitInfo::SelectUnit::Response {
|
-> YaUnitInfo::SelectUnit::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.unit_info->selectUnit(request.unit_id);
|
.interfaces.unit_info->selectUnit(request.unit_id);
|
||||||
},
|
},
|
||||||
[&](const YaUnitInfo::GetUnitByBus& request)
|
[&](const YaUnitInfo::GetUnitByBus& request)
|
||||||
-> YaUnitInfo::GetUnitByBus::Response {
|
-> YaUnitInfo::GetUnitByBus::Response {
|
||||||
Steinberg::Vst::UnitID unit_id;
|
Steinberg::Vst::UnitID unit_id;
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.unit_info->getUnitByBus(request.type, request.dir,
|
.interfaces.unit_info->getUnitByBus(
|
||||||
request.bus_index,
|
request.type, request.dir, request.bus_index,
|
||||||
request.channel, unit_id);
|
request.channel, unit_id);
|
||||||
|
|
||||||
return YaUnitInfo::GetUnitByBusResponse{.result = result,
|
return YaUnitInfo::GetUnitByBusResponse{.result = result,
|
||||||
@@ -1101,25 +1123,24 @@ void Vst3Bridge::run() {
|
|||||||
[&](YaUnitInfo::SetUnitProgramData& request)
|
[&](YaUnitInfo::SetUnitProgramData& request)
|
||||||
-> YaUnitInfo::SetUnitProgramData::Response {
|
-> YaUnitInfo::SetUnitProgramData::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.unit_info->setUnitProgramData(request.list_or_unit_id,
|
.interfaces.unit_info->setUnitProgramData(
|
||||||
request.program_index,
|
request.list_or_unit_id, request.program_index,
|
||||||
&request.data);
|
&request.data);
|
||||||
},
|
},
|
||||||
[&](YaXmlRepresentationController::GetXmlRepresentationStream&
|
[&](YaXmlRepresentationController::GetXmlRepresentationStream&
|
||||||
request) -> YaXmlRepresentationController::
|
request)
|
||||||
GetXmlRepresentationStream::Response {
|
-> YaXmlRepresentationController::GetXmlRepresentationStream::
|
||||||
|
Response {
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances
|
object_instances.at(request.instance_id)
|
||||||
.at(request.instance_id)
|
.interfaces.xml_representation_controller
|
||||||
.xml_representation_controller
|
->getXmlRepresentationStream(request.info,
|
||||||
->getXmlRepresentationStream(
|
&request.stream);
|
||||||
request.info, &request.stream);
|
|
||||||
|
|
||||||
return YaXmlRepresentationController::
|
return YaXmlRepresentationController::
|
||||||
GetXmlRepresentationStreamResponse{
|
GetXmlRepresentationStreamResponse{
|
||||||
.result = result,
|
.result = result,
|
||||||
.stream =
|
.stream = std::move(request.stream)};
|
||||||
std::move(request.stream)};
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1164,10 +1185,12 @@ size_t Vst3Bridge::generate_instance_id() noexcept {
|
|||||||
AudioShmBuffer::Config Vst3Bridge::setup_shared_audio_buffers(
|
AudioShmBuffer::Config Vst3Bridge::setup_shared_audio_buffers(
|
||||||
size_t instance_id,
|
size_t instance_id,
|
||||||
const Steinberg::Vst::ProcessSetup& setup) {
|
const Steinberg::Vst::ProcessSetup& setup) {
|
||||||
|
auto& instance = object_instances.at(instance_id);
|
||||||
|
|
||||||
const Steinberg::IPtr<Steinberg::Vst::IComponent> component =
|
const Steinberg::IPtr<Steinberg::Vst::IComponent> component =
|
||||||
object_instances.at(instance_id).component;
|
instance.interfaces.component;
|
||||||
const Steinberg::IPtr<Steinberg::Vst::IAudioProcessor> audio_processor =
|
const Steinberg::IPtr<Steinberg::Vst::IAudioProcessor> audio_processor =
|
||||||
object_instances.at(instance_id).audio_processor;
|
instance.interfaces.audio_processor;
|
||||||
assert(component && audio_processor);
|
assert(component && audio_processor);
|
||||||
|
|
||||||
// We'll query the plugin for its audio bus layouts, and then create
|
// We'll query the plugin for its audio bus layouts, and then create
|
||||||
@@ -1225,13 +1248,10 @@ AudioShmBuffer::Config Vst3Bridge::setup_shared_audio_buffers(
|
|||||||
.size = buffer_size,
|
.size = buffer_size,
|
||||||
.input_offsets = std::move(input_bus_offsets),
|
.input_offsets = std::move(input_bus_offsets),
|
||||||
.output_offsets = std::move(output_bus_offsets)};
|
.output_offsets = std::move(output_bus_offsets)};
|
||||||
|
if (!instance.process_buffers) {
|
||||||
std::optional<AudioShmBuffer>& process_buffers =
|
instance.process_buffers.emplace(buffer_config);
|
||||||
object_instances.at(instance_id).process_buffers;
|
|
||||||
if (!process_buffers) {
|
|
||||||
process_buffers.emplace(buffer_config);
|
|
||||||
} else {
|
} else {
|
||||||
process_buffers->resize(buffer_config);
|
instance.process_buffers->resize(buffer_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// After setting up the shared memory buffer, we need to create a vector of
|
// After setting up the shared memory buffer, we need to create a vector of
|
||||||
@@ -1258,24 +1278,27 @@ AudioShmBuffer::Config Vst3Bridge::setup_shared_audio_buffers(
|
|||||||
};
|
};
|
||||||
|
|
||||||
set_bus_pointers(
|
set_bus_pointers(
|
||||||
object_instances.at(instance_id).process_buffers_input_pointers,
|
instance.process_buffers_input_pointers,
|
||||||
process_buffers->config.input_offsets,
|
instance.process_buffers->config.input_offsets,
|
||||||
[&](uint32_t bus, uint32_t channel) -> void* {
|
[&](uint32_t bus, uint32_t channel) -> void* {
|
||||||
if (double_precision) {
|
if (double_precision) {
|
||||||
return process_buffers->input_channel_ptr<double>(bus, channel);
|
return instance.process_buffers->input_channel_ptr<double>(
|
||||||
|
bus, channel);
|
||||||
} else {
|
} else {
|
||||||
return process_buffers->input_channel_ptr<float>(bus, channel);
|
return instance.process_buffers->input_channel_ptr<float>(
|
||||||
|
bus, channel);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
set_bus_pointers(
|
set_bus_pointers(
|
||||||
object_instances.at(instance_id).process_buffers_output_pointers,
|
instance.process_buffers_output_pointers,
|
||||||
process_buffers->config.output_offsets,
|
instance.process_buffers->config.output_offsets,
|
||||||
[&](uint32_t bus, uint32_t channel) -> void* {
|
[&](uint32_t bus, uint32_t channel) -> void* {
|
||||||
if (double_precision) {
|
if (double_precision) {
|
||||||
return process_buffers->output_channel_ptr<double>(bus,
|
return instance.process_buffers->output_channel_ptr<double>(
|
||||||
channel);
|
bus, channel);
|
||||||
} else {
|
} else {
|
||||||
return process_buffers->output_channel_ptr<float>(bus, channel);
|
return instance.process_buffers->output_channel_ptr<float>(
|
||||||
|
bus, channel);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1292,8 +1315,8 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
// If the object supports `IComponent` or `IAudioProcessor`,
|
// If the object supports `IComponent` or `IAudioProcessor`,
|
||||||
// then we'll set up a dedicated thread for function calls for
|
// then we'll set up a dedicated thread for function calls for
|
||||||
// those interfaces.
|
// those interfaces.
|
||||||
if (object_instances.at(instance_id).audio_processor ||
|
if (object_instances.at(instance_id).interfaces.audio_processor ||
|
||||||
object_instances.at(instance_id).component) {
|
object_instances.at(instance_id).interfaces.component) {
|
||||||
std::promise<void> socket_listening_latch;
|
std::promise<void> socket_listening_latch;
|
||||||
|
|
||||||
object_instances.at(instance_id)
|
object_instances.at(instance_id)
|
||||||
@@ -1320,7 +1343,7 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
0b00000000;
|
0b00000000;
|
||||||
|
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.audio_processor->setBusArrangements(
|
.interfaces.audio_processor->setBusArrangements(
|
||||||
request.num_ins > 0 ? request.inputs.data()
|
request.num_ins > 0 ? request.inputs.data()
|
||||||
: &empty_arrangement,
|
: &empty_arrangement,
|
||||||
request.num_ins,
|
request.num_ins,
|
||||||
@@ -1333,7 +1356,7 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
Steinberg::Vst::SpeakerArrangement arr{};
|
Steinberg::Vst::SpeakerArrangement arr{};
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.audio_processor->getBusArrangement(
|
.interfaces.audio_processor->getBusArrangement(
|
||||||
request.dir, request.index, arr);
|
request.dir, request.index, arr);
|
||||||
|
|
||||||
return YaAudioProcessor::GetBusArrangementResponse{
|
return YaAudioProcessor::GetBusArrangementResponse{
|
||||||
@@ -1342,19 +1365,19 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
[&](const YaAudioProcessor::CanProcessSampleSize& request)
|
[&](const YaAudioProcessor::CanProcessSampleSize& request)
|
||||||
-> YaAudioProcessor::CanProcessSampleSize::Response {
|
-> YaAudioProcessor::CanProcessSampleSize::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.audio_processor->canProcessSampleSize(
|
.interfaces.audio_processor->canProcessSampleSize(
|
||||||
request.symbolic_sample_size);
|
request.symbolic_sample_size);
|
||||||
},
|
},
|
||||||
[&](const YaAudioProcessor::GetLatencySamples& request)
|
[&](const YaAudioProcessor::GetLatencySamples& request)
|
||||||
-> YaAudioProcessor::GetLatencySamples::Response {
|
-> YaAudioProcessor::GetLatencySamples::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.audio_processor->getLatencySamples();
|
.interfaces.audio_processor->getLatencySamples();
|
||||||
},
|
},
|
||||||
[&](YaAudioProcessor::SetupProcessing& request)
|
[&](YaAudioProcessor::SetupProcessing& request)
|
||||||
-> YaAudioProcessor::SetupProcessing::Response {
|
-> YaAudioProcessor::SetupProcessing::Response {
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.audio_processor->setupProcessing(
|
.interfaces.audio_processor->setupProcessing(
|
||||||
request.setup);
|
request.setup);
|
||||||
|
|
||||||
// We'll set up the shared audio buffers on the Wine
|
// We'll set up the shared audio buffers on the Wine
|
||||||
@@ -1374,7 +1397,8 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
[&](const YaAudioProcessor::SetProcessing& request)
|
[&](const YaAudioProcessor::SetProcessing& request)
|
||||||
-> YaAudioProcessor::SetProcessing::Response {
|
-> YaAudioProcessor::SetProcessing::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.audio_processor->setProcessing(request.state);
|
.interfaces.audio_processor->setProcessing(
|
||||||
|
request.state);
|
||||||
},
|
},
|
||||||
[&](MessageReference<YaAudioProcessor::Process>&
|
[&](MessageReference<YaAudioProcessor::Process>&
|
||||||
request_ref)
|
request_ref)
|
||||||
@@ -1388,12 +1412,6 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
// `bitsery::ext::MessageReference`)
|
// `bitsery::ext::MessageReference`)
|
||||||
YaAudioProcessor::Process& request = request_ref.get();
|
YaAudioProcessor::Process& request = request_ref.get();
|
||||||
|
|
||||||
// Most plugins will already enable FTZ, but there are a
|
|
||||||
// handful of plugins that don't that suffer from
|
|
||||||
// extreme DSP load increases when they start producing
|
|
||||||
// denormals
|
|
||||||
ScopedFlushToZero ftz_guard;
|
|
||||||
|
|
||||||
// As suggested by Jack Winter, we'll synchronize this
|
// As suggested by Jack Winter, we'll synchronize this
|
||||||
// thread's audio processing priority with that of the
|
// thread's audio processing priority with that of the
|
||||||
// host's audio thread every once in a while
|
// host's audio thread every once in a while
|
||||||
@@ -1402,17 +1420,23 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
true, *request.new_realtime_priority);
|
true, *request.new_realtime_priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vst3PluginInstance& instance =
|
||||||
|
object_instances.at(request.instance_id);
|
||||||
|
|
||||||
|
// Most plugins will already enable FTZ, but there are a
|
||||||
|
// handful of plugins that don't that suffer from
|
||||||
|
// extreme DSP load increases when they start producing
|
||||||
|
// denormals
|
||||||
|
ScopedFlushToZero ftz_guard;
|
||||||
|
|
||||||
// The actual audio is stored in the shared memory
|
// The actual audio is stored in the shared memory
|
||||||
// buffers, so the reconstruction function will need to
|
// buffers, so the reconstruction function will need to
|
||||||
// know where it should point the `AudioBusBuffers` to
|
// know where it should point the `AudioBusBuffers` to
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
instance.interfaces.audio_processor->process(
|
||||||
.audio_processor->process(
|
|
||||||
request.data.reconstruct(
|
request.data.reconstruct(
|
||||||
object_instances.at(request.instance_id)
|
instance.process_buffers_input_pointers,
|
||||||
.process_buffers_input_pointers,
|
instance.process_buffers_output_pointers));
|
||||||
object_instances.at(request.instance_id)
|
|
||||||
.process_buffers_output_pointers));
|
|
||||||
|
|
||||||
return YaAudioProcessor::ProcessResponse{
|
return YaAudioProcessor::ProcessResponse{
|
||||||
.result = result,
|
.result = result,
|
||||||
@@ -1421,14 +1445,15 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
[&](const YaAudioProcessor::GetTailSamples& request)
|
[&](const YaAudioProcessor::GetTailSamples& request)
|
||||||
-> YaAudioProcessor::GetTailSamples::Response {
|
-> YaAudioProcessor::GetTailSamples::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.audio_processor->getTailSamples();
|
.interfaces.audio_processor->getTailSamples();
|
||||||
},
|
},
|
||||||
[&](const YaComponent::GetControllerClassId& request)
|
[&](const YaComponent::GetControllerClassId& request)
|
||||||
-> YaComponent::GetControllerClassId::Response {
|
-> YaComponent::GetControllerClassId::Response {
|
||||||
Steinberg::TUID cid{0};
|
Steinberg::TUID cid{0};
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.component->getControllerClassId(cid);
|
.interfaces.component->getControllerClassId(
|
||||||
|
cid);
|
||||||
|
|
||||||
return YaComponent::GetControllerClassIdResponse{
|
return YaComponent::GetControllerClassIdResponse{
|
||||||
.result = result, .editor_cid = cid};
|
.result = result, .editor_cid = cid};
|
||||||
@@ -1436,21 +1461,22 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
[&](const YaComponent::SetIoMode& request)
|
[&](const YaComponent::SetIoMode& request)
|
||||||
-> YaComponent::SetIoMode::Response {
|
-> YaComponent::SetIoMode::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.component->setIoMode(request.mode);
|
.interfaces.component->setIoMode(request.mode);
|
||||||
},
|
},
|
||||||
[&](const YaComponent::GetBusCount& request)
|
[&](const YaComponent::GetBusCount& request)
|
||||||
-> YaComponent::GetBusCount::Response {
|
-> YaComponent::GetBusCount::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.component->getBusCount(request.type, request.dir);
|
.interfaces.component->getBusCount(request.type,
|
||||||
|
request.dir);
|
||||||
},
|
},
|
||||||
[&](YaComponent::GetBusInfo& request)
|
[&](YaComponent::GetBusInfo& request)
|
||||||
-> YaComponent::GetBusInfo::Response {
|
-> YaComponent::GetBusInfo::Response {
|
||||||
Steinberg::Vst::BusInfo bus{};
|
Steinberg::Vst::BusInfo bus{};
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.component->getBusInfo(request.type,
|
.interfaces.component->getBusInfo(
|
||||||
request.dir,
|
request.type, request.dir, request.index,
|
||||||
request.index, bus);
|
bus);
|
||||||
|
|
||||||
return YaComponent::GetBusInfoResponse{
|
return YaComponent::GetBusInfoResponse{
|
||||||
.result = result, .bus = std::move(bus)};
|
.result = result, .bus = std::move(bus)};
|
||||||
@@ -1460,8 +1486,8 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
Steinberg::Vst::RoutingInfo out_info{};
|
Steinberg::Vst::RoutingInfo out_info{};
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.component->getRoutingInfo(request.in_info,
|
.interfaces.component->getRoutingInfo(
|
||||||
out_info);
|
request.in_info, out_info);
|
||||||
|
|
||||||
return YaComponent::GetRoutingInfoResponse{
|
return YaComponent::GetRoutingInfoResponse{
|
||||||
.result = result, .out_info = std::move(out_info)};
|
.result = result, .out_info = std::move(out_info)};
|
||||||
@@ -1469,8 +1495,8 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
[&](const YaComponent::ActivateBus& request)
|
[&](const YaComponent::ActivateBus& request)
|
||||||
-> YaComponent::ActivateBus::Response {
|
-> YaComponent::ActivateBus::Response {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.component->activateBus(request.type, request.dir,
|
.interfaces.component->activateBus(
|
||||||
request.index,
|
request.type, request.dir, request.index,
|
||||||
request.state);
|
request.state);
|
||||||
},
|
},
|
||||||
[&](const YaComponent::SetActive& request)
|
[&](const YaComponent::SetActive& request)
|
||||||
@@ -1486,7 +1512,8 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
return do_mutual_recursion_on_off_thread(
|
return do_mutual_recursion_on_off_thread(
|
||||||
[&]() -> tresult {
|
[&]() -> tresult {
|
||||||
return object_instances.at(request.instance_id)
|
return object_instances.at(request.instance_id)
|
||||||
.component->setActive(request.state);
|
.interfaces.component->setActive(
|
||||||
|
request.state);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
[&](const YaPrefetchableSupport::GetPrefetchableSupport&
|
[&](const YaPrefetchableSupport::GetPrefetchableSupport&
|
||||||
@@ -1497,7 +1524,7 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
prefetchable;
|
prefetchable;
|
||||||
const tresult result =
|
const tresult result =
|
||||||
object_instances.at(request.instance_id)
|
object_instances.at(request.instance_id)
|
||||||
.prefetchable_support
|
.interfaces.prefetchable_support
|
||||||
->getPrefetchableSupport(prefetchable);
|
->getPrefetchableSupport(prefetchable);
|
||||||
|
|
||||||
return YaPrefetchableSupport::
|
return YaPrefetchableSupport::
|
||||||
@@ -1520,8 +1547,8 @@ size_t Vst3Bridge::register_object_instance(
|
|||||||
void Vst3Bridge::unregister_object_instance(size_t instance_id) {
|
void Vst3Bridge::unregister_object_instance(size_t instance_id) {
|
||||||
// Tear the dedicated audio processing socket down again if we
|
// Tear the dedicated audio processing socket down again if we
|
||||||
// created one while handling `Vst3PluginProxy::Construct`
|
// created one while handling `Vst3PluginProxy::Construct`
|
||||||
if (object_instances.at(instance_id).audio_processor ||
|
if (object_instances.at(instance_id).interfaces.audio_processor ||
|
||||||
object_instances.at(instance_id).component) {
|
object_instances.at(instance_id).interfaces.component) {
|
||||||
sockets.remove_audio_processor(instance_id);
|
sockets.remove_audio_processor(instance_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,12 +53,54 @@ struct Vst3PlugViewInterfaces {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A holder for plugin object instance created from the factory. This stores all
|
* Smart pointers for all interfaces a VST3 plugin object might support.
|
||||||
* relevant interface smart pointers to that object so we can handle control
|
*
|
||||||
* messages sent by the plugin without having to do these expensive casts all
|
* @relates Vst3PluginInstance
|
||||||
* the time. This also stores any additional context data, such as the
|
*/
|
||||||
* `IHostApplication` instance passed to the plugin during
|
struct Vst3PluginInterfaces {
|
||||||
* `IPluginBase::initialize()`.
|
Vst3PluginInterfaces(Steinberg::IPtr<Steinberg::FUnknown> object) noexcept;
|
||||||
|
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IAudioPresentationLatency>
|
||||||
|
audio_presentation_latency;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IAudioProcessor> audio_processor;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IAutomationState> automation_state;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IComponent> component;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IConnectionPoint> connection_point;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IEditController> edit_controller;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IEditController2> edit_controller_2;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IEditControllerHostEditing>
|
||||||
|
edit_controller_host_editing;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::ChannelContext::IInfoListener>
|
||||||
|
info_listener;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IKeyswitchController>
|
||||||
|
keyswitch_controller;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IMidiLearn> midi_learn;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IMidiMapping> midi_mapping;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::INoteExpressionController>
|
||||||
|
note_expression_controller;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::INoteExpressionPhysicalUIMapping>
|
||||||
|
note_expression_physical_ui_mapping;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::IPluginBase> plugin_base;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IUnitData> unit_data;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IParameterFunctionName>
|
||||||
|
parameter_function_name;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IPrefetchableSupport>
|
||||||
|
prefetchable_support;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IProcessContextRequirements>
|
||||||
|
process_context_requirements;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IProgramListData> program_list_data;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IUnitInfo> unit_info;
|
||||||
|
Steinberg::FUnknownPtr<Steinberg::Vst::IXmlRepresentationController>
|
||||||
|
xml_representation_controller;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A holder for plugin object instance created from the factory. This contains a
|
||||||
|
* smart pointer to the object's `FUnknown` interface and everything else we
|
||||||
|
* need to proxy for this object, like audio threads and proxy objects for
|
||||||
|
* callbacks. We also store an `interfaces` object that contains smart pointers
|
||||||
|
* to all relevant VST3 interface so we can handle control messages sent by the
|
||||||
|
* plugin without having to do these expensive casts all the time.
|
||||||
*/
|
*/
|
||||||
struct Vst3PluginInstance {
|
struct Vst3PluginInstance {
|
||||||
Vst3PluginInstance(Steinberg::IPtr<Steinberg::FUnknown> object) noexcept;
|
Vst3PluginInstance(Steinberg::IPtr<Steinberg::FUnknown> object) noexcept;
|
||||||
@@ -123,21 +165,6 @@ struct Vst3PluginInstance {
|
|||||||
registered_context_menus;
|
registered_context_menus;
|
||||||
std::mutex registered_context_menus_mutex;
|
std::mutex registered_context_menus_mutex;
|
||||||
|
|
||||||
/**
|
|
||||||
* The base object we cast from.
|
|
||||||
*/
|
|
||||||
Steinberg::IPtr<Steinberg::FUnknown> object;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The `IPlugView` object the plugin returned from a call to
|
|
||||||
* `IEditController::createView()`.
|
|
||||||
*
|
|
||||||
* XXX: Technically VST3 supports multiple named views, so we could have
|
|
||||||
* multiple different view for a single plugin. This is not used within
|
|
||||||
* the SDK, so a single pointer should be fine for now.
|
|
||||||
*/
|
|
||||||
std::optional<Vst3PlugViewInterfaces> plug_view_instance;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A shared memory object we'll write the input audio buffers to on the
|
* A shared memory object we'll write the input audio buffers to on the
|
||||||
* native plugin side. We'll then let the plugin write its outputs here on
|
* native plugin side. We'll then let the plugin write its outputs here on
|
||||||
@@ -172,41 +199,28 @@ struct Vst3PluginInstance {
|
|||||||
*/
|
*/
|
||||||
std::optional<Editor> editor;
|
std::optional<Editor> editor;
|
||||||
|
|
||||||
// All smart pointers below are created from `component`. They will be null
|
/**
|
||||||
// pointers if `component` did not implement the interface.
|
* The base object we cast from. This is upcasted form the object created by
|
||||||
|
* the factory.
|
||||||
|
*/
|
||||||
|
Steinberg::IPtr<Steinberg::FUnknown> object;
|
||||||
|
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IAudioPresentationLatency>
|
/**
|
||||||
audio_presentation_latency;
|
* The `IPlugView` object the plugin returned from a call to
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IAudioProcessor> audio_processor;
|
* `IEditController::createView()`. This object can also implement multiple
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IAutomationState> automation_state;
|
* interfaces.
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IComponent> component;
|
*
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IConnectionPoint> connection_point;
|
* XXX: Technically VST3 supports multiple named views, so we could have
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IEditController> edit_controller;
|
* multiple different view for a single plugin. This is not used within
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IEditController2> edit_controller_2;
|
* the SDK, so a single pointer should be fine for now.
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IEditControllerHostEditing>
|
*/
|
||||||
edit_controller_host_editing;
|
std::optional<Vst3PlugViewInterfaces> plug_view_instance;
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::ChannelContext::IInfoListener>
|
|
||||||
info_listener;
|
/**
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IKeyswitchController>
|
* This contains smart pointers to all VST3 plugin interfaces that can be
|
||||||
keyswitch_controller;
|
* casted from `object`.
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IMidiLearn> midi_learn;
|
*/
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IMidiMapping> midi_mapping;
|
Vst3PluginInterfaces interfaces;
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::INoteExpressionController>
|
|
||||||
note_expression_controller;
|
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::INoteExpressionPhysicalUIMapping>
|
|
||||||
note_expression_physical_ui_mapping;
|
|
||||||
Steinberg::FUnknownPtr<Steinberg::IPluginBase> plugin_base;
|
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IUnitData> unit_data;
|
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IParameterFunctionName>
|
|
||||||
parameter_function_name;
|
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IPrefetchableSupport>
|
|
||||||
prefetchable_support;
|
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IProcessContextRequirements>
|
|
||||||
process_context_requirements;
|
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IProgramListData> program_list_data;
|
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IUnitInfo> unit_info;
|
|
||||||
Steinberg::FUnknownPtr<Steinberg::Vst::IXmlRepresentationController>
|
|
||||||
xml_representation_controller;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether `IPluginBase:initialize()` has already been called for this
|
* Whether `IPluginBase:initialize()` has already been called for this
|
||||||
|
|||||||
Reference in New Issue
Block a user