forked from MoonsideGames/FAudioGMS
fix effect chain memory issues
parent
b896704dc2
commit
97924093ee
180
src/FAudioGMS.c
180
src/FAudioGMS.c
|
@ -220,9 +220,9 @@ typedef union FAudioGMS_EffectParameters
|
||||||
typedef struct FAudioGMS_EffectChain
|
typedef struct FAudioGMS_EffectChain
|
||||||
{
|
{
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
FAudioEffectChain fAudioEffectChain;
|
uint32_t effectCount;
|
||||||
FAudioGMS_EffectType *effectTypes; /* size equal to effect chain size */
|
FAudioGMS_EffectType *effectTypes; /* length equal to effectCount */
|
||||||
union FAudioGMS_EffectParameters *effectParameters; /* size equal to effect chain size */
|
union FAudioGMS_EffectParameters *effectParameters; /* length equal to effectCount */
|
||||||
} FAudioGMS_EffectChain;
|
} FAudioGMS_EffectChain;
|
||||||
|
|
||||||
static const float SPEED_OF_SOUND = 343.5f;
|
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;
|
device->soundInstances[instance->id] = NULL;
|
||||||
IdStack_Push(&device->soundInstanceIndexStack, instance->id);
|
IdStack_Push(&device->soundInstanceIndexStack, instance->id);
|
||||||
FAudioGMS_INTERNAL_SoundInstance_Stop(instance);
|
FAudioGMS_INTERNAL_SoundInstance_Stop(instance);
|
||||||
|
|
||||||
|
if (instance->effectChainAttached)
|
||||||
|
{
|
||||||
|
FAudioVoice_DestroyVoice(instance->effectVoice);
|
||||||
|
SDL_free(instance->effectSends.pSends);
|
||||||
|
}
|
||||||
|
|
||||||
FAudioVoice_DestroyVoice(instance->handle);
|
FAudioVoice_DestroyVoice(instance->handle);
|
||||||
|
|
||||||
if (!instance->isStatic)
|
if (!instance->isStatic)
|
||||||
{
|
{
|
||||||
SDL_free(instance->soundData.streamingSound.streamBuffer);
|
SDL_free(instance->soundData.streamingSound.streamBuffer);
|
||||||
|
@ -1329,8 +1337,7 @@ double FAudioGMS_EffectChain_Create()
|
||||||
RETURN_ON_NULL_DEVICE(-1.0)
|
RETURN_ON_NULL_DEVICE(-1.0)
|
||||||
FAudioGMS_EffectChain* effectChain = SDL_malloc(sizeof(FAudioGMS_EffectChain));
|
FAudioGMS_EffectChain* effectChain = SDL_malloc(sizeof(FAudioGMS_EffectChain));
|
||||||
|
|
||||||
effectChain->fAudioEffectChain.EffectCount = 0;
|
effectChain->effectCount = 0;
|
||||||
effectChain->fAudioEffectChain.pEffectDescriptors = NULL;
|
|
||||||
effectChain->effectTypes = NULL;
|
effectChain->effectTypes = NULL;
|
||||||
effectChain->effectParameters = NULL;
|
effectChain->effectParameters = NULL;
|
||||||
|
|
||||||
|
@ -1353,23 +1360,13 @@ double FAudioGMS_EffectChain_Create()
|
||||||
|
|
||||||
static void FAudioGMS_INTERNAL_EffectChain_AddReverb(FAudioGMS_EffectChain* effectChain, FAudioFXReverbParameters *reverbParameters)
|
static void FAudioGMS_INTERNAL_EffectChain_AddReverb(FAudioGMS_EffectChain* effectChain, FAudioFXReverbParameters *reverbParameters)
|
||||||
{
|
{
|
||||||
FAPO* reverb;
|
effectChain->effectCount += 1;
|
||||||
FAudioCreateReverb(&reverb, 0);
|
|
||||||
|
|
||||||
effectChain->fAudioEffectChain.EffectCount += 1;
|
effectChain->effectTypes = SDL_realloc(effectChain->effectTypes, effectChain->effectCount * sizeof(FAudioGMS_EffectType));
|
||||||
effectChain->fAudioEffectChain.pEffectDescriptors = SDL_realloc(effectChain->fAudioEffectChain.pEffectDescriptors, effectChain->fAudioEffectChain.EffectCount * sizeof(FAudioEffectDescriptor));
|
effectChain->effectTypes[effectChain->effectCount - 1] = EffectType_Reverb;
|
||||||
|
|
||||||
FAudioEffectDescriptor* reverbDescriptor = &effectChain->fAudioEffectChain.pEffectDescriptors[effectChain->fAudioEffectChain.EffectCount - 1];
|
effectChain->effectParameters = SDL_realloc(effectChain->effectParameters, effectChain->effectCount * sizeof(FAudioGMS_EffectParameters));
|
||||||
|
SDL_memcpy(&effectChain->effectParameters[effectChain->effectCount - 1], reverbParameters, sizeof(FAudioFXReverbParameters));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FAudioGMS_EffectChain_AddDefaultReverb(double effectChainID)
|
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)
|
void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effectChainID, double effectGain)
|
||||||
{
|
{
|
||||||
RETURN_ON_NULL_DEVICE()
|
RETURN_ON_NULL_DEVICE()
|
||||||
|
@ -1469,36 +1530,34 @@ void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effec
|
||||||
|
|
||||||
if (instance != NULL && effectChain != NULL)
|
if (instance != NULL && effectChain != NULL)
|
||||||
{
|
{
|
||||||
if (!instance->effectChainAttached)
|
if (instance->effectChainAttached)
|
||||||
{
|
{
|
||||||
FAudio_CreateSubmixVoice(
|
/* This frees the effect chain on the voice */
|
||||||
device->handle,
|
FAudioVoice_SetEffectChain(instance->handle, NULL);
|
||||||
&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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
uint32_t parametersSize;
|
||||||
void *parameters;
|
void *parameters;
|
||||||
|
@ -1526,24 +1585,15 @@ void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effec
|
||||||
instance->handle,
|
instance->handle,
|
||||||
&instance->effectSends);
|
&instance->effectSends);
|
||||||
|
|
||||||
/* TODO: move this to a different API call */
|
FAudioGMS_INTERNAL_SoundInstance_SetEffectGain(instance, effectGain);
|
||||||
float *outputMatrix = instance->dspSettings.pMatrixCoefficients;
|
|
||||||
|
|
||||||
outputMatrix[0] = effectGain;
|
/* all the effect parameters are copied to the voice so we free here */
|
||||||
if (instance->dspSettings.SrcChannelCount == 2)
|
for (i = 0; i < effectChain->effectCount; i += 1)
|
||||||
{
|
{
|
||||||
outputMatrix[1] = effectGain;
|
FAPOBase_Release((FAPOBase*)fAudioEffectChain->pEffectDescriptors[i].pEffect);
|
||||||
}
|
}
|
||||||
|
SDL_free(fAudioEffectChain->pEffectDescriptors);
|
||||||
FAudioVoice_SetOutputMatrix(
|
SDL_free(fAudioEffectChain);
|
||||||
instance->handle,
|
|
||||||
instance->effectVoice,
|
|
||||||
instance->dspSettings.SrcChannelCount,
|
|
||||||
1,
|
|
||||||
outputMatrix,
|
|
||||||
0);
|
|
||||||
|
|
||||||
instance->effectGain = effectGain;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1555,14 +1605,8 @@ static void FAudioGMS_INTERNAL_EffectChain_Destroy(FAudioGMS_EffectChain *effect
|
||||||
device->effectChains[effectChain->id] = NULL;
|
device->effectChains[effectChain->id] = NULL;
|
||||||
IdStack_Push(&device->effectChainIndexStack, effectChain->id);
|
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->effectParameters);
|
||||||
SDL_free(effectChain->effectTypes);
|
SDL_free(effectChain->effectTypes);
|
||||||
SDL_free(effectChain->fAudioEffectChain.pEffectDescriptors);
|
|
||||||
SDL_free(effectChain);
|
SDL_free(effectChain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,12 @@ FAUDIOGMSAPI void FAudioGMS_EffectChain_AddReverb(
|
||||||
);
|
);
|
||||||
FAUDIOGMSAPI void FAudioGMS_EffectChain_Destroy(double effectChainID);
|
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_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);
|
FAUDIOGMSAPI void FAudioGMS_SetListenerPosition(double x, double y, double z);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue