Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/faudio/src/FAPOBase.c
4389 views
1
/* FAudio - XAudio Reimplementation for FNA
2
*
3
* Copyright (c) 2011-2024 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 <[email protected]>
24
*
25
*/
26
27
#include "FAPOBase.h"
28
#include "FAudio_internal.h"
29
30
/* FAPOBase Interface */
31
32
void CreateFAPOBase(
33
FAPOBase *fapo,
34
const FAPORegistrationProperties *pRegistrationProperties,
35
uint8_t *pParameterBlocks,
36
uint32_t uParameterBlockByteSize,
37
uint8_t fProducer
38
) {
39
CreateFAPOBaseWithCustomAllocatorEXT(
40
fapo,
41
pRegistrationProperties,
42
pParameterBlocks,
43
uParameterBlockByteSize,
44
fProducer,
45
FAudio_malloc,
46
FAudio_free,
47
FAudio_realloc
48
);
49
}
50
51
void CreateFAPOBaseWithCustomAllocatorEXT(
52
FAPOBase *fapo,
53
const FAPORegistrationProperties *pRegistrationProperties,
54
uint8_t *pParameterBlocks,
55
uint32_t uParameterBlockByteSize,
56
uint8_t fProducer,
57
FAudioMallocFunc customMalloc,
58
FAudioFreeFunc customFree,
59
FAudioReallocFunc customRealloc
60
) {
61
/* Base Classes/Interfaces */
62
#define ASSIGN_VT(name) \
63
fapo->base.name = (name##Func) FAPOBase_##name;
64
ASSIGN_VT(AddRef)
65
ASSIGN_VT(Release)
66
ASSIGN_VT(GetRegistrationProperties)
67
ASSIGN_VT(IsInputFormatSupported)
68
ASSIGN_VT(IsOutputFormatSupported)
69
ASSIGN_VT(Initialize)
70
ASSIGN_VT(Reset)
71
ASSIGN_VT(LockForProcess)
72
ASSIGN_VT(UnlockForProcess)
73
ASSIGN_VT(CalcInputFrames)
74
ASSIGN_VT(CalcOutputFrames)
75
ASSIGN_VT(SetParameters)
76
ASSIGN_VT(GetParameters)
77
#undef ASSIGN_VT
78
79
/* Public Virtual Functions */
80
fapo->OnSetParameters = (OnSetParametersFunc)
81
FAPOBase_OnSetParameters;
82
83
/* Private Variables */
84
fapo->m_pRegistrationProperties = pRegistrationProperties; /* FIXME */
85
fapo->m_pfnMatrixMixFunction = NULL; /* FIXME */
86
fapo->m_pfl32MatrixCoefficients = NULL; /* FIXME */
87
fapo->m_nSrcFormatType = 0; /* FIXME */
88
fapo->m_fIsScalarMatrix = 0; /* FIXME: */
89
fapo->m_fIsLocked = 0;
90
fapo->m_pParameterBlocks = pParameterBlocks;
91
fapo->m_pCurrentParameters = pParameterBlocks;
92
fapo->m_pCurrentParametersInternal = pParameterBlocks;
93
fapo->m_uCurrentParametersIndex = 0;
94
fapo->m_uParameterBlockByteSize = uParameterBlockByteSize;
95
fapo->m_fNewerResultsReady = 0;
96
fapo->m_fProducer = fProducer;
97
98
/* Allocator Callbacks */
99
fapo->pMalloc = customMalloc;
100
fapo->pFree = customFree;
101
fapo->pRealloc = customRealloc;
102
103
/* Protected Variables */
104
fapo->m_lReferenceCount = 1;
105
}
106
107
int32_t FAPOBase_AddRef(FAPOBase *fapo)
108
{
109
fapo->m_lReferenceCount += 1;
110
return fapo->m_lReferenceCount;
111
}
112
113
int32_t FAPOBase_Release(FAPOBase *fapo)
114
{
115
fapo->m_lReferenceCount -= 1;
116
if (fapo->m_lReferenceCount == 0)
117
{
118
fapo->Destructor(fapo);
119
return 0;
120
}
121
return fapo->m_lReferenceCount;
122
}
123
124
uint32_t FAPOBase_GetRegistrationProperties(
125
FAPOBase *fapo,
126
FAPORegistrationProperties **ppRegistrationProperties
127
) {
128
*ppRegistrationProperties = (FAPORegistrationProperties*) fapo->pMalloc(
129
sizeof(FAPORegistrationProperties)
130
);
131
FAudio_memcpy(
132
*ppRegistrationProperties,
133
fapo->m_pRegistrationProperties,
134
sizeof(FAPORegistrationProperties)
135
);
136
return 0;
137
}
138
139
uint32_t FAPOBase_IsInputFormatSupported(
140
FAPOBase *fapo,
141
const FAudioWaveFormatEx *pOutputFormat,
142
const FAudioWaveFormatEx *pRequestedInputFormat,
143
FAudioWaveFormatEx **ppSupportedInputFormat
144
) {
145
if ( pRequestedInputFormat->wFormatTag != FAPOBASE_DEFAULT_FORMAT_TAG ||
146
pRequestedInputFormat->nChannels < FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS ||
147
pRequestedInputFormat->nChannels > FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS ||
148
pRequestedInputFormat->nSamplesPerSec < FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE ||
149
pRequestedInputFormat->nSamplesPerSec > FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE ||
150
pRequestedInputFormat->wBitsPerSample != FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE )
151
{
152
if (ppSupportedInputFormat != NULL)
153
{
154
(*ppSupportedInputFormat)->wFormatTag =
155
FAPOBASE_DEFAULT_FORMAT_TAG;
156
(*ppSupportedInputFormat)->nChannels = FAudio_clamp(
157
pRequestedInputFormat->nChannels,
158
FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS,
159
FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS
160
);
161
(*ppSupportedInputFormat)->nSamplesPerSec = FAudio_clamp(
162
pRequestedInputFormat->nSamplesPerSec,
163
FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE,
164
FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE
165
);
166
(*ppSupportedInputFormat)->wBitsPerSample =
167
FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE;
168
}
169
return FAPO_E_FORMAT_UNSUPPORTED;
170
}
171
return 0;
172
}
173
174
uint32_t FAPOBase_IsOutputFormatSupported(
175
FAPOBase *fapo,
176
const FAudioWaveFormatEx *pInputFormat,
177
const FAudioWaveFormatEx *pRequestedOutputFormat,
178
FAudioWaveFormatEx **ppSupportedOutputFormat
179
) {
180
if ( pRequestedOutputFormat->wFormatTag != FAPOBASE_DEFAULT_FORMAT_TAG ||
181
pRequestedOutputFormat->nChannels < FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS ||
182
pRequestedOutputFormat->nChannels > FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS ||
183
pRequestedOutputFormat->nSamplesPerSec < FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE ||
184
pRequestedOutputFormat->nSamplesPerSec > FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE ||
185
pRequestedOutputFormat->wBitsPerSample != FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE )
186
{
187
if (ppSupportedOutputFormat != NULL)
188
{
189
(*ppSupportedOutputFormat)->wFormatTag =
190
FAPOBASE_DEFAULT_FORMAT_TAG;
191
(*ppSupportedOutputFormat)->nChannels = FAudio_clamp(
192
pRequestedOutputFormat->nChannels,
193
FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS,
194
FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS
195
);
196
(*ppSupportedOutputFormat)->nSamplesPerSec = FAudio_clamp(
197
pRequestedOutputFormat->nSamplesPerSec,
198
FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE,
199
FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE
200
);
201
(*ppSupportedOutputFormat)->wBitsPerSample =
202
FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE;
203
}
204
return FAPO_E_FORMAT_UNSUPPORTED;
205
}
206
return 0;
207
}
208
209
uint32_t FAPOBase_Initialize(
210
FAPOBase *fapo,
211
const void* pData,
212
uint32_t DataByteSize
213
) {
214
return 0;
215
}
216
217
void FAPOBase_Reset(FAPOBase *fapo)
218
{
219
}
220
221
uint32_t FAPOBase_LockForProcess(
222
FAPOBase *fapo,
223
uint32_t InputLockedParameterCount,
224
const FAPOLockForProcessBufferParameters *pInputLockedParameters,
225
uint32_t OutputLockedParameterCount,
226
const FAPOLockForProcessBufferParameters *pOutputLockedParameters
227
) {
228
/* Verify parameter counts... */
229
if ( InputLockedParameterCount < fapo->m_pRegistrationProperties->MinInputBufferCount ||
230
InputLockedParameterCount > fapo->m_pRegistrationProperties->MaxInputBufferCount ||
231
OutputLockedParameterCount < fapo->m_pRegistrationProperties->MinOutputBufferCount ||
232
OutputLockedParameterCount > fapo->m_pRegistrationProperties->MaxOutputBufferCount )
233
{
234
return FAUDIO_E_INVALID_ARG;
235
}
236
237
238
/* Validate input/output formats */
239
#define VERIFY_FORMAT_FLAG(flag, prop) \
240
if ( (fapo->m_pRegistrationProperties->Flags & flag) && \
241
(pInputLockedParameters->pFormat->prop != pOutputLockedParameters->pFormat->prop) ) \
242
{ \
243
return FAUDIO_E_INVALID_ARG; \
244
}
245
VERIFY_FORMAT_FLAG(FAPO_FLAG_CHANNELS_MUST_MATCH, nChannels)
246
VERIFY_FORMAT_FLAG(FAPO_FLAG_FRAMERATE_MUST_MATCH, nSamplesPerSec)
247
VERIFY_FORMAT_FLAG(FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH, wBitsPerSample)
248
#undef VERIFY_FORMAT_FLAG
249
if ( (fapo->m_pRegistrationProperties->Flags & FAPO_FLAG_BUFFERCOUNT_MUST_MATCH) &&
250
(InputLockedParameterCount != OutputLockedParameterCount) )
251
{
252
return FAUDIO_E_INVALID_ARG;
253
}
254
fapo->m_fIsLocked = 1;
255
return 0;
256
}
257
258
void FAPOBase_UnlockForProcess(FAPOBase *fapo)
259
{
260
fapo->m_fIsLocked = 0;
261
}
262
263
uint32_t FAPOBase_CalcInputFrames(FAPOBase *fapo, uint32_t OutputFrameCount)
264
{
265
return OutputFrameCount;
266
}
267
268
uint32_t FAPOBase_CalcOutputFrames(FAPOBase *fapo, uint32_t InputFrameCount)
269
{
270
return InputFrameCount;
271
}
272
273
uint32_t FAPOBase_ValidateFormatDefault(
274
FAPOBase *fapo,
275
FAudioWaveFormatEx *pFormat,
276
uint8_t fOverwrite
277
) {
278
if ( pFormat->wFormatTag != FAPOBASE_DEFAULT_FORMAT_TAG ||
279
pFormat->nChannels < FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS ||
280
pFormat->nChannels > FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS ||
281
pFormat->nSamplesPerSec < FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE ||
282
pFormat->nSamplesPerSec > FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE ||
283
pFormat->wBitsPerSample != FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE )
284
{
285
if (fOverwrite)
286
{
287
pFormat->wFormatTag =
288
FAPOBASE_DEFAULT_FORMAT_TAG;
289
pFormat->nChannels = FAudio_clamp(
290
pFormat->nChannels,
291
FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS,
292
FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS
293
);
294
pFormat->nSamplesPerSec = FAudio_clamp(
295
pFormat->nSamplesPerSec,
296
FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE,
297
FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE
298
);
299
pFormat->wBitsPerSample =
300
FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE;
301
}
302
return FAPO_E_FORMAT_UNSUPPORTED;
303
}
304
return 0;
305
}
306
307
uint32_t FAPOBase_ValidateFormatPair(
308
FAPOBase *fapo,
309
const FAudioWaveFormatEx *pSupportedFormat,
310
FAudioWaveFormatEx *pRequestedFormat,
311
uint8_t fOverwrite
312
) {
313
if ( pRequestedFormat->wFormatTag != FAPOBASE_DEFAULT_FORMAT_TAG ||
314
pRequestedFormat->nChannels < FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS ||
315
pRequestedFormat->nChannels > FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS ||
316
pRequestedFormat->nSamplesPerSec < FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE ||
317
pRequestedFormat->nSamplesPerSec > FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE ||
318
pRequestedFormat->wBitsPerSample != FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE )
319
{
320
if (fOverwrite)
321
{
322
pRequestedFormat->wFormatTag =
323
FAPOBASE_DEFAULT_FORMAT_TAG;
324
pRequestedFormat->nChannels = FAudio_clamp(
325
pRequestedFormat->nChannels,
326
FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS,
327
FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS
328
);
329
pRequestedFormat->nSamplesPerSec = FAudio_clamp(
330
pRequestedFormat->nSamplesPerSec,
331
FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE,
332
FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE
333
);
334
pRequestedFormat->wBitsPerSample =
335
FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE;
336
}
337
return FAPO_E_FORMAT_UNSUPPORTED;
338
}
339
return 0;
340
}
341
342
void FAPOBase_ProcessThru(
343
FAPOBase *fapo,
344
void* pInputBuffer,
345
float *pOutputBuffer,
346
uint32_t FrameCount,
347
uint16_t InputChannelCount,
348
uint16_t OutputChannelCount,
349
uint8_t MixWithOutput
350
) {
351
uint32_t i, co, ci;
352
float *input = (float*) pInputBuffer;
353
354
if (MixWithOutput)
355
{
356
/* TODO: SSE */
357
for (i = 0; i < FrameCount; i += 1)
358
for (co = 0; co < OutputChannelCount; co += 1)
359
for (ci = 0; ci < InputChannelCount; ci += 1)
360
{
361
/* Add, don't overwrite! */
362
pOutputBuffer[i * OutputChannelCount + co] +=
363
input[i * InputChannelCount + ci];
364
}
365
}
366
else
367
{
368
/* TODO: SSE */
369
for (i = 0; i < FrameCount; i += 1)
370
for (co = 0; co < OutputChannelCount; co += 1)
371
for (ci = 0; ci < InputChannelCount; ci += 1)
372
{
373
/* Overwrite, don't add! */
374
pOutputBuffer[i * OutputChannelCount + co] =
375
input[i * InputChannelCount + ci];
376
}
377
}
378
}
379
380
void FAPOBase_SetParameters(
381
FAPOBase *fapo,
382
const void* pParameters,
383
uint32_t ParameterByteSize
384
) {
385
FAudio_assert(!fapo->m_fProducer);
386
387
/* User callback for validation */
388
fapo->OnSetParameters(
389
fapo,
390
pParameters,
391
ParameterByteSize
392
);
393
394
/* Increment parameter block index... */
395
fapo->m_uCurrentParametersIndex += 1;
396
if (fapo->m_uCurrentParametersIndex == 3)
397
{
398
fapo->m_uCurrentParametersIndex = 0;
399
}
400
fapo->m_pCurrentParametersInternal = fapo->m_pParameterBlocks + (
401
fapo->m_uParameterBlockByteSize *
402
fapo->m_uCurrentParametersIndex
403
);
404
405
/* Copy to what will eventually be the next parameter update */
406
FAudio_memcpy(
407
fapo->m_pCurrentParametersInternal,
408
pParameters,
409
ParameterByteSize
410
);
411
}
412
413
void FAPOBase_GetParameters(
414
FAPOBase *fapo,
415
void* pParameters,
416
uint32_t ParameterByteSize
417
) {
418
/* Copy what's current as of the last Process */
419
FAudio_memcpy(
420
pParameters,
421
fapo->m_pCurrentParameters,
422
ParameterByteSize
423
);
424
}
425
426
void FAPOBase_OnSetParameters(
427
FAPOBase *fapo,
428
const void* parameters,
429
uint32_t parametersSize
430
) {
431
}
432
433
uint8_t FAPOBase_ParametersChanged(FAPOBase *fapo)
434
{
435
/* Internal will get updated when SetParameters is called */
436
return fapo->m_pCurrentParametersInternal != fapo->m_pCurrentParameters;
437
}
438
439
uint8_t* FAPOBase_BeginProcess(FAPOBase *fapo)
440
{
441
/* Set the latest block as "current", this is what Process will use now */
442
fapo->m_pCurrentParameters = fapo->m_pCurrentParametersInternal;
443
return fapo->m_pCurrentParameters;
444
}
445
446
void FAPOBase_EndProcess(FAPOBase *fapo)
447
{
448
/* I'm 100% sure my parameter block increment is wrong... */
449
}
450
451
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */
452
453