diff --git a/src/FAudioGMS.c b/src/FAudioGMS.c index d15ba5f..d8de43f 100644 --- a/src/FAudioGMS.c +++ b/src/FAudioGMS.c @@ -142,6 +142,24 @@ static inline uint32_t IdStack_Pop(IdStack *stack) 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 { SoundState_Playing, @@ -155,6 +173,7 @@ typedef struct FAudioGMS_Voice FAudioVoiceSends sends; uint8_t effectChainAttached; + FAudioGMS_EffectChain *effectChain; FAudioSubmixVoice *effectVoice; FAudioVoiceSends effectSends; float effectGain; @@ -215,6 +234,9 @@ struct FAudioGMS_SoundInstance FAudioGMS_SoundInstance *queuedSoundInstance; + uint8_t destroyTimerActive; + double destroyTimer; + union { FAudioGMS_StaticSound *staticSound; /* static sounds are loaded separately, so they do @@ -223,24 +245,6 @@ struct FAudioGMS_SoundInstance } 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 DOPPLER_SCALE = 1.0f; @@ -676,6 +680,8 @@ static FAudioGMS_SoundInstance *FAudioGMS_INTERNAL_SoundInstance_Init( instance->isStatic = isStatic; instance->loop = 0; instance->destroyOnFinish = 0; + instance->destroyTimer = 0; + instance->destroyTimerActive = 0; instance->isGlobalPaused = 0; 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); instance->voice.effectChainAttached = 0; + instance->voice.effectChain = NULL; instance->voice.effectVoice = NULL; 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->effectChain = effectChain; + FAudioEffectChain *fAudioEffectChain = FAudioGMS_INTERNAL_CreateFAudioEffectChain(effectChain); voice->effectSends.SendCount = 1; @@ -1969,7 +1978,7 @@ void FAudioGMS_EffectChain_Destroy(double effectChainID) void FAudioGMS_Update() { RETURN_ON_NULL_DEVICE() - uint32_t i; + uint32_t i, j; for (i = 0; i < device->soundInstanceCount; i += 1) { @@ -2017,9 +2026,35 @@ void FAudioGMS_Update() &state, FAUDIO_VOICE_NOSAMPLESPLAYED); - if (state.BuffersQueued == 0) + if (instance->destroyTimerActive) { - FAudioGMS_INTERNAL_SoundInstance_Destroy(instance); + instance->destroyTimer -= device->timestep; + + if (instance->destroyTimer <= 0) + { + 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); + } } } }