winamp/Src/external_dependencies/openmpt-trunk/pluginBridge/BridgeWrapper.h
2024-09-24 14:54:57 +02:00

238 lines
7.2 KiB
C++

/*
* BridgeWrapper.h
* ---------------
* Purpose: VST plugin bridge wrapper (host side)
* Notes : (currently none)
* Authors: OpenMPT Devs
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
*/
#pragma once
#include "openmpt/all/BuildSettings.hpp"
#ifdef MPT_WITH_VST
#include "BridgeCommon.h"
#include "../common/ComponentManager.h"
OPENMPT_NAMESPACE_BEGIN
struct VSTPluginLib;
enum PluginArch : int
{
PluginArch_unknown = 0,
PluginArch_x86 = 32,
PluginArch_amd64 = 64,
PluginArch_arm = 128 + 32,
PluginArch_arm64 = 128 + 64,
};
std::size_t GetPluginArchPointerSize(PluginArch arch);
enum class Generation
{
Legacy,
Modern,
};
class ComponentPluginBridge
: public ComponentBase
{
public:
enum Availability
{
AvailabilityUnknown = 0,
AvailabilityOK = 1,
AvailabilityMissing = -1,
AvailabilityWrongVersion = -2,
};
private:
const PluginArch arch;
const Generation generation;
mpt::PathString exeName;
Availability availability = AvailabilityUnknown;
protected:
ComponentPluginBridge(PluginArch arch, Generation generation);
protected:
bool DoInitialize() override;
public:
Availability GetAvailability() const { return availability; }
mpt::PathString GetFileName() const { return exeName; }
};
class ComponentPluginBridge_x86
: public ComponentPluginBridge
{
MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridge_x86, "PluginBridge-x86")
public:
ComponentPluginBridge_x86() : ComponentPluginBridge(PluginArch_x86, Generation::Modern) { }
};
class ComponentPluginBridgeLegacy_x86
: public ComponentPluginBridge
{
MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridgeLegacy_x86, "PluginBridgeLegacy-x86")
public:
ComponentPluginBridgeLegacy_x86() : ComponentPluginBridge(PluginArch_x86, Generation::Legacy) { }
};
class ComponentPluginBridge_amd64
: public ComponentPluginBridge
{
MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridge_amd64, "PluginBridge-amd64")
public:
ComponentPluginBridge_amd64() : ComponentPluginBridge(PluginArch_amd64, Generation::Modern) { }
};
class ComponentPluginBridgeLegacy_amd64
: public ComponentPluginBridge
{
MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridgeLegacy_amd64, "PluginBridgeLegacy-amd64")
public:
ComponentPluginBridgeLegacy_amd64() : ComponentPluginBridge(PluginArch_amd64, Generation::Legacy) { }
};
#if defined(MPT_WITH_WINDOWS10)
class ComponentPluginBridge_arm
: public ComponentPluginBridge
{
MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridge_arm, "PluginBridge-arm")
public:
ComponentPluginBridge_arm() : ComponentPluginBridge(PluginArch_arm, Generation::Modern) { }
};
class ComponentPluginBridgeLegacy_arm
: public ComponentPluginBridge
{
MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridgeLegacy_arm, "PluginBridgeLegacy-arm")
public:
ComponentPluginBridgeLegacy_arm() : ComponentPluginBridge(PluginArch_arm, Generation::Legacy) { }
};
class ComponentPluginBridge_arm64
: public ComponentPluginBridge
{
MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridge_arm64, "PluginBridge-arm64")
public:
ComponentPluginBridge_arm64() : ComponentPluginBridge(PluginArch_arm64, Generation::Modern) { }
};
class ComponentPluginBridgeLegacy_arm64
: public ComponentPluginBridge
{
MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridgeLegacy_arm64, "PluginBridgeLegacy-arm64")
public:
ComponentPluginBridgeLegacy_arm64() : ComponentPluginBridge(PluginArch_arm64, Generation::Legacy) { }
};
#endif // MPT_WITH_WINDOWS10
class BridgeWrapper : private BridgeCommon
{
protected:
Event m_sigAutomation;
MappedMemory m_oldProcessMem;
// Helper struct for keeping track of auxiliary shared memory
struct AuxMem
{
std::atomic<bool> used = false;
std::atomic<uint32> size = 0;
MappedMemory memory;
wchar_t name[64];
};
AuxMem m_auxMems[MSG_STACK_SIZE];
std::vector<char> m_cachedProgNames;
std::vector<ParameterInfo> m_cachedParamInfo;
std::vector<float> m_cachedParamValues;
int32 m_cachedProgNameStart = 0, m_cachedParamInfoStart = 0;
bool m_isSettingProgram = false;
Vst::ERect m_editRect;
Vst::VstSpeakerArrangement m_speakers[2];
ComponentHandle<ComponentPluginBridge_x86> pluginBridge_x86;
ComponentHandle<ComponentPluginBridgeLegacy_x86> pluginBridgeLegacy_x86;
ComponentHandle<ComponentPluginBridge_amd64> pluginBridge_amd64;
ComponentHandle<ComponentPluginBridgeLegacy_amd64> pluginBridgeLegacy_amd64;
#if defined(MPT_WITH_WINDOWS10)
ComponentHandle<ComponentPluginBridge_arm> pluginBridge_arm;
ComponentHandle<ComponentPluginBridgeLegacy_arm> pluginBridgeLegacy_arm;
ComponentHandle<ComponentPluginBridge_arm64> pluginBridge_arm64;
ComponentHandle<ComponentPluginBridgeLegacy_arm64> pluginBridgeLegacy_arm64;
#endif // MPT_WITH_WINDOWS10
Generation m_Generation = Generation::Modern;
public:
// Generic bridge exception
class BridgeException : public std::exception
{
public:
BridgeException(const char *str) : std::exception(str) { }
BridgeException() { }
};
class BridgeNotFoundException : public BridgeException { };
// Exception from bridge process
class BridgeRemoteException
{
protected:
wchar_t *str;
public:
BridgeRemoteException(const wchar_t *str_) : str(_wcsdup(str_)) { }
BridgeRemoteException(const BridgeRemoteException &) = delete;
BridgeRemoteException & operator=(const BridgeRemoteException &) = delete;
~BridgeRemoteException() { free(str); }
const wchar_t *what() const { return str; }
};
public:
static PluginArch GetNativePluginBinaryType();
static PluginArch GetPluginBinaryType(const mpt::PathString &pluginPath);
static bool IsPluginNative(const mpt::PathString &pluginPath) { return GetPluginBinaryType(pluginPath) == GetNativePluginBinaryType(); }
static uint64 GetFileVersion(const WCHAR *exePath);
static Vst::AEffect *Create(const VSTPluginLib &plugin, bool forceLegacy);
protected:
BridgeWrapper();
~BridgeWrapper();
bool Init(const mpt::PathString &pluginPath, Generation bridgeGeneration, BridgeWrapper *sharedInstace);
void ParseNextMessage(int msgID);
void DispatchToHost(DispatchMsg &msg);
bool SendToBridge(BridgeMessage &sendMsg);
void SendAutomationQueue();
AuxMem *GetAuxMemory(uint32 size);
static intptr_t VSTCALLBACK DispatchToPlugin(Vst::AEffect *effect, Vst::VstOpcodeToPlugin opcode, int32 index, intptr_t value, void *ptr, float opt);
intptr_t DispatchToPlugin(Vst::VstOpcodeToPlugin opcode, int32 index, intptr_t value, void *ptr, float opt);
static void VSTCALLBACK SetParameter(Vst::AEffect *effect, int32 index, float parameter);
void SetParameter(int32 index, float parameter);
static float VSTCALLBACK GetParameter(Vst::AEffect *effect, int32 index);
float GetParameter(int32 index);
static void VSTCALLBACK Process(Vst::AEffect *effect, float **inputs, float **outputs, int32 sampleFrames);
static void VSTCALLBACK ProcessReplacing(Vst::AEffect *effect, float **inputs, float **outputs, int32 sampleFrames);
static void VSTCALLBACK ProcessDoubleReplacing(Vst::AEffect *effect, double **inputs, double **outputs, int32 sampleFrames);
template<typename buf_t>
void BuildProcessBuffer(ProcessMsg::ProcessType type, int32 numInputs, int32 numOutputs, buf_t **inputs, buf_t **outputs, int32 sampleFrames);
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
};
OPENMPT_NAMESPACE_END
#endif // MPT_WITH_VST