mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-06-20 11:02:52 +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
|
#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() : universal_result(Value::kResultFalse) {}
|
||||||
|
|
||||||
UniversalTResult::UniversalTResult(tresult native_result)
|
UniversalTResult::UniversalTResult(tresult native_result)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <bitsery/traits/array.h>
|
||||||
#include <pluginterfaces/base/ftypes.h>
|
#include <pluginterfaces/base/ftypes.h>
|
||||||
#include <pluginterfaces/base/funknown.h>
|
#include <pluginterfaces/base/funknown.h>
|
||||||
#include <pluginterfaces/vst/vsttypes.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::int32, Steinberg::int64, Steinberg::uint8, Steinberg::uint16,
|
||||||
Steinberg::uint32, Steinberg::uint64, Steinberg::tresult;
|
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.
|
* The maximum number of speakers or busses we support.
|
||||||
*/
|
*/
|
||||||
@@ -86,6 +78,82 @@ struct Ack {
|
|||||||
void serialize(S&) {}
|
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
|
* A simple wrapper around primitive values for serialization purposes. Bitsery
|
||||||
* doesn't seem to like serializing plain primitives using `s.object()` even if
|
* doesn't seem to like serializing plain primitives using `s.object()` even if
|
||||||
|
|||||||
@@ -25,13 +25,6 @@ YaPluginFactory::ConstructArgs::ConstructArgs() {}
|
|||||||
|
|
||||||
YaPluginFactory::ConstructArgs::ConstructArgs(
|
YaPluginFactory::ConstructArgs::ConstructArgs(
|
||||||
Steinberg::IPtr<Steinberg::IPluginFactory> factory) {
|
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`
|
// `IPluginFactory::getFactoryInfo`
|
||||||
if (Steinberg::PFactoryInfo info;
|
if (Steinberg::PFactoryInfo info;
|
||||||
factory->getFactoryInfo(&info) == Steinberg::kResultOk) {
|
factory->getFactoryInfo(&info) == Steinberg::kResultOk) {
|
||||||
@@ -131,6 +124,13 @@ tresult PLUGIN_API YaPluginFactory::getClassInfo(Steinberg::int32 index,
|
|||||||
return Steinberg::kInvalidArgument;
|
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]) {
|
if (arguments.class_infos_1[index]) {
|
||||||
*info = *arguments.class_infos_1[index];
|
*info = *arguments.class_infos_1[index];
|
||||||
return Steinberg::kResultOk;
|
return Steinberg::kResultOk;
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <bitsery/ext/std_optional.h>
|
#include <bitsery/ext/std_optional.h>
|
||||||
#include <bitsery/traits/array.h>
|
|
||||||
#include <pluginterfaces/vst/ivstcomponent.h>
|
#include <pluginterfaces/vst/ivstcomponent.h>
|
||||||
|
|
||||||
#include "../../../bitsery/ext/vst3.h"
|
#include "../../../bitsery/ext/vst3.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user