BridgeWrapper.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*
  2. * BridgeWrapper.h
  3. * ---------------
  4. * Purpose: VST plugin bridge wrapper (host side)
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #pragma once
  10. #include "openmpt/all/BuildSettings.hpp"
  11. #ifdef MPT_WITH_VST
  12. #include "BridgeCommon.h"
  13. #include "../common/ComponentManager.h"
  14. OPENMPT_NAMESPACE_BEGIN
  15. struct VSTPluginLib;
  16. enum PluginArch : int
  17. {
  18. PluginArch_unknown = 0,
  19. PluginArch_x86 = 32,
  20. PluginArch_amd64 = 64,
  21. PluginArch_arm = 128 + 32,
  22. PluginArch_arm64 = 128 + 64,
  23. };
  24. std::size_t GetPluginArchPointerSize(PluginArch arch);
  25. enum class Generation
  26. {
  27. Legacy,
  28. Modern,
  29. };
  30. class ComponentPluginBridge
  31. : public ComponentBase
  32. {
  33. public:
  34. enum Availability
  35. {
  36. AvailabilityUnknown = 0,
  37. AvailabilityOK = 1,
  38. AvailabilityMissing = -1,
  39. AvailabilityWrongVersion = -2,
  40. };
  41. private:
  42. const PluginArch arch;
  43. const Generation generation;
  44. mpt::PathString exeName;
  45. Availability availability = AvailabilityUnknown;
  46. protected:
  47. ComponentPluginBridge(PluginArch arch, Generation generation);
  48. protected:
  49. bool DoInitialize() override;
  50. public:
  51. Availability GetAvailability() const { return availability; }
  52. mpt::PathString GetFileName() const { return exeName; }
  53. };
  54. class ComponentPluginBridge_x86
  55. : public ComponentPluginBridge
  56. {
  57. MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridge_x86, "PluginBridge-x86")
  58. public:
  59. ComponentPluginBridge_x86() : ComponentPluginBridge(PluginArch_x86, Generation::Modern) { }
  60. };
  61. class ComponentPluginBridgeLegacy_x86
  62. : public ComponentPluginBridge
  63. {
  64. MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridgeLegacy_x86, "PluginBridgeLegacy-x86")
  65. public:
  66. ComponentPluginBridgeLegacy_x86() : ComponentPluginBridge(PluginArch_x86, Generation::Legacy) { }
  67. };
  68. class ComponentPluginBridge_amd64
  69. : public ComponentPluginBridge
  70. {
  71. MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridge_amd64, "PluginBridge-amd64")
  72. public:
  73. ComponentPluginBridge_amd64() : ComponentPluginBridge(PluginArch_amd64, Generation::Modern) { }
  74. };
  75. class ComponentPluginBridgeLegacy_amd64
  76. : public ComponentPluginBridge
  77. {
  78. MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridgeLegacy_amd64, "PluginBridgeLegacy-amd64")
  79. public:
  80. ComponentPluginBridgeLegacy_amd64() : ComponentPluginBridge(PluginArch_amd64, Generation::Legacy) { }
  81. };
  82. #if defined(MPT_WITH_WINDOWS10)
  83. class ComponentPluginBridge_arm
  84. : public ComponentPluginBridge
  85. {
  86. MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridge_arm, "PluginBridge-arm")
  87. public:
  88. ComponentPluginBridge_arm() : ComponentPluginBridge(PluginArch_arm, Generation::Modern) { }
  89. };
  90. class ComponentPluginBridgeLegacy_arm
  91. : public ComponentPluginBridge
  92. {
  93. MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridgeLegacy_arm, "PluginBridgeLegacy-arm")
  94. public:
  95. ComponentPluginBridgeLegacy_arm() : ComponentPluginBridge(PluginArch_arm, Generation::Legacy) { }
  96. };
  97. class ComponentPluginBridge_arm64
  98. : public ComponentPluginBridge
  99. {
  100. MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridge_arm64, "PluginBridge-arm64")
  101. public:
  102. ComponentPluginBridge_arm64() : ComponentPluginBridge(PluginArch_arm64, Generation::Modern) { }
  103. };
  104. class ComponentPluginBridgeLegacy_arm64
  105. : public ComponentPluginBridge
  106. {
  107. MPT_DECLARE_COMPONENT_MEMBERS(ComponentPluginBridgeLegacy_arm64, "PluginBridgeLegacy-arm64")
  108. public:
  109. ComponentPluginBridgeLegacy_arm64() : ComponentPluginBridge(PluginArch_arm64, Generation::Legacy) { }
  110. };
  111. #endif // MPT_WITH_WINDOWS10
  112. class BridgeWrapper : private BridgeCommon
  113. {
  114. protected:
  115. Event m_sigAutomation;
  116. MappedMemory m_oldProcessMem;
  117. // Helper struct for keeping track of auxiliary shared memory
  118. struct AuxMem
  119. {
  120. std::atomic<bool> used = false;
  121. std::atomic<uint32> size = 0;
  122. MappedMemory memory;
  123. wchar_t name[64];
  124. };
  125. AuxMem m_auxMems[MSG_STACK_SIZE];
  126. std::vector<char> m_cachedProgNames;
  127. std::vector<ParameterInfo> m_cachedParamInfo;
  128. std::vector<float> m_cachedParamValues;
  129. int32 m_cachedProgNameStart = 0, m_cachedParamInfoStart = 0;
  130. bool m_isSettingProgram = false;
  131. Vst::ERect m_editRect;
  132. Vst::VstSpeakerArrangement m_speakers[2];
  133. ComponentHandle<ComponentPluginBridge_x86> pluginBridge_x86;
  134. ComponentHandle<ComponentPluginBridgeLegacy_x86> pluginBridgeLegacy_x86;
  135. ComponentHandle<ComponentPluginBridge_amd64> pluginBridge_amd64;
  136. ComponentHandle<ComponentPluginBridgeLegacy_amd64> pluginBridgeLegacy_amd64;
  137. #if defined(MPT_WITH_WINDOWS10)
  138. ComponentHandle<ComponentPluginBridge_arm> pluginBridge_arm;
  139. ComponentHandle<ComponentPluginBridgeLegacy_arm> pluginBridgeLegacy_arm;
  140. ComponentHandle<ComponentPluginBridge_arm64> pluginBridge_arm64;
  141. ComponentHandle<ComponentPluginBridgeLegacy_arm64> pluginBridgeLegacy_arm64;
  142. #endif // MPT_WITH_WINDOWS10
  143. Generation m_Generation = Generation::Modern;
  144. public:
  145. // Generic bridge exception
  146. class BridgeException : public std::exception
  147. {
  148. public:
  149. BridgeException(const char *str) : std::exception(str) { }
  150. BridgeException() { }
  151. };
  152. class BridgeNotFoundException : public BridgeException { };
  153. // Exception from bridge process
  154. class BridgeRemoteException
  155. {
  156. protected:
  157. wchar_t *str;
  158. public:
  159. BridgeRemoteException(const wchar_t *str_) : str(_wcsdup(str_)) { }
  160. BridgeRemoteException(const BridgeRemoteException &) = delete;
  161. BridgeRemoteException & operator=(const BridgeRemoteException &) = delete;
  162. ~BridgeRemoteException() { free(str); }
  163. const wchar_t *what() const { return str; }
  164. };
  165. public:
  166. static PluginArch GetNativePluginBinaryType();
  167. static PluginArch GetPluginBinaryType(const mpt::PathString &pluginPath);
  168. static bool IsPluginNative(const mpt::PathString &pluginPath) { return GetPluginBinaryType(pluginPath) == GetNativePluginBinaryType(); }
  169. static uint64 GetFileVersion(const WCHAR *exePath);
  170. static Vst::AEffect *Create(const VSTPluginLib &plugin, bool forceLegacy);
  171. protected:
  172. BridgeWrapper();
  173. ~BridgeWrapper();
  174. bool Init(const mpt::PathString &pluginPath, Generation bridgeGeneration, BridgeWrapper *sharedInstace);
  175. void ParseNextMessage(int msgID);
  176. void DispatchToHost(DispatchMsg &msg);
  177. bool SendToBridge(BridgeMessage &sendMsg);
  178. void SendAutomationQueue();
  179. AuxMem *GetAuxMemory(uint32 size);
  180. static intptr_t VSTCALLBACK DispatchToPlugin(Vst::AEffect *effect, Vst::VstOpcodeToPlugin opcode, int32 index, intptr_t value, void *ptr, float opt);
  181. intptr_t DispatchToPlugin(Vst::VstOpcodeToPlugin opcode, int32 index, intptr_t value, void *ptr, float opt);
  182. static void VSTCALLBACK SetParameter(Vst::AEffect *effect, int32 index, float parameter);
  183. void SetParameter(int32 index, float parameter);
  184. static float VSTCALLBACK GetParameter(Vst::AEffect *effect, int32 index);
  185. float GetParameter(int32 index);
  186. static void VSTCALLBACK Process(Vst::AEffect *effect, float **inputs, float **outputs, int32 sampleFrames);
  187. static void VSTCALLBACK ProcessReplacing(Vst::AEffect *effect, float **inputs, float **outputs, int32 sampleFrames);
  188. static void VSTCALLBACK ProcessDoubleReplacing(Vst::AEffect *effect, double **inputs, double **outputs, int32 sampleFrames);
  189. template<typename buf_t>
  190. void BuildProcessBuffer(ProcessMsg::ProcessType type, int32 numInputs, int32 numOutputs, buf_t **inputs, buf_t **outputs, int32 sampleFrames);
  191. static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  192. };
  193. OPENMPT_NAMESPACE_END
  194. #endif // MPT_WITH_VST