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 /* This file has no documentation since the MSDN docs are still perfectly fine:
28  * https://docs.microsoft.com/en-us/windows/desktop/api/xapobase/
29  *
30  * Of course, the APIs aren't exactly the same since XAPO is super dependent on
31  * C++. Instead, we use a struct full of functions to mimic a vtable.
32  *
33  * To mimic the CXAPOParametersBase experience, initialize the object like this:
34  *
35  * extern FAPORegistrationProperties MyFAPOProperties;
36  * extern int32_t producer;
37  * typedef struct MyFAPOParams
38  * {
39  *	uint32_t something;
40  * } MyFAPOParams;
41  * typedef struct MyFAPO
42  * {
43  *	FAPOBase base;
44  *	uint32_t somethingElse;
45  * } MyFAPO;
46  * void MyFAPO_Free(void* fapo)
47  * {
48  *	MyFAPO *mine = (MyFAPO*) fapo;
49  *	mine->base.pFree(mine->base.m_pParameterBlocks);
50  *	mine->base.pFree(fapo);
51  * }
52  *
53  * MyFAPO *result = (MyFAPO*) SDL_malloc(sizeof(MyFAPO));
54  * uint8_t *params = (uint8_t*) SDL_malloc(sizeof(MyFAPOParams) * 3);
55  * CreateFAPOBase(
56  *	&result->base,
57  *	&MyFAPOProperties,
58  *	params,
59  *	sizeof(MyFAPOParams),
60  *	producer
61  * );
62  * result->base.base.Initialize = (InitializeFunc) MyFAPO_Initialize;
63  * result->base.base.Process = (ProcessFunc) MyFAPO_Process;
64  * result->base.Destructor = MyFAPO_Free;
65  */
66 
67 #ifndef FAPOBASE_H
68 #define FAPOBASE_H
69 
70 #include "FAPO.h"
71 
72 #ifdef __cplusplus
73 extern "C" {
74 #endif /* __cplusplus */
75 
76 /* Constants */
77 
78 #define FAPOBASE_DEFAULT_FORMAT_TAG		FAUDIO_FORMAT_IEEE_FLOAT
79 #define FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS	FAPO_MIN_CHANNELS
80 #define FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS	FAPO_MAX_CHANNELS
81 #define FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE	FAPO_MIN_FRAMERATE
82 #define FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE	FAPO_MAX_FRAMERATE
83 #define FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE	32
84 
85 #define FAPOBASE_DEFAULT_FLAG ( \
86 	FAPO_FLAG_CHANNELS_MUST_MATCH | \
87 	FAPO_FLAG_FRAMERATE_MUST_MATCH | \
88 	FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH | \
89 	FAPO_FLAG_BUFFERCOUNT_MUST_MATCH | \
90 	FAPO_FLAG_INPLACE_SUPPORTED \
91 )
92 
93 #define FAPOBASE_DEFAULT_BUFFER_COUNT 1
94 
95 /* FAPOBase Interface */
96 
97 typedef struct FAPOBase FAPOBase;
98 
99 typedef void (FAPOCALL * OnSetParametersFunc)(
100 	FAPOBase *fapo,
101 	const void* parameters,
102 	uint32_t parametersSize
103 );
104 
105 #pragma pack(push, 8)
106 struct FAPOBase
107 {
108 	/* Base Classes/Interfaces */
109 	FAPO base;
110 	void (FAPOCALL *Destructor)(void*);
111 
112 	/* Public Virtual Functions */
113 	OnSetParametersFunc OnSetParameters;
114 
115 	/* Private Variables */
116 	const FAPORegistrationProperties *m_pRegistrationProperties;
117 	void* m_pfnMatrixMixFunction;
118 	float *m_pfl32MatrixCoefficients;
119 	uint32_t m_nSrcFormatType;
120 	uint8_t m_fIsScalarMatrix;
121 	uint8_t m_fIsLocked;
122 	uint8_t *m_pParameterBlocks;
123 	uint8_t *m_pCurrentParameters;
124 	uint8_t *m_pCurrentParametersInternal;
125 	uint32_t m_uCurrentParametersIndex;
126 	uint32_t m_uParameterBlockByteSize;
127 	uint8_t m_fNewerResultsReady;
128 	uint8_t m_fProducer;
129 
130 	/* Protected Variables */
131 	int32_t m_lReferenceCount; /* LONG */
132 
133 	/* Allocator callbacks, NOT part of XAPOBase spec! */
134 	FAudioMallocFunc pMalloc;
135 	FAudioFreeFunc pFree;
136 	FAudioReallocFunc pRealloc;
137 };
138 #pragma pack(pop)
139 
140 FAPOAPI void CreateFAPOBase(
141 	FAPOBase *fapo,
142 	const FAPORegistrationProperties *pRegistrationProperties,
143 	uint8_t *pParameterBlocks,
144 	uint32_t uParameterBlockByteSize,
145 	uint8_t fProducer
146 );
147 
148 /* See "extensions/CustomAllocatorEXT.txt" for more information. */
149 FAPOAPI void CreateFAPOBaseWithCustomAllocatorEXT(
150 	FAPOBase *fapo,
151 	const FAPORegistrationProperties *pRegistrationProperties,
152 	uint8_t *pParameterBlocks,
153 	uint32_t uParameterBlockByteSize,
154 	uint8_t fProducer,
155 	FAudioMallocFunc customMalloc,
156 	FAudioFreeFunc customFree,
157 	FAudioReallocFunc customRealloc
158 );
159 
160 FAPOAPI int32_t FAPOBase_AddRef(FAPOBase *fapo);
161 
162 FAPOAPI int32_t FAPOBase_Release(FAPOBase *fapo);
163 
164 FAPOAPI uint32_t FAPOBase_GetRegistrationProperties(
165 	FAPOBase *fapo,
166 	FAPORegistrationProperties **ppRegistrationProperties
167 );
168 
169 FAPOAPI uint32_t FAPOBase_IsInputFormatSupported(
170 	FAPOBase *fapo,
171 	const FAudioWaveFormatEx *pOutputFormat,
172 	const FAudioWaveFormatEx *pRequestedInputFormat,
173 	FAudioWaveFormatEx **ppSupportedInputFormat
174 );
175 
176 FAPOAPI uint32_t FAPOBase_IsOutputFormatSupported(
177 	FAPOBase *fapo,
178 	const FAudioWaveFormatEx *pInputFormat,
179 	const FAudioWaveFormatEx *pRequestedOutputFormat,
180 	FAudioWaveFormatEx **ppSupportedOutputFormat
181 );
182 
183 FAPOAPI uint32_t FAPOBase_Initialize(
184 	FAPOBase *fapo,
185 	const void* pData,
186 	uint32_t DataByteSize
187 );
188 
189 FAPOAPI void FAPOBase_Reset(FAPOBase *fapo);
190 
191 FAPOAPI uint32_t FAPOBase_LockForProcess(
192 	FAPOBase *fapo,
193 	uint32_t InputLockedParameterCount,
194 	const FAPOLockForProcessBufferParameters *pInputLockedParameters,
195 	uint32_t OutputLockedParameterCount,
196 	const FAPOLockForProcessBufferParameters *pOutputLockedParameters
197 );
198 
199 FAPOAPI void FAPOBase_UnlockForProcess(FAPOBase *fapo);
200 
201 FAPOAPI uint32_t FAPOBase_CalcInputFrames(
202 	FAPOBase *fapo,
203 	uint32_t OutputFrameCount
204 );
205 
206 FAPOAPI uint32_t FAPOBase_CalcOutputFrames(
207 	FAPOBase *fapo,
208 	uint32_t InputFrameCount
209 );
210 
211 FAPOAPI uint32_t FAPOBase_ValidateFormatDefault(
212 	FAPOBase *fapo,
213 	FAudioWaveFormatEx *pFormat,
214 	uint8_t fOverwrite
215 );
216 
217 FAPOAPI uint32_t FAPOBase_ValidateFormatPair(
218 	FAPOBase *fapo,
219 	const FAudioWaveFormatEx *pSupportedFormat,
220 	FAudioWaveFormatEx *pRequestedFormat,
221 	uint8_t fOverwrite
222 );
223 
224 FAPOAPI void FAPOBase_ProcessThru(
225 	FAPOBase *fapo,
226 	void* pInputBuffer,
227 	float *pOutputBuffer,
228 	uint32_t FrameCount,
229 	uint16_t InputChannelCount,
230 	uint16_t OutputChannelCount,
231 	uint8_t MixWithOutput
232 );
233 
234 FAPOAPI void FAPOBase_SetParameters(
235 	FAPOBase *fapo,
236 	const void* pParameters,
237 	uint32_t ParameterByteSize
238 );
239 
240 FAPOAPI void FAPOBase_GetParameters(
241 	FAPOBase *fapo,
242 	void* pParameters,
243 	uint32_t ParameterByteSize
244 );
245 
246 FAPOAPI void FAPOBase_OnSetParameters(
247 	FAPOBase *fapo,
248 	const void* parameters,
249 	uint32_t parametersSize
250 );
251 
252 FAPOAPI uint8_t FAPOBase_ParametersChanged(FAPOBase *fapo);
253 
254 FAPOAPI uint8_t* FAPOBase_BeginProcess(FAPOBase *fapo);
255 
256 FAPOAPI void FAPOBase_EndProcess(FAPOBase *fapo);
257 
258 #ifdef __cplusplus
259 }
260 #endif /* __cplusplus */
261 
262 #endif /* FAPOBASE_H */
263 
264 /* vim: set noexpandtab shiftwidth=8 tabstop=8: */
265