mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-14 12:30:00 +02:00
Add conversions for the garbled UIDs
We'll need this to make sure the reported class IDs match up with the actual IDs.
This commit is contained in:
@@ -66,6 +66,51 @@ const Steinberg::Vst::TChar* u16string_to_tchar_pointer(
|
||||
#endif
|
||||
}
|
||||
|
||||
WineUID::WineUID() {}
|
||||
WineUID::WineUID(const Steinberg::TUID& tuid) : uid(std::to_array(tuid)) {}
|
||||
|
||||
ArrayUID WineUID::get_native_uid() const {
|
||||
// We need to shuffle the first 8 bytes around to convert between the
|
||||
// COM-compatible and non COM-compatible formats described by the
|
||||
// `INLINE_UID` macro. See that macro as a reference for the transformations
|
||||
// we're applying here.
|
||||
ArrayUID converted_uid = uid;
|
||||
|
||||
converted_uid[0] = uid[3];
|
||||
converted_uid[1] = uid[2];
|
||||
converted_uid[2] = uid[1];
|
||||
converted_uid[3] = uid[0];
|
||||
|
||||
converted_uid[4] = uid[5];
|
||||
converted_uid[5] = uid[4];
|
||||
converted_uid[6] = uid[7];
|
||||
converted_uid[7] = uid[6];
|
||||
|
||||
return converted_uid;
|
||||
}
|
||||
|
||||
NativeUID::NativeUID() {}
|
||||
NativeUID::NativeUID(const Steinberg::TUID& tuid) : uid(std::to_array(tuid)) {}
|
||||
|
||||
ArrayUID NativeUID::get_wine_uid() const {
|
||||
// This transformation is actually the same as the one in
|
||||
// `WineUID::get_native_uid()`, but we'll spell it out here in full for
|
||||
// understandability's sake.
|
||||
ArrayUID converted_uid = uid;
|
||||
|
||||
converted_uid[0] = uid[3];
|
||||
converted_uid[1] = uid[2];
|
||||
converted_uid[2] = uid[1];
|
||||
converted_uid[3] = uid[0];
|
||||
|
||||
converted_uid[4] = uid[5];
|
||||
converted_uid[5] = uid[4];
|
||||
converted_uid[6] = uid[7];
|
||||
converted_uid[7] = uid[6];
|
||||
|
||||
return converted_uid;
|
||||
}
|
||||
|
||||
UniversalTResult::UniversalTResult() : universal_result(Value::kResultFalse) {}
|
||||
|
||||
UniversalTResult::UniversalTResult(tresult native_result)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <bitsery/traits/array.h>
|
||||
#include <pluginterfaces/base/ftypes.h>
|
||||
#include <pluginterfaces/base/funknown.h>
|
||||
#include <pluginterfaces/vst/vsttypes.h>
|
||||
@@ -31,15 +32,6 @@ using Steinberg::TBool, Steinberg::char16, Steinberg::int8, Steinberg::int16,
|
||||
Steinberg::int32, Steinberg::int64, Steinberg::uint8, Steinberg::uint16,
|
||||
Steinberg::uint32, Steinberg::uint64, Steinberg::tresult;
|
||||
|
||||
/**
|
||||
* Both `TUID` (`int8_t[16]`) and `FIDString` (`char*`) are hard to work with
|
||||
* because you can't just copy them. So when serializing/deserializing them
|
||||
* we'll use `std::array`.
|
||||
*/
|
||||
using ArrayUID = std::array<
|
||||
std::remove_reference_t<decltype(std::declval<Steinberg::TUID>()[0])>,
|
||||
std::extent_v<Steinberg::TUID>>;
|
||||
|
||||
/**
|
||||
* The maximum number of speakers or busses we support.
|
||||
*/
|
||||
@@ -86,6 +78,82 @@ struct Ack {
|
||||
void serialize(S&) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Both `TUID` (`int8_t[16]`) and `FIDString` (`char*`) are hard to work with
|
||||
* because you can't just copy them. So when serializing/deserializing them
|
||||
* we'll use `std::array`.
|
||||
*
|
||||
* FIXME: Replace usages of ArrayUID everywhere with either `WineUID` or
|
||||
* `NativeUID`
|
||||
*/
|
||||
using ArrayUID = std::array<
|
||||
std::remove_reference_t<decltype(std::declval<Steinberg::TUID>()[0])>,
|
||||
std::extent_v<Steinberg::TUID>>;
|
||||
|
||||
/**
|
||||
* Store a serializable UID in the format used on the Wine host. This then has
|
||||
* to be converted to the correct native format on the plugin side.
|
||||
*
|
||||
* NOTE: This is crucial. The `INLINE_UID` macro from the VST3 SDK uses
|
||||
* different byte ordering on Windows (with COM support) versus on other
|
||||
* platforms. We need to reverse this transformation manually in order for
|
||||
* projects with the Windows VST3 version of plugin X, the Linux VST3
|
||||
* version of plugin X, and the Windows VST3 version of plugin X running
|
||||
* through yabridge to be compatible.
|
||||
*/
|
||||
class WineUID {
|
||||
public:
|
||||
WineUID();
|
||||
WineUID(const Steinberg::TUID& tuid);
|
||||
|
||||
ArrayUID get_native_uid() const;
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
s.container1b(uid);
|
||||
}
|
||||
|
||||
protected:
|
||||
ArrayUID uid;
|
||||
};
|
||||
|
||||
/**
|
||||
* Store a serializable UID in the 'real' format as used by the Windows version
|
||||
* of the VST3 plugin on Windows and the Linux version of the same plugin on
|
||||
* Linux. This then has to be converted to the format reported by the plugin on
|
||||
* the Wine host.
|
||||
*
|
||||
* NOTE: This is crucial. The `INLINE_UID` macro from the VST3 SDK uses
|
||||
* different byte ordering on Windows (with COM support) versus on other
|
||||
* platforms. We need to reverse this transformation manually in order for
|
||||
* projects with the Windows VST3 version of plugin X, the Linux VST3
|
||||
* version of plugin X, and the Windows VST3 version of plugin X running
|
||||
* through yabridge to be compatible.
|
||||
*/
|
||||
class NativeUID {
|
||||
public:
|
||||
NativeUID();
|
||||
NativeUID(const Steinberg::TUID& tuid);
|
||||
|
||||
/**
|
||||
* Convert to the garbled byte order used in the Wine plugin host.
|
||||
*/
|
||||
ArrayUID get_wine_uid() const;
|
||||
|
||||
/**
|
||||
* Get a reference to the proper native UID.
|
||||
*/
|
||||
inline const ArrayUID& native_uid() const { return uid; };
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
s.container1b(uid);
|
||||
}
|
||||
|
||||
protected:
|
||||
ArrayUID uid;
|
||||
};
|
||||
|
||||
/**
|
||||
* A simple wrapper around primitive values for serialization purposes. Bitsery
|
||||
* doesn't seem to like serializing plain primitives using `s.object()` even if
|
||||
|
||||
@@ -25,13 +25,6 @@ YaPluginFactory::ConstructArgs::ConstructArgs() {}
|
||||
|
||||
YaPluginFactory::ConstructArgs::ConstructArgs(
|
||||
Steinberg::IPtr<Steinberg::IPluginFactory> factory) {
|
||||
// FIXME: The class IDs are incorrect! See the `INLINE_UID` macro. We need
|
||||
// to shuffle the byte orders around for plugins to be compatible
|
||||
// with projects saved under Windows and with native Linux versions
|
||||
// of the same plugin.
|
||||
// FIXME: We need to do similar translations everywhere where we encounter
|
||||
// `ArrayUID`, such as `IComponent::getControllerClassId()`
|
||||
|
||||
// `IPluginFactory::getFactoryInfo`
|
||||
if (Steinberg::PFactoryInfo info;
|
||||
factory->getFactoryInfo(&info) == Steinberg::kResultOk) {
|
||||
@@ -131,6 +124,13 @@ tresult PLUGIN_API YaPluginFactory::getClassInfo(Steinberg::int32 index,
|
||||
return Steinberg::kInvalidArgument;
|
||||
}
|
||||
|
||||
// FIXME: The class IDs are incorrect! See the `INLINE_UID` macro. We need
|
||||
// to shuffle the byte orders around for plugins to be compatible
|
||||
// with projects saved under Windows and with native Linux versions
|
||||
// of the same plugin. We need to do this transformation for all of
|
||||
// these functions
|
||||
// FIXME: We need to do similar translations everywhere where we encounter
|
||||
// `ArrayUID`, such as `IComponent::getControllerClassId()`
|
||||
if (arguments.class_infos_1[index]) {
|
||||
*info = *arguments.class_infos_1[index];
|
||||
return Steinberg::kResultOk;
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <bitsery/ext/std_optional.h>
|
||||
#include <bitsery/traits/array.h>
|
||||
#include <pluginterfaces/vst/ivstcomponent.h>
|
||||
|
||||
#include "../../../bitsery/ext/vst3.h"
|
||||
|
||||
Reference in New Issue
Block a user