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 /* FXEcho FAPO Implementation */
31 
32 const FAudioGUID FAPOFX_CLSID_FXEcho =
33 {
34 	0x5039D740,
35 	0xF736,
36 	0x449A,
37 	{
38 		0x84,
39 		0xD3,
40 		0xA5,
41 		0x62,
42 		0x02,
43 		0x55,
44 		0x7B,
45 		0x87
46 	}
47 };
48 
49 static FAPORegistrationProperties FXEchoProperties =
50 {
51 	/* .clsid = */ {0},
52 	/* .FriendlyName = */
53 	{
54 		'F', 'X', 'E', 'c', 'h', 'o', '\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_FXEcho_LEGACY =
77 {
78 	0xA90BC001,
79 	0xE897,
80 	0xE897,
81 	{
82 		0x74,
83 		0x39,
84 		0x43,
85 		0x55,
86 		0x00,
87 		0x00,
88 		0x00,
89 		0x03
90 	}
91 };
92 
93 static FAPORegistrationProperties FXEchoProperties_LEGACY =
94 {
95 	/* .clsid = */ {0},
96 	/* .FriendlyName = */
97 	{
98 		'F', 'X', 'E', 'c', 'h', 'o', '\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 FAPOFXEcho
121 {
122 	FAPOBase base;
123 
124 	/* TODO */
125 } FAPOFXEcho;
126 
FAPOFXEcho_Initialize(FAPOFXEcho * fapo,const void * pData,uint32_t DataByteSize)127 uint32_t FAPOFXEcho_Initialize(
128 	FAPOFXEcho *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 
FAPOFXEcho_Process(FAPOFXEcho * fapo,uint32_t InputProcessParameterCount,const FAPOProcessBufferParameters * pInputProcessParameters,uint32_t OutputProcessParameterCount,FAPOProcessBufferParameters * pOutputProcessParameters,int32_t IsEnabled)145 void FAPOFXEcho_Process(
146 	FAPOFXEcho *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 
FAPOFXEcho_Free(void * fapo)160 void FAPOFXEcho_Free(void* fapo)
161 {
162 	FAPOFXEcho *echo = (FAPOFXEcho*) fapo;
163 	echo->base.pFree(echo->base.m_pParameterBlocks);
164 	echo->base.pFree(fapo);
165 }
166 
167 /* Public API */
168 
FAPOFXCreateEcho(FAPO ** pEffect,const void * pInitData,uint32_t InitDataByteSize,FAudioMallocFunc customMalloc,FAudioFreeFunc customFree,FAudioReallocFunc customRealloc,uint8_t legacy)169 uint32_t FAPOFXCreateEcho(
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 FAPOFXEchoParameters fxdefault =
179 	{
180 		FAPOFXECHO_DEFAULT_WETDRYMIX,
181 		FAPOFXECHO_DEFAULT_FEEDBACK,
182 		FAPOFXECHO_DEFAULT_DELAY
183 	};
184 
185 	/* Allocate... */
186 	FAPOFXEcho *result = (FAPOFXEcho*) customMalloc(
187 		sizeof(FAPOFXEcho)
188 	);
189 	uint8_t *params = (uint8_t*) customMalloc(
190 		sizeof(FAPOFXEchoParameters) * 3
191 	);
192 	if (pInitData == NULL)
193 	{
194 		FAudio_zero(params, sizeof(FAPOFXEchoParameters) * 3);
195 		#define INITPARAMS(offset) \
196 			FAudio_memcpy( \
197 				params + sizeof(FAPOFXEchoParameters) * offset, \
198 				&fxdefault, \
199 				sizeof(FAPOFXEchoParameters) \
200 			);
201 		INITPARAMS(0)
202 		INITPARAMS(1)
203 		INITPARAMS(2)
204 		#undef INITPARAMS
205 	}
206 	else
207 	{
208 		FAudio_assert(InitDataByteSize == sizeof(FAPOFXEchoParameters));
209 		FAudio_memcpy(params, pInitData, InitDataByteSize);
210 		FAudio_memcpy(params + InitDataByteSize, pInitData, InitDataByteSize);
211 		FAudio_memcpy(params + (InitDataByteSize * 2), pInitData, InitDataByteSize);
212 	}
213 
214 	/* Initialize... */
215 	FAudio_memcpy(
216 		&FXEchoProperties_LEGACY.clsid,
217 		&FAPOFX_CLSID_FXEcho_LEGACY,
218 		sizeof(FAudioGUID)
219 	);
220 	FAudio_memcpy(
221 		&FXEchoProperties.clsid,
222 		&FAPOFX_CLSID_FXEcho,
223 		sizeof(FAudioGUID)
224 	);
225 	CreateFAPOBaseWithCustomAllocatorEXT(
226 		&result->base,
227 		legacy ? &FXEchoProperties_LEGACY : &FXEchoProperties,
228 		params,
229 		sizeof(FAPOFXEchoParameters),
230 		0,
231 		customMalloc,
232 		customFree,
233 		customRealloc
234 	);
235 
236 	/* Function table... */
237 	result->base.base.Initialize = (InitializeFunc)
238 		FAPOFXEcho_Initialize;
239 	result->base.base.Process = (ProcessFunc)
240 		FAPOFXEcho_Process;
241 	result->base.Destructor = FAPOFXEcho_Free;
242 
243 	/* Finally. */
244 	*pEffect = &result->base.base;
245 	return 0;
246 }
247 
248 /* vim: set noexpandtab shiftwidth=8 tabstop=8: */
249