mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-07 20:10:13 +02:00
💥 Convert between UID formats for class IDs
This is a breaking change. Old projects containing VST3 plugins running through yabridge will no longer work without modifications. I'll write some scripts to convert the class IDs stored in those project files soon a migration path. The UIDs reported by the plugin were apparently wrong, which meant that the native Linux VST3 version of plugin X and the normal Windows VST3 version of plugin X used different class ideas than the Windows VST3 version of plugin X running through yabridge. Those things are supposed to be compatible, so we sadly needed to make this change at some point.
This commit is contained in:
@@ -79,7 +79,8 @@ bool Vst3Logger::log_request(bool is_host_vst,
|
||||
const Vst3PluginProxy::Construct& request) {
|
||||
return log_request_base(is_host_vst, [&](auto& message) {
|
||||
message << "IPluginFactory::createInstance(cid = "
|
||||
<< format_uid(Steinberg::FUID::fromTUID(request.cid.data()))
|
||||
<< format_uid(Steinberg::FUID::fromTUID(
|
||||
request.cid.native_uid().data()))
|
||||
<< ", _iid = ";
|
||||
switch (request.requested_interface) {
|
||||
case Vst3PluginProxy::Construct::Interface::IComponent:
|
||||
|
||||
@@ -38,6 +38,13 @@ YaPluginFactory::ConstructArgs::ConstructArgs(
|
||||
Steinberg::PClassInfo info;
|
||||
if (factory->getClassInfo(i, &info) == Steinberg::kResultOk) {
|
||||
class_infos_1[i] = info;
|
||||
|
||||
// NOTE: We'll need to do a byte order conversion to the reported
|
||||
// class IDs match up with native and 'real' Windows VST3
|
||||
// plugins. See `WineUID` for more information.
|
||||
ArrayUID native_uid = WineUID(info.cid).get_native_uid();
|
||||
std::copy(native_uid.begin(), native_uid.end(),
|
||||
class_infos_1[i]->cid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +60,13 @@ YaPluginFactory::ConstructArgs::ConstructArgs(
|
||||
Steinberg::PClassInfo2 info;
|
||||
if (factory2->getClassInfo2(i, &info) == Steinberg::kResultOk) {
|
||||
class_infos_2[i] = info;
|
||||
|
||||
// NOTE: We'll need to do a byte order conversion to the reported
|
||||
// class IDs match up with native and 'real' Windows VST3
|
||||
// plugins. See `WineUID` for more information.
|
||||
ArrayUID native_uid = WineUID(info.cid).get_native_uid();
|
||||
std::copy(native_uid.begin(), native_uid.end(),
|
||||
class_infos_1[i]->cid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +82,13 @@ YaPluginFactory::ConstructArgs::ConstructArgs(
|
||||
Steinberg::PClassInfoW info;
|
||||
if (factory3->getClassInfoUnicode(i, &info) == Steinberg::kResultOk) {
|
||||
class_infos_unicode[i] = info;
|
||||
|
||||
// NOTE: We'll need to do a byte order conversion to the reported
|
||||
// class IDs match up with native and 'real' Windows VST3
|
||||
// plugins. See `WineUID` for more information.
|
||||
ArrayUID native_uid = WineUID(info.cid).get_native_uid();
|
||||
std::copy(native_uid.begin(), native_uid.end(),
|
||||
class_infos_1[i]->cid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
/**
|
||||
* Wraps around `IPluginFactory{1,2,3}` for serialization purposes. See
|
||||
* `docs/vst3.md` for more information on how this works.
|
||||
*
|
||||
* TODO: Redo this in the new 'Vst3PluginFactoryProxy' style
|
||||
*/
|
||||
class YaPluginFactory : public Steinberg::IPluginFactory3 {
|
||||
public:
|
||||
@@ -70,6 +72,10 @@ class YaPluginFactory : public Steinberg::IPluginFactory3 {
|
||||
* info versions if the plugin can provide them since we don't know
|
||||
* which version of the interface the host will use. Will be
|
||||
* `std::nullopt` if the plugin doesn't return a class info.
|
||||
*
|
||||
* NOTE: We'll have already converted all returned class IDs to native
|
||||
* class IDs using `WienUID::to_native_uid()` for cross-platform
|
||||
* compatibility. This applies to all `class_info_*` fields here.
|
||||
*/
|
||||
std::vector<std::optional<Steinberg::PClassInfo>> class_infos_1;
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ class Vst3PluginProxy : public YaAudioPresentationLatency,
|
||||
struct Construct {
|
||||
using Response = std::variant<ConstructArgs, UniversalTResult>;
|
||||
|
||||
ArrayUID cid;
|
||||
NativeUID cid;
|
||||
|
||||
/**
|
||||
* The interface the host was trying to instantiate an object for.
|
||||
@@ -189,7 +189,7 @@ class Vst3PluginProxy : public YaAudioPresentationLatency,
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
s.container1b(cid);
|
||||
s.object(cid);
|
||||
s.value4b(requested_interface);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -35,8 +35,8 @@ YaPluginFactoryImpl::createInstance(Steinberg::FIDString cid,
|
||||
return Steinberg::kInvalidArgument;
|
||||
}
|
||||
|
||||
ArrayUID cid_array;
|
||||
std::copy(cid, cid + std::extent_v<Steinberg::TUID>, cid_array.begin());
|
||||
Steinberg::TUID cid_array;
|
||||
std::copy(cid, cid + std::extent_v<Steinberg::TUID>, cid_array);
|
||||
|
||||
// FIXME: `_iid` in Bitwig Studio 3.3.1 is not null terminated, and the
|
||||
// comparison below will thus fail since the strings have different
|
||||
|
||||
@@ -120,7 +120,9 @@ void Vst3Bridge::run() {
|
||||
[&](const Vst3PluginProxy::Construct& request)
|
||||
-> Vst3PluginProxy::Construct::Response {
|
||||
Steinberg::TUID cid;
|
||||
std::copy(request.cid.begin(), request.cid.end(), cid);
|
||||
|
||||
ArrayUID wine_cid = request.cid.get_wine_uid();
|
||||
std::copy(wine_cid.begin(), wine_cid.end(), cid);
|
||||
|
||||
// Even though we're requesting a specific interface (to mimic
|
||||
// what the host is doing), we're immediately upcasting it to an
|
||||
|
||||
Reference in New Issue
Block a user