mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 03:50:11 +02:00
Add a workaround for Bluecat Audio VST3 plugins
These plugins don't expose `IPluginBase` through the query interface, so we have to do this nasty coercion instead.
This commit is contained in:
@@ -10,6 +10,9 @@ Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
### Fixed
|
||||
|
||||
- Added a workaround for a bug present in every Bluecat Audio VST3 plugin where
|
||||
those plugins don't expose the `IPluginBase` interface through their query
|
||||
interface.
|
||||
- Worked around a regression in Wine 6.5 that would prevent yabridge from
|
||||
shutting down. With Wine 6.5 terminating a Wine process no longer terminates
|
||||
its threads, which would cause yabridge's plugin and host components to wait
|
||||
|
||||
@@ -35,6 +35,19 @@
|
||||
#define __IFileOperation_INTERFACE_DEFINED__
|
||||
#include <public.sdk/source/vst/hosting/module_win32.cpp>
|
||||
|
||||
/**
|
||||
* This is a workaround for Bluecat Audio plugins that don't expose their
|
||||
* `IPluginBase` interface through the query interface. Even though every plugin
|
||||
* object _must_ support `IPlugBase`, these plugins only expose those functions
|
||||
* through `IComponent` (which derives from `IPluginBase`). So if we do
|
||||
* encounter one of those plugins, then we'll just have to coerce an
|
||||
* `IComponent` pointer into an `IPluginBase` smart pointer. This way we can
|
||||
* keep the rest of yabridge's design in tact.
|
||||
*/
|
||||
Steinberg::FUnknownPtr<Steinberg::IPluginBase> hack_init_plugin_base(
|
||||
Steinberg::IPtr<Steinberg::FUnknown> object,
|
||||
Steinberg::IPtr<Steinberg::Vst::IComponent> component);
|
||||
|
||||
InstancePlugView::InstancePlugView() {}
|
||||
|
||||
InstancePlugView::InstancePlugView(
|
||||
@@ -62,7 +75,7 @@ InstanceInterfaces::InstanceInterfaces(
|
||||
midi_mapping(object),
|
||||
note_expression_controller(object),
|
||||
note_expression_physical_ui_mapping(object),
|
||||
plugin_base(object),
|
||||
plugin_base(hack_init_plugin_base(object, component)),
|
||||
unit_data(object),
|
||||
parameter_function_name(object),
|
||||
prefetchable_support(object),
|
||||
@@ -1297,3 +1310,42 @@ void Vst3Bridge::unregister_object_instance(size_t instance_id) {
|
||||
})
|
||||
.wait();
|
||||
}
|
||||
|
||||
Steinberg::FUnknownPtr<Steinberg::IPluginBase> hack_init_plugin_base(
|
||||
Steinberg::IPtr<Steinberg::FUnknown> object,
|
||||
Steinberg::IPtr<Steinberg::Vst::IComponent> component) {
|
||||
// See the docstring for more information
|
||||
Steinberg::FUnknownPtr<Steinberg::IPluginBase> plugin_base(object);
|
||||
if (plugin_base) {
|
||||
return plugin_base;
|
||||
} else if (component) {
|
||||
// HACK: So this should never be hit, because every object
|
||||
// initializeable from a plugin's factory must inherit from
|
||||
// `IPluginBase`. But, the Bluecat Audio plugins seem to have an
|
||||
// implementation issue where they don't expose this interface. So
|
||||
// instead we'll coerce from `IComponent` instead if this is the
|
||||
// case, since `IComponent` derives from `IPluginBase`. Doing
|
||||
// these manual pointer casts should be perfectly safe, even if
|
||||
// they go against the very idea of having a query interface.
|
||||
static_assert(sizeof(Steinberg::FUnknownPtr<Steinberg::IPluginBase>) ==
|
||||
sizeof(Steinberg::IPtr<Steinberg::IPluginBase>));
|
||||
|
||||
std::cerr << "WARNING: This plugin doesn't expose the IPluginBase"
|
||||
<< std::endl;
|
||||
std::cerr << " interface and is broken. We will attempt an"
|
||||
<< std::endl;
|
||||
std::cerr << " unsafe coercion from IComponent instead."
|
||||
<< std::endl;
|
||||
|
||||
Steinberg::IPtr<Steinberg::IPluginBase> coerced_plugin_base(
|
||||
component.get());
|
||||
|
||||
return *static_cast<Steinberg::FUnknownPtr<Steinberg::IPluginBase>*>(
|
||||
&coerced_plugin_base);
|
||||
} else {
|
||||
// This isn't really needed because the VST3 smart pointers can already
|
||||
// deal with null pointers, but might as well drive the point of this
|
||||
// hack home even further
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user