forked from MoonsideGames/FAudioGMS
fix effect chain memory issues
parent
8c26f79d28
commit
6cd6147961
180
src/FAudioGMS.c
180
src/FAudioGMS.c
|
@ -220,9 +220,9 @@ typedef union FAudioGMS_EffectParameters
|
|||
typedef struct FAudioGMS_EffectChain
|
||||
{
|
||||
uint32_t id;
|
||||
FAudioEffectChain fAudioEffectChain;
|
||||
FAudioGMS_EffectType *effectTypes; /* size equal to effect chain size */
|
||||
union FAudioGMS_EffectParameters *effectParameters; /* size equal to effect chain size */
|
||||
uint32_t effectCount;
|
||||
FAudioGMS_EffectType *effectTypes; /* length equal to effectCount */
|
||||
union FAudioGMS_EffectParameters *effectParameters; /* length equal to effectCount */
|
||||
} FAudioGMS_EffectChain;
|
||||
|
||||
static const float SPEED_OF_SOUND = 343.5f;
|
||||
|
@ -1268,7 +1268,15 @@ static void FAudioGMS_INTERNAL_SoundInstance_Destroy(FAudioGMS_SoundInstance* in
|
|||
device->soundInstances[instance->id] = NULL;
|
||||
IdStack_Push(&device->soundInstanceIndexStack, instance->id);
|
||||
FAudioGMS_INTERNAL_SoundInstance_Stop(instance);
|
||||
|
||||
if (instance->effectChainAttached)
|
||||
{
|
||||
FAudioVoice_DestroyVoice(instance->effectVoice);
|
||||
SDL_free(instance->effectSends.pSends);
|
||||
}
|
||||
|
||||
FAudioVoice_DestroyVoice(instance->handle);
|
||||
|
||||
if (!instance->isStatic)
|
||||
{
|
||||
SDL_free(instance->soundData.streamingSound.streamBuffer);
|
||||
|
@ -1329,8 +1337,7 @@ double FAudioGMS_EffectChain_Create()
|
|||
RETURN_ON_NULL_DEVICE(-1.0)
|
||||
FAudioGMS_EffectChain* effectChain = SDL_malloc(sizeof(FAudioGMS_EffectChain));
|
||||
|
||||
effectChain->fAudioEffectChain.EffectCount = 0;
|
||||
effectChain->fAudioEffectChain.pEffectDescriptors = NULL;
|
||||
effectChain->effectCount = 0;
|
||||
effectChain->effectTypes = NULL;
|
||||
effectChain->effectParameters = NULL;
|
||||
|
||||
|
@ -1353,23 +1360,13 @@ double FAudioGMS_EffectChain_Create()
|
|||
|
||||
static void FAudioGMS_INTERNAL_EffectChain_AddReverb(FAudioGMS_EffectChain* effectChain, FAudioFXReverbParameters *reverbParameters)
|
||||
{
|
||||
FAPO* reverb;
|
||||
FAudioCreateReverb(&reverb, 0);
|
||||
effectChain->effectCount += 1;
|
||||
|
||||
effectChain->fAudioEffectChain.EffectCount += 1;
|
||||
effectChain->fAudioEffectChain.pEffectDescriptors = SDL_realloc(effectChain->fAudioEffectChain.pEffectDescriptors, effectChain->fAudioEffectChain.EffectCount * sizeof(FAudioEffectDescriptor));
|
||||
effectChain->effectTypes = SDL_realloc(effectChain->effectTypes, effectChain->effectCount * sizeof(FAudioGMS_EffectType));
|
||||
effectChain->effectTypes[effectChain->effectCount - 1] = EffectType_Reverb;
|
||||
|
||||
FAudioEffectDescriptor* reverbDescriptor = &effectChain->fAudioEffectChain.pEffectDescriptors[effectChain->fAudioEffectChain.EffectCount - 1];
|
||||
|
||||
reverbDescriptor->InitialState = 1;
|
||||
reverbDescriptor->OutputChannels = device->deviceDetails.OutputFormat.Format.nChannels == 6 ? 6 : 1;
|
||||
reverbDescriptor->pEffect = reverb;
|
||||
|
||||
effectChain->effectTypes = SDL_realloc(effectChain->effectTypes, effectChain->fAudioEffectChain.EffectCount * sizeof(FAudioGMS_EffectType));
|
||||
effectChain->effectTypes[effectChain->fAudioEffectChain.EffectCount - 1] = EffectType_Reverb;
|
||||
|
||||
effectChain->effectParameters = SDL_realloc(effectChain->effectParameters, effectChain->fAudioEffectChain.EffectCount * sizeof(FAudioGMS_EffectParameters));
|
||||
SDL_memcpy(&effectChain->effectParameters[effectChain->fAudioEffectChain.EffectCount - 1], reverbParameters, sizeof(FAudioFXReverbParameters));
|
||||
effectChain->effectParameters = SDL_realloc(effectChain->effectParameters, effectChain->effectCount * sizeof(FAudioGMS_EffectParameters));
|
||||
SDL_memcpy(&effectChain->effectParameters[effectChain->effectCount - 1], reverbParameters, sizeof(FAudioFXReverbParameters));
|
||||
}
|
||||
|
||||
void FAudioGMS_EffectChain_AddDefaultReverb(double effectChainID)
|
||||
|
@ -1460,6 +1457,70 @@ void FAudioGMS_EffectChain_AddReverb(
|
|||
}
|
||||
}
|
||||
|
||||
static void FAudioGMS_INTERNAL_SoundInstance_SetEffectGain(FAudioGMS_SoundInstance *instance, float effectGain)
|
||||
{
|
||||
float* outputMatrix = instance->dspSettings.pMatrixCoefficients;
|
||||
|
||||
outputMatrix[0] = effectGain;
|
||||
if (instance->dspSettings.SrcChannelCount == 2)
|
||||
{
|
||||
outputMatrix[1] = effectGain;
|
||||
}
|
||||
|
||||
FAudioVoice_SetOutputMatrix(
|
||||
instance->handle,
|
||||
instance->effectVoice,
|
||||
instance->dspSettings.SrcChannelCount,
|
||||
1,
|
||||
outputMatrix,
|
||||
0);
|
||||
|
||||
instance->effectGain = effectGain;
|
||||
}
|
||||
|
||||
void FAudioGMS_SoundInstance_SetEffectGain(double soundInstanceID, double effectGain)
|
||||
{
|
||||
RETURN_ON_NULL_DEVICE()
|
||||
FAudioGMS_SoundInstance *instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID);
|
||||
|
||||
if (instance != NULL)
|
||||
{
|
||||
FAudioGMS_INTERNAL_SoundInstance_SetEffectGain(instance, effectGain);
|
||||
}
|
||||
}
|
||||
|
||||
static FAudioEffectChain* FAudioGMS_INTERNAL_CreateFAudioEffectChain(FAudioGMS_EffectChain* effectChain)
|
||||
{
|
||||
FAudioEffectChain* fAudioEffectChain = SDL_malloc(sizeof(FAudioEffectChain));
|
||||
uint32_t i;
|
||||
|
||||
fAudioEffectChain->EffectCount = effectChain->effectCount;
|
||||
fAudioEffectChain->pEffectDescriptors = SDL_malloc(fAudioEffectChain->EffectCount * sizeof(FAudioEffectDescriptor));
|
||||
|
||||
FAPO* reverb;
|
||||
|
||||
for (i = 0; i < effectChain->effectCount; i += 1)
|
||||
{
|
||||
switch (effectChain->effectTypes[i])
|
||||
{
|
||||
case EffectType_Reverb:
|
||||
FAudioCreateReverb(&reverb, 0);
|
||||
|
||||
FAudioEffectDescriptor* reverbDescriptor = &fAudioEffectChain->pEffectDescriptors[i];
|
||||
reverbDescriptor->InitialState = 1;
|
||||
reverbDescriptor->OutputChannels = device->deviceDetails.OutputFormat.Format.nChannels == 6 ? 6 : 1;
|
||||
reverbDescriptor->pEffect = reverb;
|
||||
break;
|
||||
|
||||
default:
|
||||
Log("Unknown effect type! Something is very wrong!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return fAudioEffectChain;
|
||||
}
|
||||
|
||||
void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effectChainID, double effectGain)
|
||||
{
|
||||
RETURN_ON_NULL_DEVICE()
|
||||
|
@ -1469,36 +1530,34 @@ void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effec
|
|||
|
||||
if (instance != NULL && effectChain != NULL)
|
||||
{
|
||||
if (!instance->effectChainAttached)
|
||||
if (instance->effectChainAttached)
|
||||
{
|
||||
FAudio_CreateSubmixVoice(
|
||||
device->handle,
|
||||
&instance->effectVoice,
|
||||
1, /* FIXME: is this correct? */
|
||||
device->deviceDetails.OutputFormat.Format.nSamplesPerSec,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
&effectChain->fAudioEffectChain);
|
||||
|
||||
instance->effectSends.SendCount = 2;
|
||||
instance->effectSends.pSends = SDL_malloc(2 * sizeof(FAudioSendDescriptor));
|
||||
|
||||
instance->effectSends.pSends[0].Flags = 0;
|
||||
instance->effectSends.pSends[0].pOutputVoice = device->masteringVoice;
|
||||
instance->effectSends.pSends[1].Flags = 0;
|
||||
instance->effectSends.pSends[1].pOutputVoice = instance->effectVoice;
|
||||
|
||||
instance->effectChainAttached = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FAudioVoice_SetEffectChain(
|
||||
instance->effectVoice,
|
||||
&effectChain->fAudioEffectChain);
|
||||
/* This frees the effect chain on the voice */
|
||||
FAudioVoice_SetEffectChain(instance->handle, NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < effectChain->fAudioEffectChain.EffectCount; i += 1)
|
||||
FAudioEffectChain* fAudioEffectChain = FAudioGMS_INTERNAL_CreateFAudioEffectChain(effectChain);
|
||||
FAudio_CreateSubmixVoice(
|
||||
device->handle,
|
||||
&instance->effectVoice,
|
||||
1, /* FIXME: is this correct? */
|
||||
device->deviceDetails.OutputFormat.Format.nSamplesPerSec,
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
fAudioEffectChain);
|
||||
|
||||
instance->effectSends.SendCount = 2;
|
||||
instance->effectSends.pSends = SDL_malloc(2 * sizeof(FAudioSendDescriptor));
|
||||
|
||||
instance->effectSends.pSends[0].Flags = 0;
|
||||
instance->effectSends.pSends[0].pOutputVoice = device->masteringVoice;
|
||||
instance->effectSends.pSends[1].Flags = 0;
|
||||
instance->effectSends.pSends[1].pOutputVoice = instance->effectVoice;
|
||||
|
||||
instance->effectChainAttached = 1;
|
||||
|
||||
for (i = 0; i < effectChain->effectCount; i += 1)
|
||||
{
|
||||
uint32_t parametersSize;
|
||||
void *parameters;
|
||||
|
@ -1526,24 +1585,15 @@ void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effec
|
|||
instance->handle,
|
||||
&instance->effectSends);
|
||||
|
||||
/* TODO: move this to a different API call */
|
||||
float *outputMatrix = instance->dspSettings.pMatrixCoefficients;
|
||||
FAudioGMS_INTERNAL_SoundInstance_SetEffectGain(instance, effectGain);
|
||||
|
||||
outputMatrix[0] = effectGain;
|
||||
if (instance->dspSettings.SrcChannelCount == 2)
|
||||
/* all the effect parameters are copied to the voice so we free here */
|
||||
for (i = 0; i < effectChain->effectCount; i += 1)
|
||||
{
|
||||
outputMatrix[1] = effectGain;
|
||||
FAPOBase_Release((FAPOBase*)fAudioEffectChain->pEffectDescriptors[i].pEffect);
|
||||
}
|
||||
|
||||
FAudioVoice_SetOutputMatrix(
|
||||
instance->handle,
|
||||
instance->effectVoice,
|
||||
instance->dspSettings.SrcChannelCount,
|
||||
1,
|
||||
outputMatrix,
|
||||
0);
|
||||
|
||||
instance->effectGain = effectGain;
|
||||
SDL_free(fAudioEffectChain->pEffectDescriptors);
|
||||
SDL_free(fAudioEffectChain);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1555,14 +1605,8 @@ static void FAudioGMS_INTERNAL_EffectChain_Destroy(FAudioGMS_EffectChain *effect
|
|||
device->effectChains[effectChain->id] = NULL;
|
||||
IdStack_Push(&device->effectChainIndexStack, effectChain->id);
|
||||
|
||||
for (i = 0; i < effectChain->fAudioEffectChain.EffectCount; i += 1)
|
||||
{
|
||||
FAPOBase_Release((FAPOBase*)effectChain->fAudioEffectChain.pEffectDescriptors[i].pEffect);
|
||||
}
|
||||
|
||||
SDL_free(effectChain->effectParameters);
|
||||
SDL_free(effectChain->effectTypes);
|
||||
SDL_free(effectChain->fAudioEffectChain.pEffectDescriptors);
|
||||
SDL_free(effectChain);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,7 +93,12 @@ FAUDIOGMSAPI void FAudioGMS_EffectChain_AddReverb(
|
|||
);
|
||||
FAUDIOGMSAPI void FAudioGMS_EffectChain_Destroy(double effectChainID);
|
||||
|
||||
/*
|
||||
* NOTE: Any changes to the effect chain will NOT apply after this is set!
|
||||
* You MUST call SetEffectChain again if you make changes to the effect chain parameters!
|
||||
*/
|
||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effectChainID, double effectGain);
|
||||
FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetEffectGain(double soundInstanceID, double effectGain);
|
||||
|
||||
FAUDIOGMSAPI void FAudioGMS_SetListenerPosition(double x, double y, double z);
|
||||
|
||||
|
|
Loading…
Reference in New Issue