effect chain API
							parent
							
								
									abf4d289d9
								
							
						
					
					
						commit
						56c1a9c766
					
				
							
								
								
									
										464
									
								
								src/FAudioGMS.c
								
								
								
								
							
							
						
						
									
										464
									
								
								src/FAudioGMS.c
								
								
								
								
							|  | @ -142,7 +142,7 @@ static inline uint32_t IdStack_Pop(IdStack* stack) | |||
|     return stack->array[stack->count]; | ||||
| } | ||||
| 
 | ||||
| typedef struct BufferQueue  | ||||
| typedef struct BufferQueue | ||||
| { | ||||
|     uint32_t head; | ||||
|     uint32_t tail; | ||||
|  | @ -160,9 +160,9 @@ static inline void BufferQueue_Init(BufferQueue* queue, uint32_t size) | |||
|     queue->buffers = SDL_malloc(size * sizeof(uint8_t*)); | ||||
| } | ||||
| 
 | ||||
| static inline uint8_t* BufferQueue_Dequeue(BufferQueue *queue)  | ||||
| static inline uint8_t* BufferQueue_Dequeue(BufferQueue *queue) | ||||
| { | ||||
|     if (queue->tail == queue->head)  | ||||
|     if (queue->tail == queue->head) | ||||
|     { | ||||
|         return NULL; | ||||
|     } | ||||
|  | @ -175,9 +175,9 @@ static inline uint8_t* BufferQueue_Dequeue(BufferQueue *queue) | |||
|     return buffer; | ||||
| } | ||||
| 
 | ||||
| static inline void BufferQueue_Enqueue(BufferQueue *queue, uint8_t* buffer)  | ||||
| static inline void BufferQueue_Enqueue(BufferQueue *queue, uint8_t* buffer) | ||||
| { | ||||
|     if (((queue->head + 1) % queue->size) == queue->tail)  | ||||
|     if (((queue->head + 1) % queue->size) == queue->tail) | ||||
|     { | ||||
|         return; | ||||
|     } | ||||
|  | @ -225,14 +225,14 @@ typedef struct FAudioGMS_SoundInstance | |||
|     float pan; | ||||
|     float pitch; | ||||
|     float volume; | ||||
|     float reverb; | ||||
|     float lowPassFilter; | ||||
|     float highPassFilter; | ||||
|     float bandPassFilter; | ||||
| 
 | ||||
|     uint8_t reverbAttached; | ||||
|     FAudioSubmixVoice* reverbVoice; | ||||
|     FAudioVoiceSends reverbSends; | ||||
|     uint8_t effectChainAttached; | ||||
|     FAudioSubmixVoice* effectVoice; | ||||
|     FAudioVoiceSends effectSends; | ||||
|     float effectGain; | ||||
| 
 | ||||
|     uint8_t adjustingVolumeOverTime; | ||||
|     float targetVolume; | ||||
|  | @ -252,6 +252,24 @@ typedef struct FAudioGMS_SoundInstance | |||
|     } soundData; | ||||
| } FAudioGMS_SoundInstance; | ||||
| 
 | ||||
| typedef enum FAudioGMS_EffectType | ||||
| { | ||||
|     EffectType_Reverb | ||||
| } FAudioGMS_EffectType; | ||||
| 
 | ||||
| typedef union FAudioGMS_EffectParameters | ||||
| { | ||||
|     FAudioFXReverbParameters reverbParameters; | ||||
| } 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 */ | ||||
| } FAudioGMS_EffectChain; | ||||
| 
 | ||||
| static const float SPEED_OF_SOUND = 343.5f; | ||||
| static const float DOPPLER_SCALE = 1.0f; | ||||
| static const uint32_t MINIMUM_BUFFER_CHECK = 3; | ||||
|  | @ -278,6 +296,10 @@ typedef struct FAudioGMS_Device | |||
|     uint32_t soundInstanceCount; | ||||
|     IdStack soundInstanceIndexStack; | ||||
| 
 | ||||
|     FAudioGMS_EffectChain** effectChains; | ||||
|     uint32_t effectChainCount; | ||||
|     IdStack effectChainIndexStack; | ||||
| 
 | ||||
|     float streamStagingBuffer[STREAMING_BUFFER_SIZE]; | ||||
|     double timestep; | ||||
| } FAudioGMS_Device; | ||||
|  | @ -310,6 +332,19 @@ static inline FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_LookupSoundInstance(ui | |||
|     } | ||||
| } | ||||
| 
 | ||||
| static inline FAudioGMS_EffectChain* FAudioGMS_INTERNAL_LookupEffectChain(uint32_t id) | ||||
| { | ||||
|     if (id >= 0 && id < device->effectChainCount) | ||||
|     { | ||||
|         return device->effectChains[id]; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         Log("Invalid EffectChain ID!"); | ||||
|         return NULL; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_Init(double spatialDistanceScale, double timestep) | ||||
| { | ||||
|     device = SDL_malloc(sizeof(FAudioGMS_Device)); | ||||
|  | @ -413,6 +448,10 @@ void FAudioGMS_Init(double spatialDistanceScale, double timestep) | |||
|     device->soundInstanceCount = 0; | ||||
|     IdStack_Init(&device->soundInstanceIndexStack); | ||||
| 
 | ||||
|     device->effectChains = NULL; | ||||
|     device->effectChainCount = 0; | ||||
|     IdStack_Init(&device->effectChainIndexStack); | ||||
| 
 | ||||
|     device->timestep = timestep; | ||||
| 
 | ||||
|     Log("FAudio initialized successfully!"); | ||||
|  | @ -521,118 +560,6 @@ double FAudioGMS_StaticSound_LoadWAV(char *filePath) | |||
|     return (double)sound->id; | ||||
| } | ||||
| 
 | ||||
| static void FAudioGMS_INTERNAL_SoundInstance_AttachReverb(FAudioGMS_SoundInstance* instance) | ||||
| { | ||||
|     if (!instance->reverbAttached) | ||||
|     { | ||||
|         /* Init reverb */ | ||||
| 
 | ||||
|         FAPO* reverb; | ||||
|         FAudioCreateReverb(&reverb, 0); | ||||
| 
 | ||||
|         FAudioEffectChain* reverbChain = SDL_malloc(sizeof(FAudioEffectChain)); | ||||
| 
 | ||||
|         reverbChain->EffectCount = 1; | ||||
|         reverbChain->pEffectDescriptors = SDL_malloc(sizeof(FAudioEffectDescriptor)); | ||||
| 
 | ||||
|         FAudioEffectDescriptor* reverbDescriptor = reverbChain->pEffectDescriptors; | ||||
| 
 | ||||
|         reverbDescriptor->InitialState = 1; | ||||
|         reverbDescriptor->OutputChannels = device->deviceDetails.OutputFormat.Format.nChannels == 6 ? 6 : 1; | ||||
|         reverbDescriptor->pEffect = reverb; | ||||
| 
 | ||||
|         FAudio_CreateSubmixVoice( | ||||
|             device->handle, | ||||
|             &instance->reverbVoice, | ||||
|             1, /* omnidirectional reverb */ | ||||
|             device->deviceDetails.OutputFormat.Format.nSamplesPerSec, | ||||
|             0, | ||||
|             0, | ||||
|             NULL, | ||||
|             reverbChain); | ||||
| 
 | ||||
|         FAPOBase_Release((FAPOBase*)reverb); | ||||
|         SDL_free(reverbChain->pEffectDescriptors); | ||||
|         SDL_free(reverbChain); | ||||
| 
 | ||||
|         FAudioFXReverbParameters* reverbParams = SDL_malloc(sizeof(FAudioFXReverbParameters)); | ||||
| 
 | ||||
|         reverbParams->WetDryMix = 100.0f; | ||||
|         reverbParams->ReflectionsDelay = 7; | ||||
|         reverbParams->ReverbDelay = 11; | ||||
|         reverbParams->RearDelay = FAUDIOFX_REVERB_DEFAULT_REAR_DELAY; | ||||
|         reverbParams->PositionLeft = FAUDIOFX_REVERB_DEFAULT_POSITION; | ||||
|         reverbParams->PositionRight = FAUDIOFX_REVERB_DEFAULT_POSITION; | ||||
|         reverbParams->PositionMatrixLeft = FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX; | ||||
|         reverbParams->PositionMatrixRight = FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX; | ||||
|         reverbParams->EarlyDiffusion = 15; | ||||
|         reverbParams->LateDiffusion = 15; | ||||
|         reverbParams->LowEQGain = 8; | ||||
|         reverbParams->LowEQCutoff = 4; | ||||
|         reverbParams->HighEQGain = 8; | ||||
|         reverbParams->HighEQCutoff = 6; | ||||
|         reverbParams->RoomFilterFreq = 5000.0f; | ||||
|         reverbParams->RoomFilterMain = -10.0f; | ||||
|         reverbParams->RoomFilterHF = -1.0f; | ||||
|         reverbParams->ReflectionsGain = -26.0200005f; | ||||
|         reverbParams->ReverbGain = 10.0f; | ||||
|         reverbParams->DecayTime = 1.49000001f; | ||||
|         reverbParams->Density = 100.0f; | ||||
|         reverbParams->RoomSize = FAUDIOFX_REVERB_DEFAULT_ROOM_SIZE; | ||||
| 
 | ||||
|         FAudioVoice_SetEffectParameters( | ||||
|             instance->reverbVoice, | ||||
|             0, | ||||
|             reverbParams, | ||||
|             sizeof(FAudioFXReverbParameters), | ||||
|             0); | ||||
| 
 | ||||
|         SDL_free(reverbParams); | ||||
| 
 | ||||
|         /* Init reverb sends */ | ||||
| 
 | ||||
|         instance->reverbSends.SendCount = 2; | ||||
|         instance->reverbSends.pSends = SDL_malloc(2 * sizeof(FAudioSendDescriptor)); | ||||
| 
 | ||||
|         instance->reverbSends.pSends[0].Flags = 0; | ||||
|         instance->reverbSends.pSends[0].pOutputVoice = device->masteringVoice; | ||||
|         instance->reverbSends.pSends[1].Flags = 0; | ||||
|         instance->reverbSends.pSends[1].pOutputVoice = instance->reverbVoice; | ||||
| 
 | ||||
|         instance->reverbAttached = 1; | ||||
|     } | ||||
| 
 | ||||
|     FAudioVoice_SetOutputVoices( | ||||
|         instance->handle, | ||||
|         &instance->reverbSends); | ||||
| } | ||||
| 
 | ||||
| static void FAudioGMS_INTERNAL_SoundInstance_SetReverb(FAudioGMS_SoundInstance *instance, float reverb) | ||||
| { | ||||
|     if (!instance->reverbAttached) | ||||
|     { | ||||
|         FAudioGMS_INTERNAL_SoundInstance_AttachReverb(instance); | ||||
|     } | ||||
| 
 | ||||
|     float* outputMatrix = instance->dspSettings.pMatrixCoefficients; | ||||
| 
 | ||||
|     outputMatrix[0] = reverb; | ||||
|     if (instance->dspSettings.SrcChannelCount == 2) | ||||
|     { | ||||
|         outputMatrix[1] = reverb; | ||||
|     } | ||||
| 
 | ||||
|     FAudioVoice_SetOutputMatrix( | ||||
|         instance->handle,  | ||||
|         instance->reverbVoice,  | ||||
|         instance->dspSettings.SrcChannelCount,  | ||||
|         1,  | ||||
|         outputMatrix, | ||||
|         0); | ||||
| 
 | ||||
|     instance->reverb = reverb; | ||||
| } | ||||
| 
 | ||||
| static void FAudioGMS_INTERNAL_SoundInstance_SetLowPassFilter(FAudioGMS_SoundInstance* instance, float lowPassFilter) | ||||
| { | ||||
|     FAudioFilterParameters p; | ||||
|  | @ -747,16 +674,11 @@ static void FAudioGMS_INTERNAL_SoundInstance_SetVolume(FAudioGMS_SoundInstance* | |||
|     FAudioVoice_SetVolume(instance->handle, volume, 0); | ||||
| } | ||||
| 
 | ||||
| static void FAudioGMS_INTERNAL_SoundInstance_SetProperties(FAudioGMS_SoundInstance* instance, double pan, double pitch, double volume, double reverb) | ||||
| static void FAudioGMS_INTERNAL_SoundInstance_SetProperties(FAudioGMS_SoundInstance* instance, double pan, double pitch, double volume) | ||||
| { | ||||
|     FAudioGMS_INTERNAL_SoundInstance_SetPan(instance, pan); | ||||
|     FAudioGMS_INTERNAL_SoundInstance_SetPitch(instance, pitch); | ||||
|     FAudioGMS_INTERNAL_SoundInstance_SetVolume(instance, volume); | ||||
| 
 | ||||
|     if (reverb > 0.0f) | ||||
|     { | ||||
|         FAudioGMS_INTERNAL_SoundInstance_SetReverb(instance, reverb); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void FAudioGMS_INTERNAL_Apply3D(FAudioGMS_SoundInstance* instance) | ||||
|  | @ -831,8 +753,10 @@ static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_Init( | |||
|     instance->dspSettings.pMatrixCoefficients = SDL_malloc(memsize); | ||||
|     SDL_memset(instance->dspSettings.pMatrixCoefficients, 0, memsize); | ||||
| 
 | ||||
|     instance->reverbAttached = 0; | ||||
|     instance->reverb = 0.0f; | ||||
|     instance->effectChainAttached = 0; | ||||
|     instance->effectVoice = NULL; | ||||
|     instance->effectGain = 0; | ||||
| 
 | ||||
|     instance->lowPassFilter = 0.0f; | ||||
|     instance->highPassFilter = 0.0f; | ||||
|     instance->bandPassFilter = 0.0f; | ||||
|  | @ -917,7 +841,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_AddBuffer(FAudioGMS_SoundInstance* | |||
|     buffer.pContext = NULL; | ||||
| 
 | ||||
|     FAudioSourceVoice_SubmitSourceBuffer(instance->handle, &buffer, NULL); | ||||
|      | ||||
| 
 | ||||
|     /* We have reached the end of the file! */ | ||||
|     if (sampleCount < STREAMING_BUFFER_SIZE) | ||||
|     { | ||||
|  | @ -1072,7 +996,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_Play(FAudioGMS_SoundInstance* insta | |||
|     instance->soundState = SoundState_Playing; | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double pitch, double volume, double reverb) | ||||
| void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double pitch, double volume) | ||||
| { | ||||
|     FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID); | ||||
| 
 | ||||
|  | @ -1080,7 +1004,7 @@ void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double p | |||
|     { | ||||
|         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound); | ||||
|         instance->destroyOnFinish = 1; | ||||
|         FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, pan, pitch, volume, reverb); | ||||
|         FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, pan, pitch, volume); | ||||
|         FAudioGMS_INTERNAL_SoundInstance_Play(instance); | ||||
|     } | ||||
|     else | ||||
|  | @ -1089,7 +1013,7 @@ void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double p | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_StaticSound_PlayOneOffSpatial(double staticSoundID, double x, double y, double z, double pitch, double volume, double reverb) | ||||
| void FAudioGMS_StaticSound_PlayOneOffSpatial(double staticSoundID, double x, double y, double z, double pitch, double volume) | ||||
| { | ||||
|     FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID); | ||||
| 
 | ||||
|  | @ -1097,7 +1021,7 @@ void FAudioGMS_StaticSound_PlayOneOffSpatial(double staticSoundID, double x, dou | |||
|     { | ||||
|         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound); | ||||
|         instance->destroyOnFinish = 1; | ||||
|         FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, 0, pitch, volume, reverb); | ||||
|         FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, 0, pitch, volume); | ||||
|         FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z); | ||||
|         FAudioGMS_INTERNAL_SoundInstance_Play(instance); | ||||
|     } | ||||
|  | @ -1107,7 +1031,7 @@ void FAudioGMS_StaticSound_PlayOneOffSpatial(double staticSoundID, double x, dou | |||
|     } | ||||
| } | ||||
| 
 | ||||
| double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch, double volume, double reverb, double loop) | ||||
| double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch, double volume, double loop) | ||||
| { | ||||
|     FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID); | ||||
| 
 | ||||
|  | @ -1115,7 +1039,7 @@ double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch | |||
|     { | ||||
|         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound); | ||||
|         instance->loop = (uint8_t)loop; | ||||
|         FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, pan, pitch, volume, reverb); | ||||
|         FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, pan, pitch, volume); | ||||
|         FAudioGMS_INTERNAL_SoundInstance_Play(instance); | ||||
|         return (double)instance->id; | ||||
|     } | ||||
|  | @ -1126,7 +1050,7 @@ double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch | |||
|     } | ||||
| } | ||||
| 
 | ||||
| double FAudioGMS_StaticSound_PlaySpatial(double staticSoundID, double x, double y, double z, double pitch, double volume, double reverb, double loop) | ||||
| double FAudioGMS_StaticSound_PlaySpatial(double staticSoundID, double x, double y, double z, double pitch, double volume, double loop) | ||||
| { | ||||
|     FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID); | ||||
| 
 | ||||
|  | @ -1134,7 +1058,7 @@ double FAudioGMS_StaticSound_PlaySpatial(double staticSoundID, double x, double | |||
|     { | ||||
|         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound); | ||||
|         instance->loop = (uint8_t)loop; | ||||
|         FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, 0, pitch, volume, reverb); | ||||
|         FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, 0, pitch, volume); | ||||
|         FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z); | ||||
|         FAudioGMS_INTERNAL_SoundInstance_Play(instance); | ||||
|         return (double)instance->id; | ||||
|  | @ -1254,16 +1178,6 @@ void FAudioGMS_SoundInstance_SetVolume(double soundInstanceID, double volume) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_SoundInstance_SetReverb(double soundInstanceID, double reverb) | ||||
| { | ||||
|     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID); | ||||
| 
 | ||||
|     if (instance != NULL) | ||||
|     { | ||||
|         FAudioGMS_INTERNAL_SoundInstance_SetReverb(instance, reverb); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z) | ||||
| { | ||||
|     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID); | ||||
|  | @ -1451,6 +1365,255 @@ void FAudioGMS_StaticSound_Destroy(double staticSoundID) | |||
|     FAudioGMS_INTERNAL_StaticSound_Destroy(sound); | ||||
| } | ||||
| 
 | ||||
| double FAudioGMS_EffectChain_Create() | ||||
| { | ||||
|     FAudioGMS_EffectChain* effectChain = SDL_malloc(sizeof(FAudioGMS_EffectChain)); | ||||
| 
 | ||||
|     effectChain->fAudioEffectChain.EffectCount = 0; | ||||
|     effectChain->fAudioEffectChain.pEffectDescriptors = NULL; | ||||
|     effectChain->effectTypes = NULL; | ||||
|     effectChain->effectParameters = NULL; | ||||
| 
 | ||||
|     if (device->effectChainIndexStack.count > 0) | ||||
|     { | ||||
|         effectChain->id = IdStack_Pop(&device->effectChainIndexStack); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         effectChain->id = device->effectChainCount; | ||||
| 
 | ||||
|         device->effectChains = SDL_realloc(device->effectChains, (device->effectChainCount + 1) * sizeof(FAudioGMS_EffectChain*)); | ||||
|         device->effectChainCount += 1; | ||||
|     } | ||||
| 
 | ||||
|     device->effectChains[effectChain->id] = effectChain; | ||||
| 
 | ||||
|     return effectChain->id; | ||||
| } | ||||
| 
 | ||||
| static void FAudioGMS_INTERNAL_EffectChain_AddReverb(FAudioGMS_EffectChain* effectChain, FAudioFXReverbParameters *reverbParameters) | ||||
| { | ||||
|     FAPO* reverb; | ||||
|     FAudioCreateReverb(&reverb, 0); | ||||
| 
 | ||||
|     effectChain->fAudioEffectChain.EffectCount += 1; | ||||
|     effectChain->fAudioEffectChain.pEffectDescriptors = SDL_realloc(effectChain->fAudioEffectChain.pEffectDescriptors, effectChain->fAudioEffectChain.EffectCount * sizeof(FAudioEffectDescriptor)); | ||||
| 
 | ||||
|     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)); | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_EffectChain_AddDefaultReverb(double effectChainID) | ||||
| { | ||||
|     FAudioGMS_EffectChain *effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID); | ||||
| 
 | ||||
|     if (effectChain != NULL) | ||||
|     { | ||||
|         FAudioFXReverbParameters reverbParams; | ||||
| 
 | ||||
|         reverbParams.WetDryMix = 100.0f; | ||||
|         reverbParams.ReflectionsDelay = 7; | ||||
|         reverbParams.ReverbDelay = 11; | ||||
|         reverbParams.RearDelay = FAUDIOFX_REVERB_DEFAULT_REAR_DELAY; | ||||
|         reverbParams.PositionLeft = FAUDIOFX_REVERB_DEFAULT_POSITION; | ||||
|         reverbParams.PositionRight = FAUDIOFX_REVERB_DEFAULT_POSITION; | ||||
|         reverbParams.PositionMatrixLeft = FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX; | ||||
|         reverbParams.PositionMatrixRight = FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX; | ||||
|         reverbParams.EarlyDiffusion = 15; | ||||
|         reverbParams.LateDiffusion = 15; | ||||
|         reverbParams.LowEQGain = 8; | ||||
|         reverbParams.LowEQCutoff = 4; | ||||
|         reverbParams.HighEQGain = 8; | ||||
|         reverbParams.HighEQCutoff = 6; | ||||
|         reverbParams.RoomFilterFreq = 5000.0f; | ||||
|         reverbParams.RoomFilterMain = -10.0f; | ||||
|         reverbParams.RoomFilterHF = -1.0f; | ||||
|         reverbParams.ReflectionsGain = -26.0200005f; | ||||
|         reverbParams.ReverbGain = 10.0f; | ||||
|         reverbParams.DecayTime = 1.49000001f; | ||||
|         reverbParams.Density = 100.0f; | ||||
|         reverbParams.RoomSize = FAUDIOFX_REVERB_DEFAULT_ROOM_SIZE; | ||||
| 
 | ||||
|         FAudioGMS_INTERNAL_EffectChain_AddReverb(effectChain, &reverbParams); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /* no room filter params because game maker only supports 16 arguments lmao */ | ||||
| void FAudioGMS_EffectChain_AddReverb( | ||||
|     double effectChainID, | ||||
|     double wetDryMix, | ||||
|     double reflectionsDelay, | ||||
|     double reverbDelay, | ||||
|     double earlyDiffusion, | ||||
|     double lateDiffusion, | ||||
|     double lowEQGain, | ||||
|     double lowEQCutoff, | ||||
|     double highEQGain, | ||||
|     double highEQCutoff, | ||||
|     double reflectionsGain, | ||||
|     double reverbGain, | ||||
|     double decayTime, | ||||
|     double density, | ||||
|     double roomSize | ||||
| ) { | ||||
|     FAudioGMS_EffectChain* effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID); | ||||
| 
 | ||||
|     if (effectChain != NULL) | ||||
|     { | ||||
|         FAudioFXReverbParameters reverbParams; | ||||
| 
 | ||||
|         reverbParams.WetDryMix = wetDryMix; | ||||
|         reverbParams.ReflectionsDelay = reflectionsDelay; | ||||
|         reverbParams.ReverbDelay = reverbDelay; | ||||
|         reverbParams.RearDelay = FAUDIOFX_REVERB_DEFAULT_REAR_DELAY; | ||||
|         reverbParams.PositionLeft = FAUDIOFX_REVERB_DEFAULT_POSITION; | ||||
|         reverbParams.PositionRight = FAUDIOFX_REVERB_DEFAULT_POSITION; | ||||
|         reverbParams.PositionMatrixLeft = FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX; | ||||
|         reverbParams.PositionMatrixRight = FAUDIOFX_REVERB_DEFAULT_POSITION_MATRIX; | ||||
|         reverbParams.EarlyDiffusion = earlyDiffusion; | ||||
|         reverbParams.LateDiffusion = lateDiffusion; | ||||
|         reverbParams.LowEQGain = lowEQGain; | ||||
|         reverbParams.LowEQCutoff = lowEQCutoff; | ||||
|         reverbParams.HighEQGain = highEQGain; | ||||
|         reverbParams.HighEQCutoff = highEQCutoff; | ||||
|         reverbParams.RoomFilterFreq = 5000.0f; | ||||
|         reverbParams.RoomFilterMain = -10.0f; | ||||
|         reverbParams.RoomFilterHF = -1.0f; | ||||
|         reverbParams.ReflectionsGain = reflectionsGain; | ||||
|         reverbParams.ReverbGain = reverbGain; | ||||
|         reverbParams.DecayTime = decayTime; | ||||
|         reverbParams.Density = density; | ||||
|         reverbParams.RoomSize = roomSize; | ||||
| 
 | ||||
|         FAudioGMS_INTERNAL_EffectChain_AddReverb(effectChain, &reverbParams); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effectChainID, double effectGain) | ||||
| { | ||||
|     FAudioGMS_SoundInstance *instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID); | ||||
|     FAudioGMS_EffectChain *effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID); | ||||
|     uint32_t i; | ||||
| 
 | ||||
|     if (instance != NULL && effectChain != NULL) | ||||
|     { | ||||
|         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); | ||||
|         } | ||||
| 
 | ||||
|         for (i = 0; i < effectChain->fAudioEffectChain.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( | ||||
|                 instance->effectVoice, | ||||
|                 i, | ||||
|                 parameters, | ||||
|                 parametersSize, | ||||
|                 0); | ||||
|         } | ||||
| 
 | ||||
|         FAudioVoice_SetOutputVoices( | ||||
|             instance->handle, | ||||
|             &instance->effectSends); | ||||
| 
 | ||||
|         /* TODO: move this to a different API call */ | ||||
|         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; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void FAudioGMS_INTERNAL_EffectChain_Destroy(FAudioGMS_EffectChain *effectChain) | ||||
| { | ||||
|     uint32_t i; | ||||
|     if (effectChain != NULL) | ||||
|     { | ||||
|         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); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_EffectChain_Destroy(double effectChainID) | ||||
| { | ||||
|     FAudioGMS_EffectChain *effectChain = FAudioGMS_INTERNAL_LookupEffectChain((uint32_t)effectChainID); | ||||
| 
 | ||||
|     if (effectChain != NULL) | ||||
|     { | ||||
|         FAudioGMS_INTERNAL_EffectChain_Destroy(effectChain); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_Update() | ||||
| { | ||||
|     uint32_t i; | ||||
|  | @ -1532,6 +1695,11 @@ void FAudioGMS_Destroy() | |||
|         FAudioGMS_INTERNAL_SoundInstance_Destroy(device->soundInstances[i]); | ||||
|     } | ||||
| 
 | ||||
|     for (i = 0; i < device->effectChainCount; i += 1) | ||||
|     { | ||||
|         FAudioGMS_INTERNAL_EffectChain_Destroy(device->effectChains[i]); | ||||
|     } | ||||
| 
 | ||||
|     for (i = 0; i < device->staticSoundCount; i += 1) | ||||
|     { | ||||
|         FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[i]); | ||||
|  |  | |||
|  | @ -42,10 +42,10 @@ extern "C" { | |||
| FAUDIOGMSAPI void FAudioGMS_Init(double spatialDistanceScale, double timestep); | ||||
| 
 | ||||
| FAUDIOGMSAPI double FAudioGMS_StaticSound_LoadWAV(char *filePath); /* returns a static sound ID */ | ||||
| FAUDIOGMSAPI void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double pitch, double volume, double reverb); /* automatically frees itself when done! */ | ||||
| FAUDIOGMSAPI void FAudioGMS_StaticSound_PlayOneOffSpatial(double staticSoundID, double x, double y, double z, double pitch, double volume, double reverb); /* automatically frees itself when done! */ | ||||
| FAUDIOGMSAPI double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch, double volume, double reverb, double loop); /* returns a sound instance ID. must be freed! */ | ||||
| FAUDIOGMSAPI double FAudioGMS_StaticSound_PlaySpatial(double staticSoundID, double x, double y, double z, double pitch, double volume, double reverb, double loop); /* returns a sound instance ID. must be freed! */ | ||||
| FAUDIOGMSAPI void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double pitch, double volume); /* automatically frees itself when done! */ | ||||
| FAUDIOGMSAPI void FAudioGMS_StaticSound_PlayOneOffSpatial(double staticSoundID, double x, double y, double z, double pitch, double volume); /* automatically frees itself when done! */ | ||||
| FAUDIOGMSAPI double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch, double volume, double loop); /* returns a sound instance ID. must be freed! */ | ||||
| FAUDIOGMSAPI double FAudioGMS_StaticSound_PlaySpatial(double staticSoundID, double x, double y, double z, double pitch, double volume, double loop); /* returns a sound instance ID. must be freed! */ | ||||
| FAUDIOGMSAPI void FAudioGMS_StaticSound_Destroy(double staticSoundID); | ||||
| 
 | ||||
| FAUDIOGMSAPI double FAudioGMS_StreamingSound_LoadOGG(char* filepath); /* returns a sound instance */ | ||||
|  | @ -58,7 +58,6 @@ FAUDIOGMSAPI void FAudioGMS_SoundInstance_StopImmediate(double soundInstanceID); | |||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetPan(double soundInstanceID, double pan); | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetPitch(double soundInstanceID, double pitch); | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetVolume(double soundInstanceID, double volume); | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetReverb(double soundInstanceID, double reverb); | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z); | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetTrackPosition(double soundInstanceID, double trackPositionInSeconds); | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetVolumeOverTime(double soundInstanceID, double volume, double milliseconds); | ||||
|  | @ -73,6 +72,29 @@ FAUDIOGMSAPI double FAudioGMS_SoundInstance_GetTrackLengthInSeconds(double sound | |||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_Destroy(double soundInstanceID); | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_DestroyWhenFinished(double soundInstanceID); | ||||
| 
 | ||||
| FAUDIOGMSAPI double FAudioGMS_EffectChain_Create(); | ||||
| FAUDIOGMSAPI void FAudioGMS_EffectChain_AddDefaultReverb(double effectChainID); | ||||
| FAUDIOGMSAPI void FAudioGMS_EffectChain_AddReverb( | ||||
|     double effectChainID, | ||||
|     double wetDryMix, | ||||
|     double reflectionsDelay, | ||||
|     double reverbDelay, | ||||
|     double earlyDiffusion, | ||||
|     double lateDiffusion, | ||||
|     double lowEQGain, | ||||
|     double lowEQCutoff, | ||||
|     double highEQGain, | ||||
|     double highEQCutoff, | ||||
|     double reflectionsGain, | ||||
|     double reverbGain, | ||||
|     double decayTime, | ||||
|     double density, | ||||
|     double roomSize | ||||
| ); | ||||
| FAUDIOGMSAPI void FAudioGMS_EffectChain_Destroy(double effectChainID); | ||||
| 
 | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_SetEffectChain(double soundInstanceID, double effectChainID, double effectGain); | ||||
| 
 | ||||
| FAUDIOGMSAPI void FAudioGMS_SetListenerPosition(double x, double y, double z); | ||||
| 
 | ||||
| FAUDIOGMSAPI void FAudioGMS_StopAll(); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue