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 | ||||
| { | ||||
|     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