1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
|
/*
* 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
|