1 /*
2 * PluginManager.h
3 * ---------------
4 * Purpose: Plugin management
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
10
11 #pragma once
12
13 #include "openmpt/all/BuildSettings.hpp"
14
15 OPENMPT_NAMESPACE_BEGIN
16
PLUGMAGIC(char a,char b,char c,char d)17 constexpr int32 PLUGMAGIC(char a, char b, char c, char d) noexcept
18 {
19 return static_cast<int32>((static_cast<uint32>(a) << 24) | (static_cast<uint32>(b) << 16) | (static_cast<uint32>(c) << 8) | (static_cast<uint32>(d) << 0));
20 }
21
22 //#define kBuzzMagic PLUGMAGIC('B', 'u', 'z', 'z')
23 inline constexpr int32 kDmoMagic = PLUGMAGIC('D', 'X', 'M', 'O');
24
25 class CSoundFile;
26 class IMixPlugin;
27 struct SNDMIXPLUGIN;
28 enum PluginArch : int;
29
30 struct VSTPluginLib
31 {
32 public:
33 enum PluginCategory : uint8
34 {
35 // Same plugin categories as defined in VST SDK
36 catUnknown = 0,
37 catEffect, // Simple Effect
38 catSynth, // VST Instrument (Synths, samplers,...)
39 catAnalysis, // Scope, Tuner, ...
40 catMastering, // Dynamics, ...
41 catSpacializer, // Panners, ...
42 catRoomFx, // Delays and Reverbs
43 catSurroundFx, // Dedicated surround processor
44 catRestoration, // Denoiser, ...
45 catOfflineProcess, // Offline Process
46 catShell, // Plug-in is container of other plug-ins
47 catGenerator, // Tone Generator, ...
48 // Custom categories
49 catDMO, // DirectX media object plugin
50 catHidden, // For internal plugins that should not be visible to the user (e.g. because they only exist for legacy reasons)
51
52 numCategories
53 };
54
55 public:
56 using CreateProc = IMixPlugin *(*)(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct);
57
58 IMixPlugin *pPluginsList = nullptr; // Pointer to first plugin instance (this instance carries pointers to other instances)
59 CreateProc Create; // Factory to call for this plugin
60 mpt::PathString libraryName; // Display name
61 mpt::PathString dllPath; // Full path name
62 #ifdef MODPLUG_TRACKER
63 mpt::ustring tags; // User tags
64 CString vendor;
65 #endif // MODPLUG_TRACKER
66 int32 pluginId1 = 0; // Plugin type (kEffectMagic, kDmoMagic, ...)
67 int32 pluginId2 = 0; // Plugin unique ID
68 PluginCategory category = catUnknown;
69 const bool isBuiltIn : 1;
70 bool isInstrument : 1;
71 bool useBridge : 1, shareBridgeInstance : 1, modernBridge : 1;
72 protected:
73 mutable uint8 dllArch = 0;
74
75 public:
76 VSTPluginLib(CreateProc factoryProc, bool isBuiltIn, const mpt::PathString &dllPath, const mpt::PathString &libraryName
77 #ifdef MODPLUG_TRACKER
78 , const mpt::ustring &tags = mpt::ustring(), const CString &vendor = CString()
79 #endif // MODPLUG_TRACKER
80 )
CreateVSTPluginLib81 : Create(factoryProc)
82 , libraryName(libraryName), dllPath(dllPath)
83 #ifdef MODPLUG_TRACKER
84 , tags(tags)
85 , vendor(vendor)
86 #endif // MODPLUG_TRACKER
87 , category(catUnknown)
88 , isBuiltIn(isBuiltIn), isInstrument(false)
89 , useBridge(false), shareBridgeInstance(true), modernBridge(true)
90 {
91 }
92
93 #ifdef MPT_WITH_VST
94
95 // Get native phost process arch encoded as plugin arch
96 static uint8 GetNativePluginArch();
97 static mpt::ustring GetPluginArchName(uint8 arch);
98 static mpt::ustring GetPluginArchNameUser(uint8 arch);
99
100 // Check whether a plugin can be hosted inside OpenMPT or requires bridging
101 uint8 GetDllArch(bool fromCache = true) const;
102 mpt::ustring GetDllArchName(bool fromCache = true) const;
103 mpt::ustring GetDllArchNameUser(bool fromCache = true) const;
104 bool IsNative(bool fromCache = true) const;
105 // Check if a plugin is native, and if it is currently unknown, assume that it is native. Use this function only for performance reasons
106 // (e.g. if tons of unscanned plugins would slow down generation of the plugin selection dialog)
107 bool IsNativeFromCache() const;
108
109 #endif // MPT_WITH_VST
110
111 void WriteToCache() const;
112
EncodeCacheFlagsVSTPluginLib113 uint32 EncodeCacheFlags() const
114 {
115 // Format: 00000000.0000000M.AAAAAASB.CCCCCCCI
116 return (isInstrument ? 1 : 0)
117 | (category << 1)
118 | (useBridge ? 0x100 : 0)
119 | (shareBridgeInstance ? 0x200 : 0)
120 | ((dllArch / 8) << 10)
121 | (modernBridge ? 0x10000 : 0)
122 ;
123 }
124
DecodeCacheFlagsVSTPluginLib125 void DecodeCacheFlags(uint32 flags)
126 {
127 category = static_cast<PluginCategory>((flags & 0xFF) >> 1);
128 if(category >= numCategories)
129 {
130 category = catUnknown;
131 }
132 if(flags & 1)
133 {
134 isInstrument = true;
135 category = catSynth;
136 }
137 useBridge = (flags & 0x100) != 0;
138 shareBridgeInstance = (flags & 0x200) != 0;
139 dllArch = ((flags >> 10) & 0x3F) * 8;
140 modernBridge = (flags & 0x10000) != 0;
141 }
142 };
143
144
145 class CVstPluginManager
146 {
147 #ifndef NO_PLUGINS
148 protected:
149 #if defined(MPT_WITH_DMO)
150 bool MustUnInitilizeCOM = false;
151 #endif
152 std::vector<VSTPluginLib *> pluginList;
153
154 public:
155 CVstPluginManager();
156 ~CVstPluginManager();
157
158 using iterator = std::vector<VSTPluginLib *>::iterator;
159 using const_iterator = std::vector<VSTPluginLib *>::const_iterator;
160
begin()161 iterator begin() { return pluginList.begin(); }
begin()162 const_iterator begin() const { return pluginList.begin(); }
end()163 iterator end() { return pluginList.end(); }
end()164 const_iterator end() const { return pluginList.end(); }
reserve(size_t num)165 void reserve(size_t num) { pluginList.reserve(num); }
size()166 size_t size() const { return pluginList.size(); }
167
168 bool IsValidPlugin(const VSTPluginLib *pLib) const;
169 VSTPluginLib *AddPlugin(const mpt::PathString &dllPath, bool maskCrashes, const mpt::ustring &tags = mpt::ustring(), bool fromCache = true, bool *fileFound = nullptr);
170 bool RemovePlugin(VSTPluginLib *);
171 bool CreateMixPlugin(SNDMIXPLUGIN &, CSoundFile &);
172 void OnIdle();
173 static void ReportPlugException(const mpt::ustring &msg);
174
175 protected:
176 void EnumerateDirectXDMOs();
177
178 #else // NO_PLUGINS
179 public:
180 const VSTPluginLib **begin() const { return nullptr; }
181 const VSTPluginLib **end() const { return nullptr; }
182 void reserve(size_t) { }
183 size_t size() const { return 0; }
184
185 void OnIdle() {}
186 #endif // NO_PLUGINS
187 };
188
189
190 OPENMPT_NAMESPACE_END
191