Show More
Commit Description:
Various UI improvements.
Commit Description:
Various UI improvements.
References:
File last commit:
Show/Diff file:
Action:
FNA/lib/FAudio/src/FAPOBase.c
451 lines | 12.8 KiB | text/x-c | CLexer
451 lines | 12.8 KiB | text/x-c | CLexer
r0 | /* FAudio - XAudio Reimplementation for FNA | |||
* | ||||
* Copyright (c) 2011-2020 Ethan Lee, Luigi Auriemma, and the MonoGame Team | ||||
* | ||||
* This software is provided 'as-is', without any express or implied warranty. | ||||
* In no event will the authors be held liable for any damages arising from | ||||
* the use of this software. | ||||
* | ||||
* Permission is granted to anyone to use this software for any purpose, | ||||
* including commercial applications, and to alter it and redistribute it | ||||
* freely, subject to the following restrictions: | ||||
* | ||||
* 1. The origin of this software must not be misrepresented; you must not | ||||
* claim that you wrote the original software. If you use this software in a | ||||
* product, an acknowledgment in the product documentation would be | ||||
* appreciated but is not required. | ||||
* | ||||
* 2. Altered source versions must be plainly marked as such, and must not be | ||||
* misrepresented as being the original software. | ||||
* | ||||
* 3. This notice may not be removed or altered from any source distribution. | ||||
* | ||||
* Ethan "flibitijibibo" Lee <flibitijibibo@flibitijibibo.com> | ||||
* | ||||
*/ | ||||
#include "FAPOBase.h" | ||||
#include "FAudio_internal.h" | ||||
/* FAPOBase Interface */ | ||||
void CreateFAPOBase( | ||||
FAPOBase *fapo, | ||||
const FAPORegistrationProperties *pRegistrationProperties, | ||||
uint8_t *pParameterBlocks, | ||||
uint32_t uParameterBlockByteSize, | ||||
uint8_t fProducer | ||||
) { | ||||
CreateFAPOBaseWithCustomAllocatorEXT( | ||||
fapo, | ||||
pRegistrationProperties, | ||||
pParameterBlocks, | ||||
uParameterBlockByteSize, | ||||
fProducer, | ||||
FAudio_malloc, | ||||
FAudio_free, | ||||
FAudio_realloc | ||||
); | ||||
} | ||||
void CreateFAPOBaseWithCustomAllocatorEXT( | ||||
FAPOBase *fapo, | ||||
const FAPORegistrationProperties *pRegistrationProperties, | ||||
uint8_t *pParameterBlocks, | ||||
uint32_t uParameterBlockByteSize, | ||||
uint8_t fProducer, | ||||
FAudioMallocFunc customMalloc, | ||||
FAudioFreeFunc customFree, | ||||
FAudioReallocFunc customRealloc | ||||
) { | ||||
/* Base Classes/Interfaces */ | ||||
#define ASSIGN_VT(name) \ | ||||
fapo->base.name = (name##Func) FAPOBase_##name; | ||||
ASSIGN_VT(AddRef) | ||||
ASSIGN_VT(Release) | ||||
ASSIGN_VT(GetRegistrationProperties) | ||||
ASSIGN_VT(IsInputFormatSupported) | ||||
ASSIGN_VT(IsOutputFormatSupported) | ||||
ASSIGN_VT(Initialize) | ||||
ASSIGN_VT(Reset) | ||||
ASSIGN_VT(LockForProcess) | ||||
ASSIGN_VT(UnlockForProcess) | ||||
ASSIGN_VT(CalcInputFrames) | ||||
ASSIGN_VT(CalcOutputFrames) | ||||
ASSIGN_VT(SetParameters) | ||||
ASSIGN_VT(GetParameters) | ||||
#undef ASSIGN_VT | ||||
/* Public Virtual Functions */ | ||||
fapo->OnSetParameters = (OnSetParametersFunc) | ||||
FAPOBase_OnSetParameters; | ||||
/* Private Variables */ | ||||
fapo->m_pRegistrationProperties = pRegistrationProperties; /* FIXME */ | ||||
fapo->m_pfnMatrixMixFunction = NULL; /* FIXME */ | ||||
fapo->m_pfl32MatrixCoefficients = NULL; /* FIXME */ | ||||
fapo->m_nSrcFormatType = 0; /* FIXME */ | ||||
fapo->m_fIsScalarMatrix = 0; /* FIXME: */ | ||||
fapo->m_fIsLocked = 0; | ||||
fapo->m_pParameterBlocks = pParameterBlocks; | ||||
fapo->m_pCurrentParameters = pParameterBlocks; | ||||
fapo->m_pCurrentParametersInternal = pParameterBlocks; | ||||
fapo->m_uCurrentParametersIndex = 0; | ||||
fapo->m_uParameterBlockByteSize = uParameterBlockByteSize; | ||||
fapo->m_fNewerResultsReady = 0; | ||||
fapo->m_fProducer = fProducer; | ||||
/* Allocator Callbacks */ | ||||
fapo->pMalloc = customMalloc; | ||||
fapo->pFree = customFree; | ||||
fapo->pRealloc = customRealloc; | ||||
/* Protected Variables */ | ||||
fapo->m_lReferenceCount = 1; | ||||
} | ||||
int32_t FAPOBase_AddRef(FAPOBase *fapo) | ||||
{ | ||||
fapo->m_lReferenceCount += 1; | ||||
return fapo->m_lReferenceCount; | ||||
} | ||||
int32_t FAPOBase_Release(FAPOBase *fapo) | ||||
{ | ||||
fapo->m_lReferenceCount -= 1; | ||||
if (fapo->m_lReferenceCount == 0) | ||||
{ | ||||
fapo->Destructor(fapo); | ||||
return 0; | ||||
} | ||||
return fapo->m_lReferenceCount; | ||||
} | ||||
uint32_t FAPOBase_GetRegistrationProperties( | ||||
FAPOBase *fapo, | ||||
FAPORegistrationProperties **ppRegistrationProperties | ||||
) { | ||||
*ppRegistrationProperties = (FAPORegistrationProperties*) fapo->pMalloc( | ||||
sizeof(FAPORegistrationProperties) | ||||
); | ||||
FAudio_memcpy( | ||||
*ppRegistrationProperties, | ||||
fapo->m_pRegistrationProperties, | ||||
sizeof(FAPORegistrationProperties) | ||||
); | ||||
return 0; | ||||
} | ||||
uint32_t FAPOBase_IsInputFormatSupported( | ||||
FAPOBase *fapo, | ||||
const FAudioWaveFormatEx *pOutputFormat, | ||||
const FAudioWaveFormatEx *pRequestedInputFormat, | ||||
FAudioWaveFormatEx **ppSupportedInputFormat | ||||
) { | ||||
if ( pRequestedInputFormat->wFormatTag != FAPOBASE_DEFAULT_FORMAT_TAG || | ||||
pRequestedInputFormat->nChannels < FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS || | ||||
pRequestedInputFormat->nChannels > FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS || | ||||
pRequestedInputFormat->nSamplesPerSec < FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE || | ||||
pRequestedInputFormat->nSamplesPerSec > FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE || | ||||
pRequestedInputFormat->wBitsPerSample != FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE ) | ||||
{ | ||||
if (ppSupportedInputFormat != NULL) | ||||
{ | ||||
(*ppSupportedInputFormat)->wFormatTag = | ||||
FAPOBASE_DEFAULT_FORMAT_TAG; | ||||
(*ppSupportedInputFormat)->nChannels = FAudio_clamp( | ||||
pRequestedInputFormat->nChannels, | ||||
FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS, | ||||
FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS | ||||
); | ||||
(*ppSupportedInputFormat)->nSamplesPerSec = FAudio_clamp( | ||||
pRequestedInputFormat->nSamplesPerSec, | ||||
FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE, | ||||
FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE | ||||
); | ||||
(*ppSupportedInputFormat)->wBitsPerSample = | ||||
FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE; | ||||
} | ||||
return FAPO_E_FORMAT_UNSUPPORTED; | ||||
} | ||||
return 0; | ||||
} | ||||
uint32_t FAPOBase_IsOutputFormatSupported( | ||||
FAPOBase *fapo, | ||||
const FAudioWaveFormatEx *pInputFormat, | ||||
const FAudioWaveFormatEx *pRequestedOutputFormat, | ||||
FAudioWaveFormatEx **ppSupportedOutputFormat | ||||
) { | ||||
if ( pRequestedOutputFormat->wFormatTag != FAPOBASE_DEFAULT_FORMAT_TAG || | ||||
pRequestedOutputFormat->nChannels < FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS || | ||||
pRequestedOutputFormat->nChannels > FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS || | ||||
pRequestedOutputFormat->nSamplesPerSec < FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE || | ||||
pRequestedOutputFormat->nSamplesPerSec > FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE || | ||||
pRequestedOutputFormat->wBitsPerSample != FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE ) | ||||
{ | ||||
if (ppSupportedOutputFormat != NULL) | ||||
{ | ||||
(*ppSupportedOutputFormat)->wFormatTag = | ||||
FAPOBASE_DEFAULT_FORMAT_TAG; | ||||
(*ppSupportedOutputFormat)->nChannels = FAudio_clamp( | ||||
pRequestedOutputFormat->nChannels, | ||||
FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS, | ||||
FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS | ||||
); | ||||
(*ppSupportedOutputFormat)->nSamplesPerSec = FAudio_clamp( | ||||
pRequestedOutputFormat->nSamplesPerSec, | ||||
FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE, | ||||
FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE | ||||
); | ||||
(*ppSupportedOutputFormat)->wBitsPerSample = | ||||
FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE; | ||||
} | ||||
return FAPO_E_FORMAT_UNSUPPORTED; | ||||
} | ||||
return 0; | ||||
} | ||||
uint32_t FAPOBase_Initialize( | ||||
FAPOBase *fapo, | ||||
const void* pData, | ||||
uint32_t DataByteSize | ||||
) { | ||||
return 0; | ||||
} | ||||
void FAPOBase_Reset(FAPOBase *fapo) | ||||
{ | ||||
} | ||||
uint32_t FAPOBase_LockForProcess( | ||||
FAPOBase *fapo, | ||||
uint32_t InputLockedParameterCount, | ||||
const FAPOLockForProcessBufferParameters *pInputLockedParameters, | ||||
uint32_t OutputLockedParameterCount, | ||||
const FAPOLockForProcessBufferParameters *pOutputLockedParameters | ||||
) { | ||||
/* Verify parameter counts... */ | ||||
if ( InputLockedParameterCount < fapo->m_pRegistrationProperties->MinInputBufferCount || | ||||
InputLockedParameterCount > fapo->m_pRegistrationProperties->MaxInputBufferCount || | ||||
OutputLockedParameterCount < fapo->m_pRegistrationProperties->MinOutputBufferCount || | ||||
OutputLockedParameterCount > fapo->m_pRegistrationProperties->MaxOutputBufferCount ) | ||||
{ | ||||
return FAUDIO_E_INVALID_ARG; | ||||
} | ||||
/* Validate input/output formats */ | ||||
#define VERIFY_FORMAT_FLAG(flag, prop) \ | ||||
if ( (fapo->m_pRegistrationProperties->Flags & flag) && \ | ||||
(pInputLockedParameters->pFormat->prop != pOutputLockedParameters->pFormat->prop) ) \ | ||||
{ \ | ||||
return FAUDIO_E_INVALID_ARG; \ | ||||
} | ||||
VERIFY_FORMAT_FLAG(FAPO_FLAG_CHANNELS_MUST_MATCH, nChannels) | ||||
VERIFY_FORMAT_FLAG(FAPO_FLAG_FRAMERATE_MUST_MATCH, nSamplesPerSec) | ||||
VERIFY_FORMAT_FLAG(FAPO_FLAG_BITSPERSAMPLE_MUST_MATCH, wBitsPerSample) | ||||
#undef VERIFY_FORMAT_FLAG | ||||
if ( (fapo->m_pRegistrationProperties->Flags & FAPO_FLAG_BUFFERCOUNT_MUST_MATCH) && | ||||
(InputLockedParameterCount != OutputLockedParameterCount) ) | ||||
{ | ||||
return FAUDIO_E_INVALID_ARG; | ||||
} | ||||
fapo->m_fIsLocked = 1; | ||||
return 0; | ||||
} | ||||
void FAPOBase_UnlockForProcess(FAPOBase *fapo) | ||||
{ | ||||
fapo->m_fIsLocked = 0; | ||||
} | ||||
uint32_t FAPOBase_CalcInputFrames(FAPOBase *fapo, uint32_t OutputFrameCount) | ||||
{ | ||||
return OutputFrameCount; | ||||
} | ||||
uint32_t FAPOBase_CalcOutputFrames(FAPOBase *fapo, uint32_t InputFrameCount) | ||||
{ | ||||
return InputFrameCount; | ||||
} | ||||
uint32_t FAPOBase_ValidateFormatDefault( | ||||
FAPOBase *fapo, | ||||
FAudioWaveFormatEx *pFormat, | ||||
uint8_t fOverwrite | ||||
) { | ||||
if ( pFormat->wFormatTag != FAPOBASE_DEFAULT_FORMAT_TAG || | ||||
pFormat->nChannels < FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS || | ||||
pFormat->nChannels > FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS || | ||||
pFormat->nSamplesPerSec < FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE || | ||||
pFormat->nSamplesPerSec > FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE || | ||||
pFormat->wBitsPerSample != FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE ) | ||||
{ | ||||
if (fOverwrite) | ||||
{ | ||||
pFormat->wFormatTag = | ||||
FAPOBASE_DEFAULT_FORMAT_TAG; | ||||
pFormat->nChannels = FAudio_clamp( | ||||
pFormat->nChannels, | ||||
FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS, | ||||
FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS | ||||
); | ||||
pFormat->nSamplesPerSec = FAudio_clamp( | ||||
pFormat->nSamplesPerSec, | ||||
FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE, | ||||
FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE | ||||
); | ||||
pFormat->wBitsPerSample = | ||||
FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE; | ||||
} | ||||
return FAPO_E_FORMAT_UNSUPPORTED; | ||||
} | ||||
return 0; | ||||
} | ||||
uint32_t FAPOBase_ValidateFormatPair( | ||||
FAPOBase *fapo, | ||||
const FAudioWaveFormatEx *pSupportedFormat, | ||||
FAudioWaveFormatEx *pRequestedFormat, | ||||
uint8_t fOverwrite | ||||
) { | ||||
if ( pRequestedFormat->wFormatTag != FAPOBASE_DEFAULT_FORMAT_TAG || | ||||
pRequestedFormat->nChannels < FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS || | ||||
pRequestedFormat->nChannels > FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS || | ||||
pRequestedFormat->nSamplesPerSec < FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE || | ||||
pRequestedFormat->nSamplesPerSec > FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE || | ||||
pRequestedFormat->wBitsPerSample != FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE ) | ||||
{ | ||||
if (fOverwrite) | ||||
{ | ||||
pRequestedFormat->wFormatTag = | ||||
FAPOBASE_DEFAULT_FORMAT_TAG; | ||||
pRequestedFormat->nChannels = FAudio_clamp( | ||||
pRequestedFormat->nChannels, | ||||
FAPOBASE_DEFAULT_FORMAT_MIN_CHANNELS, | ||||
FAPOBASE_DEFAULT_FORMAT_MAX_CHANNELS | ||||
); | ||||
pRequestedFormat->nSamplesPerSec = FAudio_clamp( | ||||
pRequestedFormat->nSamplesPerSec, | ||||
FAPOBASE_DEFAULT_FORMAT_MIN_FRAMERATE, | ||||
FAPOBASE_DEFAULT_FORMAT_MAX_FRAMERATE | ||||
); | ||||
pRequestedFormat->wBitsPerSample = | ||||
FAPOBASE_DEFAULT_FORMAT_BITSPERSAMPLE; | ||||
} | ||||
return FAPO_E_FORMAT_UNSUPPORTED; | ||||
} | ||||
return 0; | ||||
} | ||||
void FAPOBase_ProcessThru( | ||||
FAPOBase *fapo, | ||||
void* pInputBuffer, | ||||
float *pOutputBuffer, | ||||
uint32_t FrameCount, | ||||
uint16_t InputChannelCount, | ||||
uint16_t OutputChannelCount, | ||||
uint8_t MixWithOutput | ||||
) { | ||||
uint32_t i, co, ci; | ||||
float *input = (float*) pInputBuffer; | ||||
if (MixWithOutput) | ||||
{ | ||||
/* TODO: SSE */ | ||||
for (i = 0; i < FrameCount; i += 1) | ||||
for (co = 0; co < OutputChannelCount; co += 1) | ||||
for (ci = 0; ci < InputChannelCount; ci += 1) | ||||
{ | ||||
/* Add, don't overwrite! */ | ||||
pOutputBuffer[i * OutputChannelCount + co] += | ||||
input[i * InputChannelCount + ci]; | ||||
} | ||||
} | ||||
else | ||||
{ | ||||
/* TODO: SSE */ | ||||
for (i = 0; i < FrameCount; i += 1) | ||||
for (co = 0; co < OutputChannelCount; co += 1) | ||||
for (ci = 0; ci < InputChannelCount; ci += 1) | ||||
{ | ||||
/* Overwrite, don't add! */ | ||||
pOutputBuffer[i * OutputChannelCount + co] = | ||||
input[i * InputChannelCount + ci]; | ||||
} | ||||
} | ||||
} | ||||
void FAPOBase_SetParameters( | ||||
FAPOBase *fapo, | ||||
const void* pParameters, | ||||
uint32_t ParameterByteSize | ||||
) { | ||||
FAudio_assert(!fapo->m_fProducer); | ||||
/* User callback for validation */ | ||||
fapo->OnSetParameters( | ||||
fapo, | ||||
pParameters, | ||||
ParameterByteSize | ||||
); | ||||
/* Increment parameter block index... */ | ||||
fapo->m_uCurrentParametersIndex += 1; | ||||
if (fapo->m_uCurrentParametersIndex == 3) | ||||
{ | ||||
fapo->m_uCurrentParametersIndex = 0; | ||||
} | ||||
fapo->m_pCurrentParametersInternal = fapo->m_pParameterBlocks + ( | ||||
fapo->m_uParameterBlockByteSize * | ||||
fapo->m_uCurrentParametersIndex | ||||
); | ||||
/* Copy to what will eventually be the next parameter update */ | ||||
FAudio_memcpy( | ||||
fapo->m_pCurrentParametersInternal, | ||||
pParameters, | ||||
ParameterByteSize | ||||
); | ||||
} | ||||
void FAPOBase_GetParameters( | ||||
FAPOBase *fapo, | ||||
void* pParameters, | ||||
uint32_t ParameterByteSize | ||||
) { | ||||
/* Copy what's current as of the last Process */ | ||||
FAudio_memcpy( | ||||
pParameters, | ||||
fapo->m_pCurrentParameters, | ||||
ParameterByteSize | ||||
); | ||||
} | ||||
void FAPOBase_OnSetParameters( | ||||
FAPOBase *fapo, | ||||
const void* parameters, | ||||
uint32_t parametersSize | ||||
) { | ||||
} | ||||
uint8_t FAPOBase_ParametersChanged(FAPOBase *fapo) | ||||
{ | ||||
/* Internal will get updated when SetParameters is called */ | ||||
return fapo->m_pCurrentParametersInternal != fapo->m_pCurrentParameters; | ||||
} | ||||
uint8_t* FAPOBase_BeginProcess(FAPOBase *fapo) | ||||
{ | ||||
/* Set the latest block as "current", this is what Process will use now */ | ||||
fapo->m_pCurrentParameters = fapo->m_pCurrentParametersInternal; | ||||
return fapo->m_pCurrentParameters; | ||||
} | ||||
void FAPOBase_EndProcess(FAPOBase *fapo) | ||||
{ | ||||
/* I'm 100% sure my parameter block increment is wrong... */ | ||||
} | ||||
/* vim: set noexpandtab shiftwidth=8 tabstop=8: */ | ||||