fix sounds that use reverb being destroyed too early

main
cosmonaut 2021-11-09 15:09:47 -08:00
parent 4d834b3567
commit 22d759ea11
1 changed files with 56 additions and 21 deletions

View File

@ -142,6 +142,24 @@ static inline uint32_t IdStack_Pop(IdStack *stack)
return stack->array[stack->count]; return stack->array[stack->count];
} }
typedef enum FAudioGMS_EffectType
{
EffectType_Reverb
} FAudioGMS_EffectType;
typedef union FAudioGMS_EffectParameters
{
FAudioFXReverbParameters reverbParameters;
} FAudioGMS_EffectParameters;
typedef struct FAudioGMS_EffectChain
{
uint32_t id;
uint32_t effectCount;
FAudioGMS_EffectType *effectTypes; /* length equal to effectCount */
union FAudioGMS_EffectParameters *effectParameters; /* length equal to effectCount */
} FAudioGMS_EffectChain;
typedef enum FAudioGMS_SoundState typedef enum FAudioGMS_SoundState
{ {
SoundState_Playing, SoundState_Playing,
@ -155,6 +173,7 @@ typedef struct FAudioGMS_Voice
FAudioVoiceSends sends; FAudioVoiceSends sends;
uint8_t effectChainAttached; uint8_t effectChainAttached;
FAudioGMS_EffectChain *effectChain;
FAudioSubmixVoice *effectVoice; FAudioSubmixVoice *effectVoice;
FAudioVoiceSends effectSends; FAudioVoiceSends effectSends;
float effectGain; float effectGain;
@ -215,6 +234,9 @@ struct FAudioGMS_SoundInstance
FAudioGMS_SoundInstance *queuedSoundInstance; FAudioGMS_SoundInstance *queuedSoundInstance;
uint8_t destroyTimerActive;
double destroyTimer;
union union
{ {
FAudioGMS_StaticSound *staticSound; /* static sounds are loaded separately, so they do FAudioGMS_StaticSound *staticSound; /* static sounds are loaded separately, so they do
@ -223,24 +245,6 @@ struct FAudioGMS_SoundInstance
} soundData; } soundData;
}; };
typedef enum FAudioGMS_EffectType
{
EffectType_Reverb
} FAudioGMS_EffectType;
typedef union FAudioGMS_EffectParameters
{
FAudioFXReverbParameters reverbParameters;
} FAudioGMS_EffectParameters;
typedef struct FAudioGMS_EffectChain
{
uint32_t id;
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; static const float SPEED_OF_SOUND = 343.5f;
static const float DOPPLER_SCALE = 1.0f; static const float DOPPLER_SCALE = 1.0f;
@ -676,6 +680,8 @@ static FAudioGMS_SoundInstance *FAudioGMS_INTERNAL_SoundInstance_Init(
instance->isStatic = isStatic; instance->isStatic = isStatic;
instance->loop = 0; instance->loop = 0;
instance->destroyOnFinish = 0; instance->destroyOnFinish = 0;
instance->destroyTimer = 0;
instance->destroyTimerActive = 0;
instance->isGlobalPaused = 0; instance->isGlobalPaused = 0;
instance->format.wFormatTag = FAUDIO_FORMAT_IEEE_FLOAT; instance->format.wFormatTag = FAUDIO_FORMAT_IEEE_FLOAT;
@ -717,6 +723,7 @@ static FAudioGMS_SoundInstance *FAudioGMS_INTERNAL_SoundInstance_Init(
SDL_memset(instance->dspSettings.pMatrixCoefficients, 0, memsize); SDL_memset(instance->dspSettings.pMatrixCoefficients, 0, memsize);
instance->voice.effectChainAttached = 0; instance->voice.effectChainAttached = 0;
instance->voice.effectChain = NULL;
instance->voice.effectVoice = NULL; instance->voice.effectVoice = NULL;
instance->voice.effectGain = 0; instance->voice.effectGain = 0;
@ -1828,6 +1835,8 @@ static void FAudioGMS_INTERNAL_SetEffectChain(
voice->sends.pSends = SDL_realloc(voice->sends.pSends, 2 * sizeof(FAudioSendDescriptor)); voice->sends.pSends = SDL_realloc(voice->sends.pSends, 2 * sizeof(FAudioSendDescriptor));
} }
voice->effectChain = effectChain;
FAudioEffectChain *fAudioEffectChain = FAudioGMS_INTERNAL_CreateFAudioEffectChain(effectChain); FAudioEffectChain *fAudioEffectChain = FAudioGMS_INTERNAL_CreateFAudioEffectChain(effectChain);
voice->effectSends.SendCount = 1; voice->effectSends.SendCount = 1;
@ -1969,7 +1978,7 @@ void FAudioGMS_EffectChain_Destroy(double effectChainID)
void FAudioGMS_Update() void FAudioGMS_Update()
{ {
RETURN_ON_NULL_DEVICE() RETURN_ON_NULL_DEVICE()
uint32_t i; uint32_t i, j;
for (i = 0; i < device->soundInstanceCount; i += 1) for (i = 0; i < device->soundInstanceCount; i += 1)
{ {
@ -2017,11 +2026,37 @@ void FAudioGMS_Update()
&state, &state,
FAUDIO_VOICE_NOSAMPLESPLAYED); FAUDIO_VOICE_NOSAMPLESPLAYED);
if (state.BuffersQueued == 0) if (instance->destroyTimerActive)
{
instance->destroyTimer -= device->timestep;
if (instance->destroyTimer <= 0)
{ {
FAudioGMS_INTERNAL_SoundInstance_Destroy(instance); FAudioGMS_INTERNAL_SoundInstance_Destroy(instance);
} }
} }
else if (state.BuffersQueued == 0)
{
if (instance->voice.effectChainAttached)
{
/* If we have active reverb we don't want to clean up until the decay time is over */
for (j = 0; j < instance->voice.effectChain->effectCount; j += 1)
{
if (instance->voice.effectChain->effectTypes[j] == EffectType_Reverb)
{
instance->destroyTimerActive = 1;
instance->destroyTimer +=
instance->voice.effectChain->effectParameters[j]
.reverbParameters.DecayTime;
}
}
}
else
{
FAudioGMS_INTERNAL_SoundInstance_Destroy(instance);
}
}
}
} }
} }
} }