aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/soundlib/plugins/PluginManager.h
blob: 84575ad64348c20ee22f26260e3488f429f7cdd5 (plain) (blame)
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
/*
 * PluginManager.h
 * ---------------
 * Purpose: Plugin management
 * 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"

OPENMPT_NAMESPACE_BEGIN

constexpr int32 PLUGMAGIC(char a, char b, char c, char d) noexcept
{
	return static_cast<int32>((static_cast<uint32>(a) << 24) | (static_cast<uint32>(b) << 16) | (static_cast<uint32>(c) << 8) | (static_cast<uint32>(d) << 0));
}

//#define kBuzzMagic	PLUGMAGIC('B', 'u', 'z', 'z')
inline constexpr int32 kDmoMagic = PLUGMAGIC('D', 'X', 'M', 'O');

class CSoundFile;
class IMixPlugin;
struct SNDMIXPLUGIN;
enum PluginArch : int;

struct VSTPluginLib
{
public:
	enum PluginCategory : uint8
	{
		// Same plugin categories as defined in VST SDK
		catUnknown = 0,
		catEffect,          // Simple Effect
		catSynth,           // VST Instrument (Synths, samplers,...)
		catAnalysis,        // Scope, Tuner, ...
		catMastering,       // Dynamics, ...
		catSpacializer,     // Panners, ...
		catRoomFx,          // Delays and Reverbs
		catSurroundFx,      // Dedicated surround processor
		catRestoration,     // Denoiser, ...
		catOfflineProcess,  // Offline Process
		catShell,           // Plug-in is container of other plug-ins
		catGenerator,       // Tone Generator, ...
		// Custom categories
		catDMO,     // DirectX media object plugin
		catHidden,  // For internal plugins that should not be visible to the user (e.g. because they only exist for legacy reasons)

		numCategories
	};

public:
	using CreateProc = IMixPlugin *(*)(VSTPluginLib &factory, CSoundFile &sndFile, SNDMIXPLUGIN *mixStruct);

	IMixPlugin *pPluginsList = nullptr; // Pointer to first plugin instance (this instance carries pointers to other instances)
	CreateProc Create;                  // Factory to call for this plugin
	mpt::PathString libraryName;        // Display name
	mpt::PathString dllPath;            // Full path name
#ifdef MODPLUG_TRACKER
	mpt::ustring tags;                  // User tags
	CString vendor;
#endif // MODPLUG_TRACKER
	int32 pluginId1 = 0;                // Plugin type (kEffectMagic, kDmoMagic, ...)
	int32 pluginId2 = 0;                // Plugin unique ID
	PluginCategory category = catUnknown;
	const bool isBuiltIn : 1;
	bool isInstrument : 1;
	bool useBridge : 1, shareBridgeInstance : 1, modernBridge : 1;
protected:
	mutable uint8 dllArch = 0;

public:
	VSTPluginLib(CreateProc factoryProc, bool isBuiltIn, const mpt::PathString &dllPath, const mpt::PathString &libraryName
#ifdef MODPLUG_TRACKER
		, const mpt::ustring &tags = mpt::ustring(), const CString &vendor = CString()
#endif // MODPLUG_TRACKER
		)
		: Create(factoryProc)
		, libraryName(libraryName), dllPath(dllPath)
#ifdef MODPLUG_TRACKER
		, tags(tags)
		, vendor(vendor)
#endif // MODPLUG_TRACKER
		, category(catUnknown)
		, isBuiltIn(isBuiltIn), isInstrument(false)
		, useBridge(false), shareBridgeInstance(true), modernBridge(true)
	{
	}

#ifdef MPT_WITH_VST

	// Get native phost process arch encoded as plugin arch
	static uint8 GetNativePluginArch();
	static mpt::ustring GetPluginArchName(uint8 arch);
	static mpt::ustring GetPluginArchNameUser(uint8 arch);

	// Check whether a plugin can be hosted inside OpenMPT or requires bridging
	uint8 GetDllArch(bool fromCache = true) const;
	mpt::ustring GetDllArchName(bool fromCache = true) const;
	mpt::ustring GetDllArchNameUser(bool fromCache = true) const;
	bool IsNative(bool fromCache = true) const;
	// Check if a plugin is native, and if it is currently unknown, assume that it is native. Use this function only for performance reasons
	// (e.g. if tons of unscanned plugins would slow down generation of the plugin selection dialog)
	bool IsNativeFromCache() const;

#endif // MPT_WITH_VST

	void WriteToCache() const;

	uint32 EncodeCacheFlags() const
	{
		// Format: 00000000.0000000M.AAAAAASB.CCCCCCCI
		return (isInstrument ? 1 : 0)
			| (category << 1)
			| (useBridge ? 0x100 : 0)
			| (shareBridgeInstance ? 0x200 : 0)
			| ((dllArch / 8) << 10)
			| (modernBridge ? 0x10000 : 0)
			;
	}

	void DecodeCacheFlags(uint32 flags)
	{
		category = static_cast<PluginCategory>((flags & 0xFF) >> 1);
		if(category >= numCategories)
		{
			category = catUnknown;
		}
		if(flags & 1)
		{
			isInstrument = true;
			category = catSynth;
		}
		useBridge = (flags & 0x100) != 0;
		shareBridgeInstance = (flags & 0x200) != 0;
		dllArch = ((flags >> 10) & 0x3F) * 8;
		modernBridge = (flags & 0x10000) != 0;
	}
};


class CVstPluginManager
{
#ifndef NO_PLUGINS
protected:
#if defined(MPT_WITH_DMO)
	bool MustUnInitilizeCOM = false;
#endif
	std::vector<VSTPluginLib *> pluginList;

public:
	CVstPluginManager();
	~CVstPluginManager();

	using iterator = std::vector<VSTPluginLib *>::iterator;
	using const_iterator = std::vector<VSTPluginLib *>::const_iterator;

	iterator begin() { return pluginList.begin(); }
	const_iterator begin() const { return pluginList.begin(); }
	iterator end() { return pluginList.end(); }
	const_iterator end() const { return pluginList.end(); }
	void reserve(size_t num) { pluginList.reserve(num); }
	size_t size() const { return pluginList.size(); }

	bool IsValidPlugin(const VSTPluginLib *pLib) const;
	VSTPluginLib *AddPlugin(const mpt::PathString &dllPath, bool maskCrashes, const mpt::ustring &tags = mpt::ustring(), bool fromCache = true, bool *fileFound = nullptr);
	bool RemovePlugin(VSTPluginLib *);
	bool CreateMixPlugin(SNDMIXPLUGIN &, CSoundFile &);
	void OnIdle();
	static void ReportPlugException(const mpt::ustring &msg);

protected:
	void EnumerateDirectXDMOs();

#else // NO_PLUGINS
public:
	const VSTPluginLib **begin() const { return nullptr; }
	const VSTPluginLib **end() const { return nullptr; }
	void reserve(size_t) { }
	size_t size() const { return 0; }

	void OnIdle() {}
#endif // NO_PLUGINS
};


OPENMPT_NAMESPACE_END