1 /*
2  * PluginStructs.h
3  * ---------------
4  * Purpose: Basic plugin structs for CSoundFile.
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 #include "../Snd_defs.h"
16 #ifndef NO_PLUGINS
17 #include "openmpt/base/Endian.hpp"
18 #endif // NO_PLUGINS
19 
20 OPENMPT_NAMESPACE_BEGIN
21 
22 ////////////////////////////////////////////////////////////////////
23 // Mix Plugins
24 
25 typedef int32 PlugParamIndex;
26 typedef float PlugParamValue;
27 
28 struct SNDMIXPLUGINSTATE;
29 struct SNDMIXPLUGIN;
30 class IMixPlugin;
31 class CSoundFile;
32 
33 #ifndef NO_PLUGINS
34 
35 struct SNDMIXPLUGININFO
36 {
37 	// dwInputRouting flags
38 	enum RoutingFlags
39 	{
40 		irApplyToMaster	= 0x01,	// Apply to master mix
41 		irBypass		= 0x02,	// Bypass effect
42 		irWetMix		= 0x04,	// Wet Mix (dry added)
43 		irExpandMix		= 0x08,	// [0%,100%] -> [-200%,200%]
44 		irAutoSuspend	= 0x10,	// Plugin will automatically suspend on silence
45 	};
46 
47 	int32le dwPluginId1;			// Plugin type (kEffectMagic, kDmoMagic, kBuzzMagic)
48 	int32le dwPluginId2;			// Plugin unique ID
49 	uint8le routingFlags;			// See RoutingFlags
50 	uint8le mixMode;
51 	uint8le gain;					// Divide by 10 to get real gain
52 	uint8le reserved;
53 	uint32le dwOutputRouting;		// 0 = send to master 0x80 + x = send to plugin x
54 	uint32le dwReserved[4];			// Reserved for routing info
55 	mpt::modecharbuf<32, mpt::String::nullTerminated> szName;         // User-chosen plugin display name - this is locale ANSI!
56 	mpt::modecharbuf<64, mpt::String::nullTerminated> szLibraryName;  // original DLL name - this is UTF-8!
57 
58 	// Should only be called from SNDMIXPLUGIN::SetBypass() and IMixPlugin::Bypass()
59 	void SetBypass(bool bypass = true) { if(bypass) routingFlags |= irBypass; else routingFlags &= uint8(~irBypass); }
60 };
61 
62 MPT_BINARY_STRUCT(SNDMIXPLUGININFO, 128)	// this is directly written to files, so the size must be correct!
63 
64 
65 struct SNDMIXPLUGIN
66 {
67 	IMixPlugin *pMixPlugin = nullptr;
68 	std::vector<std::byte> pluginData;
69 	SNDMIXPLUGININFO Info = {};
70 	float fDryRatio = 0;
71 	int32 defaultProgram = 0;
72 	int32 editorX = 0, editorY = 0;
73 
74 #if defined(MPT_ENABLE_CHARSET_LOCALE)
GetNameLocaleSNDMIXPLUGIN75 	const char * GetNameLocale() const
76 	{
77 		return Info.szName.buf;
78 	}
GetNameSNDMIXPLUGIN79 	mpt::ustring GetName() const
80 	{
81 		return mpt::ToUnicode(mpt::Charset::Locale, Info.szName);
82 	}
83 #endif // MPT_ENABLE_CHARSET_LOCALE
GetLibraryNameSNDMIXPLUGIN84 	mpt::ustring GetLibraryName() const
85 	{
86 		return mpt::ToUnicode(mpt::Charset::UTF8, Info.szLibraryName);
87 	}
88 
89 	// Check if a plugin is loaded into this slot (also returns true if the plugin in this slot has not been found)
IsValidPluginSNDMIXPLUGIN90 	bool IsValidPlugin() const { return (Info.dwPluginId1 | Info.dwPluginId2) != 0; }
91 
92 	// Input routing getters
GetGainSNDMIXPLUGIN93 	uint8 GetGain() const
94 		{ return Info.gain; }
GetMixModeSNDMIXPLUGIN95 	uint8 GetMixMode() const
96 		{ return Info.mixMode; }
IsMasterEffectSNDMIXPLUGIN97 	bool IsMasterEffect() const
98 		{ return (Info.routingFlags & SNDMIXPLUGININFO::irApplyToMaster) != 0; }
IsWetMixSNDMIXPLUGIN99 	bool IsWetMix() const
100 		{ return (Info.routingFlags & SNDMIXPLUGININFO::irWetMix) != 0; }
IsExpandedMixSNDMIXPLUGIN101 	bool IsExpandedMix() const
102 		{ return (Info.routingFlags & SNDMIXPLUGININFO::irExpandMix) != 0; }
IsBypassedSNDMIXPLUGIN103 	bool IsBypassed() const
104 		{ return (Info.routingFlags & SNDMIXPLUGININFO::irBypass) != 0; }
IsAutoSuspendableSNDMIXPLUGIN105 	bool IsAutoSuspendable() const
106 		{ return (Info.routingFlags & SNDMIXPLUGININFO::irAutoSuspend) != 0; }
107 
108 	// Input routing setters
109 	void SetGain(uint8 gain);
SetMixModeSNDMIXPLUGIN110 	void SetMixMode(uint8 mixMode)
111 		{ Info.mixMode = mixMode; }
112 	void SetMasterEffect(bool master = true)
113 		{ if(master) Info.routingFlags |= SNDMIXPLUGININFO::irApplyToMaster; else Info.routingFlags &= uint8(~SNDMIXPLUGININFO::irApplyToMaster); }
114 	void SetWetMix(bool wetMix = true)
115 		{ if(wetMix) Info.routingFlags |= SNDMIXPLUGININFO::irWetMix; else Info.routingFlags &= uint8(~SNDMIXPLUGININFO::irWetMix); }
116 	void SetExpandedMix(bool expanded = true)
117 		{ if(expanded) Info.routingFlags |= SNDMIXPLUGININFO::irExpandMix; else Info.routingFlags &= uint8(~SNDMIXPLUGININFO::irExpandMix); }
118 	void SetBypass(bool bypass = true);
119 	void SetAutoSuspend(bool suspend = true)
120 		{ if(suspend) Info.routingFlags |= SNDMIXPLUGININFO::irAutoSuspend; else Info.routingFlags &= uint8(~SNDMIXPLUGININFO::irAutoSuspend); }
121 
122 	// Output routing getters
IsOutputToMasterSNDMIXPLUGIN123 	bool IsOutputToMaster() const
124 		{ return Info.dwOutputRouting == 0; }
GetOutputPluginSNDMIXPLUGIN125 	PLUGINDEX GetOutputPlugin() const
126 		{ return Info.dwOutputRouting >= 0x80 ? static_cast<PLUGINDEX>(Info.dwOutputRouting - 0x80) : PLUGINDEX_INVALID; }
127 
128 	// Output routing setters
SetOutputToMasterSNDMIXPLUGIN129 	void SetOutputToMaster()
130 		{ Info.dwOutputRouting = 0; }
SetOutputPluginSNDMIXPLUGIN131 	void SetOutputPlugin(PLUGINDEX plugin)
132 		{ if(plugin < MAX_MIXPLUGINS) Info.dwOutputRouting = plugin + 0x80; else Info.dwOutputRouting = 0; }
133 
134 	void Destroy();
135 };
136 
137 bool CreateMixPluginProc(SNDMIXPLUGIN &mixPlugin, CSoundFile &sndFile);
138 
139 #endif // NO_PLUGINS
140 
141 OPENMPT_NAMESPACE_END
142