1 /* FAudio - XAudio Reimplementation for FNA
2  *
3  * Copyright (c) 2011-2021 Ethan Lee, Luigi Auriemma, and the MonoGame Team
4  *
5  * This software is provided 'as-is', without any express or implied warranty.
6  * In no event will the authors be held liable for any damages arising from
7  * the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software in a
15  * product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  *
18  * 2. Altered source versions must be plainly marked as such, and must not be
19  * misrepresented as being the original software.
20  *
21  * 3. This notice may not be removed or altered from any source distribution.
22  *
23  * Ethan "flibitijibibo" Lee <flibitijibibo@flibitijibibo.com>
24  *
25  */
26 
27 #include "FAPOFX.h"
28 #include "FAudio_internal.h"
29 
30 /* FXMasteringLimiter FAPO Implementation */
31 
32 const FAudioGUID FAPOFX_CLSID_FXMasteringLimiter =
33 {
34 	0xC4137916,
35 	0x2BE1,
36 	0x46FD,
37 	{
38 		0x85,
39 		0x99,
40 		0x44,
41 		0x15,
42 		0x36,
43 		0xF4,
44 		0x98,
45 		0x56
46 	}
47 };
48 
49 static FAPORegistrationProperties FXMasteringLimiterProperties =
50 {
51 	/* .clsid = */ {0},
52 	/* .FriendlyName = */
53 	{
54 		'F', 'X', 'M', 'a', 's', 't', 'e', 'r', 'i', 'n', 'g', 'L', 'i', 'm', 'i', 't', 'e', 'r', '\0'
55 	},
56 	/*.CopyrightInfo = */
57 	{
58 		'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', ' ', '(', 'c', ')',
59 		'E', 't', 'h', 'a', 'n', ' ', 'L', 'e', 'e', '\0'
60 	},
61 	/*.MajorVersion = */ 0,
62 	/*.MinorVersion = */ 0,
63 	/*.Flags = */(
64 		FAPO_FLAG_FRAMERATE_MUST_MATCH |
65 		FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH |
66 		FAPO_FLAG_BUFFERCOUNT_MUST_MATCH |
67 		FAPO_FLAG_INPLACE_SUPPORTED |
68 		FAPO_FLAG_INPLACE_REQUIRED
69 	),
70 	/*.MinInputBufferCount = */ 1,
71 	/*.MaxInputBufferCount = */  1,
72 	/*.MinOutputBufferCount = */ 1,
73 	/*.MaxOutputBufferCount =*/ 1
74 };
75 
76 const FAudioGUID FAPOFX_CLSID_FXMasteringLimiter_LEGACY =
77 {
78 	0xA90BC001,
79 	0xE897,
80 	0xE897,
81 	{
82 		0x74,
83 		0x39,
84 		0x43,
85 		0x55,
86 		0x00,
87 		0x00,
88 		0x00,
89 		0x01
90 	}
91 };
92 
93 static FAPORegistrationProperties FXMasteringLimiterProperties_LEGACY =
94 {
95 	/* .clsid = */ {0},
96 	/* .FriendlyName = */
97 	{
98 		'F', 'X', 'M', 'a', 's', 't', 'e', 'r', 'i', 'n', 'g', 'L', 'i', 'm', 'i', 't', 'e', 'r', '\0'
99 	},
100 	/*.CopyrightInfo = */
101 	{
102 		'C', 'o', 'p', 'y', 'r', 'i', 'g', 'h', 't', ' ', '(', 'c', ')',
103 		'E', 't', 'h', 'a', 'n', ' ', 'L', 'e', 'e', '\0'
104 	},
105 	/*.MajorVersion = */ 0,
106 	/*.MinorVersion = */ 0,
107 	/*.Flags = */(
108 		FAPO_FLAG_FRAMERATE_MUST_MATCH |
109 		FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH |
110 		FAPO_FLAG_BUFFERCOUNT_MUST_MATCH |
111 		FAPO_FLAG_INPLACE_SUPPORTED |
112 		FAPO_FLAG_INPLACE_REQUIRED
113 	),
114 	/*.MinInputBufferCount = */ 1,
115 	/*.MaxInputBufferCount = */  1,
116 	/*.MinOutputBufferCount = */ 1,
117 	/*.MaxOutputBufferCount =*/ 1
118 };
119 
120 typedef struct FAPOFXMasteringLimiter
121 {
122 	FAPOBase base;
123 
124 	/* TODO */
125 } FAPOFXMasteringLimiter;
126 
FAPOFXMasteringLimiter_Initialize(FAPOFXMasteringLimiter * fapo,const void * pData,uint32_t DataByteSize)127 uint32_t FAPOFXMasteringLimiter_Initialize(
128 	FAPOFXMasteringLimiter *fapo,
129 	const void* pData,
130 	uint32_t DataByteSize
131 ) {
132 	#define INITPARAMS(offset) \
133 		FAudio_memcpy( \
134 			fapo->base.m_pParameterBlocks + DataByteSize * offset, \
135 			pData, \
136 			DataByteSize \
137 		);
138 	INITPARAMS(0)
139 	INITPARAMS(1)
140 	INITPARAMS(2)
141 	#undef INITPARAMS
142 	return 0;
143 }
144 
FAPOFXMasteringLimiter_Process(FAPOFXMasteringLimiter * fapo,uint32_t InputProcessParameterCount,const FAPOProcessBufferParameters * pInputProcessParameters,uint32_t OutputProcessParameterCount,FAPOProcessBufferParameters * pOutputProcessParameters,int32_t IsEnabled)145 void FAPOFXMasteringLimiter_Process(
146 	FAPOFXMasteringLimiter *fapo,
147 	uint32_t InputProcessParameterCount,
148 	const FAPOProcessBufferParameters* pInputProcessParameters,
149 	uint32_t OutputProcessParameterCount,
150 	FAPOProcessBufferParameters* pOutputProcessParameters,
151 	int32_t IsEnabled
152 ) {
153 	FAPOBase_BeginProcess(&fapo->base);
154 
155 	/* TODO */
156 
157 	FAPOBase_EndProcess(&fapo->base);
158 }
159 
FAPOFXMasteringLimiter_Free(void * fapo)160 void FAPOFXMasteringLimiter_Free(void* fapo)
161 {
162 	FAPOFXMasteringLimiter *limiter = (FAPOFXMasteringLimiter*) fapo;
163 	limiter->base.pFree(limiter->base.m_pParameterBlocks);
164 	limiter->base.pFree(fapo);
165 }
166 
167 /* Public API */
168 
FAPOFXCreateMasteringLimiter(FAPO ** pEffect,const void * pInitData,uint32_t InitDataByteSize,FAudioMallocFunc customMalloc,FAudioFreeFunc customFree,FAudioReallocFunc customRealloc,uint8_t legacy)169 uint32_t FAPOFXCreateMasteringLimiter(
170 	FAPO **pEffect,
171 	const void *pInitData,
172 	uint32_t InitDataByteSize,
173 	FAudioMallocFunc customMalloc,
174 	FAudioFreeFunc customFree,
175 	FAudioReallocFunc customRealloc,
176 	uint8_t legacy
177 ) {
178 	const FAPOFXMasteringLimiterParameters fxdefault =
179 	{
180 		FAPOFXMASTERINGLIMITER_DEFAULT_RELEASE,
181 		FAPOFXMASTERINGLIMITER_DEFAULT_LOUDNESS
182 	};
183 
184 	/* Allocate... */
185 	FAPOFXMasteringLimiter *result = (FAPOFXMasteringLimiter*) customMalloc(
186 		sizeof(FAPOFXMasteringLimiter)
187 	);
188 	uint8_t *params = (uint8_t*) customMalloc(
189 		sizeof(FAPOFXMasteringLimiterParameters) * 3
190 	);
191 	if (pInitData == NULL)
192 	{
193 		FAudio_zero(params, sizeof(FAPOFXMasteringLimiterParameters) * 3);
194 		#define INITPARAMS(offset) \
195 			FAudio_memcpy( \
196 				params + sizeof(FAPOFXMasteringLimiterParameters) * offset, \
197 				&fxdefault, \
198 				sizeof(FAPOFXMasteringLimiterParameters) \
199 			);
200 		INITPARAMS(0)
201 		INITPARAMS(1)
202 		INITPARAMS(2)
203 		#undef INITPARAMS
204 	}
205 	else
206 	{
207 		FAudio_assert(InitDataByteSize == sizeof(FAPOFXMasteringLimiterParameters));
208 		FAudio_memcpy(params, pInitData, InitDataByteSize);
209 		FAudio_memcpy(params + InitDataByteSize, pInitData, InitDataByteSize);
210 		FAudio_memcpy(params + (InitDataByteSize * 2), pInitData, InitDataByteSize);
211 	}
212 
213 	/* Initialize... */
214 	FAudio_memcpy(
215 		&FXMasteringLimiterProperties_LEGACY.clsid,
216 		&FAPOFX_CLSID_FXMasteringLimiter_LEGACY,
217 		sizeof(FAudioGUID)
218 	);
219 	FAudio_memcpy(
220 		&FXMasteringLimiterProperties.clsid,
221 		&FAPOFX_CLSID_FXMasteringLimiter,
222 		sizeof(FAudioGUID)
223 	);
224 	CreateFAPOBaseWithCustomAllocatorEXT(
225 		&result->base,
226 		legacy ? &FXMasteringLimiterProperties_LEGACY : &FXMasteringLimiterProperties,
227 		params,
228 		sizeof(FAPOFXMasteringLimiterParameters),
229 		0,
230 		customMalloc,
231 		customFree,
232 		customRealloc
233 	);
234 
235 	/* Function table... */
236 	result->base.base.Initialize = (InitializeFunc)
237 		FAPOFXMasteringLimiter_Initialize;
238 	result->base.base.Process = (ProcessFunc)
239 		FAPOFXMasteringLimiter_Process;
240 	result->base.Destructor = FAPOFXMasteringLimiter_Free;
241 
242 	/* Finally. */
243 	*pEffect = &result->base.base;
244 	return 0;
245 }
246 
247 /* vim: set noexpandtab shiftwidth=8 tabstop=8: */
248