From 6d8c80064c7fceedb50526c16ae6852fdee8e930 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Tue, 16 Nov 2021 23:06:44 -0800 Subject: [PATCH] refactor effect chains to use a single voice --- gamemaker/extensions/FAudioGMS/FAudioGMS.dll | 4 +- src/FAudioGMS.c | 197 +++++++------------ 2 files changed, 72 insertions(+), 129 deletions(-) diff --git a/gamemaker/extensions/FAudioGMS/FAudioGMS.dll b/gamemaker/extensions/FAudioGMS/FAudioGMS.dll index e06b4c8..cd03eaa 100644 --- a/gamemaker/extensions/FAudioGMS/FAudioGMS.dll +++ b/gamemaker/extensions/FAudioGMS/FAudioGMS.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5d8c64fb1c3707d64d28ca4ef6f8c801d86f6e5ae8fa8725d32c9b55d5c94c01 -size 1475584 +oid sha256:c3b23194e8e277a93bfb4e56548d2d868b1249f2feb499e16a029ad939a63dd0 +size 1475072 diff --git a/src/FAudioGMS.c b/src/FAudioGMS.c index 85344d9..adc6ab7 100644 --- a/src/FAudioGMS.c +++ b/src/FAudioGMS.c @@ -155,7 +155,9 @@ typedef union FAudioGMS_EffectParameters typedef struct FAudioGMS_EffectChain { uint32_t id; - uint32_t effectCount; + FAudioEffectChain fAudioEffectChain; + FAudioSubmixVoice *effectVoice; + FAudioVoiceSends effectSends; FAudioGMS_EffectType *effectTypes; /* length equal to effectCount */ union FAudioGMS_EffectParameters *effectParameters; /* length equal to effectCount */ } FAudioGMS_EffectChain; @@ -174,8 +176,6 @@ typedef struct FAudioGMS_Voice uint8_t effectChainAttached; FAudioGMS_EffectChain *effectChain; - FAudioSubmixVoice *effectVoice; - FAudioVoiceSends effectSends; float effectGain; } FAudioGMS_Voice; @@ -375,13 +375,13 @@ static void FAudioGMS_INTERNAL_OnBufferEndCallback( { /* this is a callback so we don't want to immediately destroy and screw up data */ instance->destroyTimerActive = 1; - instance->destroyTimer = 0; + instance->destroyTimer = 0; if (instance->voice.effectChainAttached) { /* If we have active reverb we don't want to clean up until the decay time is over */ - for (i = 0; i < instance->voice.effectChain->effectCount; i += 1) + for (i = 0; i < instance->voice.effectChain->fAudioEffectChain.EffectCount; i += 1) { if (instance->voice.effectChain->effectTypes[i] == EffectType_Reverb) { @@ -485,9 +485,6 @@ void FAudioGMS_Init(double spatialDistanceScale, double timestep) device->fauxMasteringVoice.effectChainAttached = 0; device->fauxMasteringVoice.effectGain = 0; - device->fauxMasteringVoice.effectVoice = NULL; - device->fauxMasteringVoice.effectSends.SendCount = 0; - device->fauxMasteringVoice.effectSends.pSends = NULL; device->spatialDistanceScale = spatialDistanceScale; @@ -645,7 +642,7 @@ static void SetPanMatrixCoefficients(FAudioGMS_SoundInstance *instance) } } -static void FAudioGMS_INTERNAL_SoundInstance_ApplyPan(FAudioGMS_SoundInstance* instance) +static void FAudioGMS_INTERNAL_SoundInstance_ApplyPan(FAudioGMS_SoundInstance* instance) { SetPanMatrixCoefficients(instance); @@ -760,7 +757,6 @@ static FAudioGMS_SoundInstance *FAudioGMS_INTERNAL_SoundInstance_Init( instance->voice.effectChainAttached = 0; instance->voice.effectChain = NULL; - instance->voice.effectVoice = NULL; instance->voice.effectGain = 0; instance->lowPassFilter = 0.0f; @@ -1580,12 +1576,6 @@ static void FAudioGMS_INTERNAL_SoundInstance_Destroy(FAudioGMS_SoundInstance *in IdStack_Push(&device->soundInstanceIndexStack, instance->id); FAudioGMS_INTERNAL_SoundInstance_Stop(instance); - if (instance->voice.effectChainAttached) - { - FAudioVoice_DestroyVoice(instance->voice.effectVoice); - SDL_free(instance->voice.effectSends.pSends); - } - SDL_free(instance->voice.sends.pSends); FAudioVoice_DestroyVoice(instance->voice.handle); @@ -1651,7 +1641,6 @@ double FAudioGMS_EffectChain_Create() RETURN_ON_NULL_DEVICE(-1.0) FAudioGMS_EffectChain *effectChain = SDL_malloc(sizeof(FAudioGMS_EffectChain)); - effectChain->effectCount = 0; effectChain->effectTypes = NULL; effectChain->effectParameters = NULL; @@ -1671,6 +1660,25 @@ double FAudioGMS_EffectChain_Create() device->effectChains[effectChain->id] = effectChain; + effectChain->fAudioEffectChain.EffectCount = 0; + effectChain->fAudioEffectChain.pEffectDescriptors = NULL; + + effectChain->effectSends.SendCount = 1; + effectChain->effectSends.pSends = SDL_malloc(sizeof(FAudioSendDescriptor)); + + effectChain->effectSends.pSends[0].Flags = 0; + effectChain->effectSends.pSends[0].pOutputVoice = device->masteringVoice; + + FAudio_CreateSubmixVoice( + device->handle, + &effectChain->effectVoice, + 1, /* FIXME: is this correct? */ + device->deviceDetails.OutputFormat.Format.nSamplesPerSec, + 0, + 0, + &effectChain->effectSends, + &effectChain->fAudioEffectChain); + return effectChain->id; } @@ -1678,20 +1686,53 @@ static void FAudioGMS_INTERNAL_EffectChain_AddReverb( FAudioGMS_EffectChain *effectChain, FAudioFXReverbParameters *reverbParameters) { - effectChain->effectCount += 1; + uint32_t effectIndex; + + effectChain->fAudioEffectChain.EffectCount += 1; + + effectChain->fAudioEffectChain.pEffectDescriptors = SDL_realloc( + effectChain->fAudioEffectChain.pEffectDescriptors, + effectChain->fAudioEffectChain.EffectCount * sizeof(FAudioEffectDescriptor)); + + effectIndex = effectChain->fAudioEffectChain.EffectCount - 1; effectChain->effectTypes = SDL_realloc( effectChain->effectTypes, - effectChain->effectCount * sizeof(FAudioGMS_EffectType)); - effectChain->effectTypes[effectChain->effectCount - 1] = EffectType_Reverb; + effectChain->fAudioEffectChain.EffectCount * sizeof(FAudioGMS_EffectType)); + + effectChain->effectTypes[effectIndex] = EffectType_Reverb; effectChain->effectParameters = SDL_realloc( effectChain->effectParameters, - effectChain->effectCount * sizeof(FAudioGMS_EffectParameters)); + effectChain->fAudioEffectChain.EffectCount * sizeof(FAudioGMS_EffectParameters)); + SDL_memcpy( - &effectChain->effectParameters[effectChain->effectCount - 1], + &effectChain->effectParameters[effectIndex], reverbParameters, sizeof(FAudioFXReverbParameters)); + + FAPO *reverb; + + FAudioCreateReverb(&reverb, 0); + + FAudioEffectDescriptor *reverbDescriptor = + &effectChain->fAudioEffectChain.pEffectDescriptors[effectIndex]; + reverbDescriptor->InitialState = 1; + reverbDescriptor->OutputChannels = + device->deviceDetails.OutputFormat.Format.nChannels == 6 ? 6 : 1; + reverbDescriptor->pEffect = reverb; + + FAudioVoice_SetEffectChain(effectChain->effectVoice, &effectChain->fAudioEffectChain); + + FAudioVoice_SetEffectParameters( + effectChain->effectVoice, + effectIndex, + &effectChain->effectParameters[effectIndex].reverbParameters, + sizeof(FAudioFXReverbParameters), + 0); + + /* All the effect parameters are copied to the voice so we free here */ + FAPOBase_Release((FAPOBase*)reverb); } void FAudioGMS_EffectChain_AddDefaultReverb(double effectChainID) @@ -1788,7 +1829,7 @@ static void FAudioGMS_INTERNAL_Voice_SetEffectGain(FAudioGMS_Voice *voice, float { if (voice->effectChainAttached) { - float *outputMatrix = SDL_stack_alloc(float, voice->effectSends.SendCount); + float *outputMatrix = SDL_stack_alloc(float, voice->handle->outputChannels); outputMatrix[0] = effectGain; if (voice->handle->outputChannels == 2) @@ -1798,7 +1839,7 @@ static void FAudioGMS_INTERNAL_Voice_SetEffectGain(FAudioGMS_Voice *voice, float FAudioVoice_SetOutputMatrix( voice->handle, - voice->effectVoice, + voice->effectChain->effectVoice, voice->handle->outputChannels, 1, outputMatrix, @@ -1822,108 +1863,17 @@ void FAudioGMS_SoundInstance_SetEffectGain(double soundInstanceID, double effect } } -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 NULL; - } - } - - return fAudioEffectChain; -} - static void FAudioGMS_INTERNAL_SetEffectChain( FAudioGMS_Voice *voice, FAudioGMS_EffectChain *effectChain, float effectGain) { - uint32_t i; - - if (voice->effectChainAttached) - { - /* This frees the effect chain on the voice */ - FAudioVoice_SetEffectChain(voice->effectVoice, NULL); - SDL_free(voice->effectSends.pSends); - } - else + if (!voice->effectChainAttached) { voice->sends.SendCount = 2; voice->sends.pSends = SDL_realloc(voice->sends.pSends, 2 * sizeof(FAudioSendDescriptor)); } - voice->effectChain = effectChain; - - FAudioEffectChain *fAudioEffectChain = FAudioGMS_INTERNAL_CreateFAudioEffectChain(effectChain); - - voice->effectSends.SendCount = 1; - voice->effectSends.pSends = SDL_malloc(sizeof(FAudioSendDescriptor)); - - voice->effectSends.pSends[0].Flags = 0; - - if (voice == &device->fauxMasteringVoice) - { - voice->effectSends.pSends[0].pOutputVoice = device->masteringVoice; - } - else - { - voice->effectSends.pSends[0].pOutputVoice = device->fauxMasteringVoice.handle; - } - - FAudio_CreateSubmixVoice( - device->handle, - &voice->effectVoice, - 1, /* FIXME: is this correct? */ - device->deviceDetails.OutputFormat.Format.nSamplesPerSec, - 0, - 0, - &voice->effectSends, - fAudioEffectChain); - - /* Copy the effect params */ - for (i = 0; i < effectChain->effectCount; i += 1) - { - uint32_t parametersSize; - void *parameters; - - switch (effectChain->effectTypes[i]) - { - case EffectType_Reverb: - parametersSize = sizeof(FAudioFXReverbParameters); - parameters = &effectChain->effectParameters[i].reverbParameters; - break; - - default: - Log("Unknown effect type! Something is very wrong!"); - } - - FAudioVoice_SetEffectParameters(voice->effectVoice, i, parameters, parametersSize, 0); - } - /* Set the instance voice to go through both faux mastering and effect voice * for wet/dry */ voice->sends.pSends[0].Flags = 0; @@ -1936,21 +1886,13 @@ static void FAudioGMS_INTERNAL_SetEffectChain( voice->sends.pSends[0].pOutputVoice = device->fauxMasteringVoice.handle; } voice->sends.pSends[1].Flags = 0; - voice->sends.pSends[1].pOutputVoice = voice->effectVoice; + voice->sends.pSends[1].pOutputVoice = effectChain->effectVoice; + voice->effectChain = effectChain; voice->effectChainAttached = 1; FAudioVoice_SetOutputVoices(voice->handle, &voice->sends); - FAudioGMS_INTERNAL_Voice_SetEffectGain(voice, effectGain); - - /* All the effect parameters are copied to the voice so we free here */ - for (i = 0; i < effectChain->effectCount; i += 1) - { - FAPOBase_Release((FAPOBase *)fAudioEffectChain->pEffectDescriptors[i].pEffect); - } - SDL_free(fAudioEffectChain->pEffectDescriptors); - SDL_free(fAudioEffectChain); } void FAudioGMS_SoundInstance_SetEffectChain( @@ -2000,6 +1942,7 @@ static void FAudioGMS_INTERNAL_EffectChain_Destroy(FAudioGMS_EffectChain *effect device->effectChains[effectChain->id] = NULL; IdStack_Push(&device->effectChainIndexStack, effectChain->id); + SDL_free(effectChain->fAudioEffectChain.pEffectDescriptors); SDL_free(effectChain->effectParameters); SDL_free(effectChain->effectTypes); SDL_free(effectChain); @@ -2021,7 +1964,7 @@ void FAudioGMS_EffectChain_Destroy(double effectChainID) void FAudioGMS_Update() { RETURN_ON_NULL_DEVICE() - uint32_t i, j; + uint32_t i; for (i = 0; i < device->soundInstanceCount; i += 1) {