initial spatial audio implementation
							parent
							
								
									fc8949d79d
								
							
						
					
					
						commit
						2581a19171
					
				
							
								
								
									
										323
									
								
								src/FAudioGMS.c
								
								
								
								
							
							
						
						
									
										323
									
								
								src/FAudioGMS.c
								
								
								
								
							|  | @ -121,6 +121,10 @@ typedef struct FAudioGMS_SoundInstance | |||
|     uint8_t isStatic; | ||||
|     uint8_t destroyOnFinish; | ||||
| 
 | ||||
|     uint8_t is3D; | ||||
|     F3DAUDIO_EMITTER* emitter; /* must not be NULL if is3D */ | ||||
|     float stereoAzimuth[2]; | ||||
| 
 | ||||
|     union | ||||
|     { | ||||
|         FAudioGMS_StaticSound *staticSound; | ||||
|  | @ -128,12 +132,20 @@ typedef struct FAudioGMS_SoundInstance | |||
|     } parent; | ||||
| } FAudioGMS_SoundInstance; | ||||
| 
 | ||||
| static const float DOPPLER_SCALE = 1.0f; | ||||
| static const float CURVE_DISTANCE_SCALER = 1.0f; | ||||
| 
 | ||||
| typedef struct FAudioGMS_Device | ||||
| { | ||||
|     FAudio* handle; | ||||
|     F3DAUDIO_HANDLE handle3D; | ||||
| 
 | ||||
|     FAudioDeviceDetails deviceDetails; | ||||
|     FAudioMasteringVoice *masteringVoice; | ||||
| 
 | ||||
|     F3DAUDIO_LISTENER listener; | ||||
|     float speedOfSound; | ||||
| 
 | ||||
|     FAudioGMS_StaticSound **staticSounds; | ||||
|     uint32_t staticSoundCount; | ||||
|     IdStack staticSoundIndexStack; | ||||
|  | @ -143,9 +155,35 @@ typedef struct FAudioGMS_Device | |||
|     IdStack soundInstanceIndexStack; | ||||
| } FAudioGMS_Device; | ||||
| 
 | ||||
| static FAudioGMS_Device *device = NULL; | ||||
| static FAudioGMS_Device* device = NULL; | ||||
| 
 | ||||
| void FAudioGMS_Init() | ||||
| static inline FAudioGMS_StaticSound* FAudioGMS_INTERNAL_LookupStaticSound(uint32_t id) | ||||
| { | ||||
|     if (id >= 0 && id < device->staticSoundCount) | ||||
|     { | ||||
|         return device->staticSounds[id]; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         Log("Invalid StaticSound ID!"); | ||||
|         return NULL; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static inline FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_LookupSoundInstance(uint32_t id) | ||||
| { | ||||
|     if (id >= 0 && id < device->soundInstanceCount) | ||||
|     { | ||||
|         return device->soundInstances[id]; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         Log("Invalid SoundInstance ID!"); | ||||
|         return NULL; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_Init(double speedOfSound) | ||||
| { | ||||
|     device = SDL_malloc(sizeof(FAudioGMS_Device)); | ||||
| 
 | ||||
|  | @ -218,6 +256,28 @@ void FAudioGMS_Init() | |||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     device->speedOfSound = speedOfSound; | ||||
| 
 | ||||
|     F3DAudioInitialize( | ||||
|         device->deviceDetails.OutputFormat.dwChannelMask, | ||||
|         device->speedOfSound, | ||||
|         device->handle3D | ||||
|     ); | ||||
| 
 | ||||
|     device->listener.OrientFront.x = 0; | ||||
|     device->listener.OrientFront.y = 0; | ||||
|     device->listener.OrientFront.z = -1; | ||||
|     device->listener.OrientTop.x = 0; | ||||
|     device->listener.OrientTop.y = 1; | ||||
|     device->listener.OrientTop.z = 0; | ||||
|     device->listener.Position.x = 0; | ||||
|     device->listener.Position.y = 0; | ||||
|     device->listener.Position.z = 0; | ||||
|     device->listener.Velocity.x = 0; | ||||
|     device->listener.Velocity.y = 0; | ||||
|     device->listener.Velocity.z = 0; | ||||
|     device->listener.pCone = NULL; | ||||
| 
 | ||||
|     device->staticSounds = NULL; | ||||
|     device->staticSoundCount = 0; | ||||
|     IdStack_Init(&device->staticSoundIndexStack); | ||||
|  | @ -240,6 +300,10 @@ static void FAudioGMS_INTERNAL_SoundInstance_Destroy(FAudioGMS_SoundInstance* in | |||
|         FAudioSourceVoice_Stop(instance->handle, 0, 0); | ||||
|         FAudioSourceVoice_FlushSourceBuffers(instance->handle); | ||||
|         FAudioVoice_DestroyVoice(instance->handle); | ||||
|         if (instance->is3D) | ||||
|         { | ||||
|             SDL_free(instance->emitter); | ||||
|         } | ||||
|         SDL_free(instance->dspSettings.pMatrixCoefficients); | ||||
|         SDL_free(instance); | ||||
|     } | ||||
|  | @ -247,12 +311,17 @@ static void FAudioGMS_INTERNAL_SoundInstance_Destroy(FAudioGMS_SoundInstance* in | |||
| 
 | ||||
| void FAudioGMS_SoundInstance_Destroy(double id) | ||||
| { | ||||
|     FAudioGMS_INTERNAL_SoundInstance_Destroy(device->soundInstances[(uint32_t)id]); | ||||
|     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); | ||||
| 
 | ||||
|     if (instance != NULL) | ||||
|     { | ||||
|         FAudioGMS_INTERNAL_SoundInstance_Destroy(instance); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_SoundInstance_DestroyWhenFinished(double id) | ||||
| { | ||||
|     FAudioGMS_SoundInstance *instance = device->soundInstances[(uint32_t)id]; | ||||
|     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); | ||||
| 
 | ||||
|     if (instance != NULL) | ||||
|     { | ||||
|  | @ -274,30 +343,13 @@ static void FAudioGMS_INTERNAL_StaticSound_Destroy(FAudioGMS_StaticSound* sound) | |||
| 
 | ||||
| void FAudioGMS_StaticSound_Destroy(double id) | ||||
| { | ||||
|     FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[(uint32_t)id]); | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_Update() | ||||
| { | ||||
|     uint32_t i; | ||||
| 
 | ||||
|     for (i = 0; i < device->soundInstanceCount; i += 1) | ||||
|     if (id >= 0 && id < device->staticSoundCount) | ||||
|     { | ||||
|         FAudioGMS_SoundInstance* instance = device->soundInstances[i]; | ||||
| 
 | ||||
|         if (instance != NULL) | ||||
|         { | ||||
|             if (instance->destroyOnFinish) | ||||
|             { | ||||
|                 FAudioVoiceState state; | ||||
|                 FAudioSourceVoice_GetState(instance->handle, &state, FAUDIO_VOICE_NOSAMPLESPLAYED); | ||||
| 
 | ||||
|                 if (state.BuffersQueued == 0) | ||||
|                 { | ||||
|                     FAudioGMS_INTERNAL_SoundInstance_Destroy(instance); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[(uint32_t)id]); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         Log("Invalid ID for destroy!"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -375,7 +427,7 @@ double FAudioGMS_StaticSound_LoadWAV(char *filePath) | |||
|     sound->buffer.LoopBegin = 0; | ||||
|     sound->buffer.LoopCount = 0; | ||||
|     sound->buffer.LoopLength = 0; | ||||
|     sound->buffer.pAudioData = pSampleData; | ||||
|     sound->buffer.pAudioData = (uint8_t*) pSampleData; | ||||
|     sound->buffer.pContext = NULL; | ||||
|     sound->buffer.PlayBegin = 0; | ||||
|     sound->buffer.PlayLength = 0; | ||||
|  | @ -563,25 +615,67 @@ static void FAudioGMS_INTERNAL_SoundInstance_SetPan(FAudioGMS_SoundInstance* ins | |||
|     ); | ||||
| } | ||||
| 
 | ||||
| static void FAudioGMS_INTERNAL_SoundInstance_SetPitch(FAudioGMS_SoundInstance* instance, float pitch) | ||||
| static void FAudioGMS_INTERNAL_SoundInstance_UpdatePitch(FAudioGMS_SoundInstance* instance) | ||||
| { | ||||
|     instance->pitch = pitch; | ||||
|     float doppler = 1.0f; | ||||
| 
 | ||||
|     pitch -= 1.0; /* default pitch is 1.0 as per GM standard */ | ||||
|     pitch = SDL_max(-1.0, SDL_min(1.0, pitch)); | ||||
|     if (!instance->is3D || DOPPLER_SCALE == 0.0f) | ||||
|     { | ||||
|         doppler = 1.0f; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         doppler = instance->dspSettings.DopplerFactor * DOPPLER_SCALE; | ||||
|     } | ||||
| 
 | ||||
|     FAudioSourceVoice_SetFrequencyRatio( | ||||
|         instance->handle, | ||||
|         SDL_powf(2.0f, pitch), | ||||
|         SDL_powf(2.0f, instance->pitch - 1) * doppler, /* FAudio expects pitch range to be -1.0 to 1.0 while GM uses 0.0 to 2.0 so we adjust here */ | ||||
|         0 | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| static void FAudioGMS_INTERNAL_SoundInstance_SetPitch(FAudioGMS_SoundInstance* instance, float pitch) | ||||
| { | ||||
|     pitch = SDL_max(0.0, SDL_min(2.0, pitch)); | ||||
|     instance->pitch = pitch; | ||||
|     FAudioGMS_INTERNAL_SoundInstance_UpdatePitch(instance); | ||||
| } | ||||
| 
 | ||||
| static void FAudioGMS_INTERNAL_SoundInstance_SetVolume(FAudioGMS_SoundInstance* instance, float volume) | ||||
| { | ||||
|     FAudioVoice_SetVolume(instance->handle, volume, 0); | ||||
| } | ||||
| 
 | ||||
| static void FAudioGMS_INTERNAL_Apply3D(FAudioGMS_SoundInstance* instance) | ||||
| { | ||||
|     F3DAUDIO_EMITTER* emitter = instance->emitter; | ||||
| 
 | ||||
|     if (emitter == NULL) | ||||
|     { | ||||
|         Log("Sound instance does not have 3D data! Did you forget to initialize?"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     F3DAudioCalculate( | ||||
|         device->handle3D, | ||||
|         &device->listener, | ||||
|         emitter, | ||||
|         F3DAUDIO_CALCULATE_MATRIX | F3DAUDIO_CALCULATE_DOPPLER, | ||||
|         &instance->dspSettings | ||||
|     ); | ||||
| 
 | ||||
|     FAudioGMS_INTERNAL_SoundInstance_UpdatePitch(instance); | ||||
|     FAudioVoice_SetOutputMatrix( | ||||
|         instance->handle, | ||||
|         device->masteringVoice, | ||||
|         instance->dspSettings.SrcChannelCount, | ||||
|         instance->dspSettings.DstChannelCount, | ||||
|         instance->dspSettings.pMatrixCoefficients, | ||||
|         0 | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound( | ||||
|     FAudioGMS_StaticSound *staticSound, | ||||
|     double pan, | ||||
|  | @ -646,6 +740,11 @@ static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_CreateFromStati | |||
| 
 | ||||
|     instance->soundState = SoundState_Stopped; | ||||
| 
 | ||||
|     instance->is3D = 0; | ||||
|     instance->emitter = NULL; | ||||
|     instance->stereoAzimuth[0] = 0.0f; | ||||
|     instance->stereoAzimuth[1] = 0.0f; | ||||
| 
 | ||||
|     if (device->soundInstanceIndexStack.count > 0) | ||||
|     { | ||||
|         instance->id = IdStack_Pop(&device->soundInstanceIndexStack); | ||||
|  | @ -663,6 +762,47 @@ static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_CreateFromStati | |||
|     return instance; | ||||
| } | ||||
| 
 | ||||
| static void FAudioGMS_INTERNAL_StaticSound_AddEmitter(FAudioGMS_SoundInstance* instance, float x, float y, float z) | ||||
| { | ||||
|     instance->is3D = 1; | ||||
| 
 | ||||
|     instance->emitter = SDL_malloc(sizeof(F3DAUDIO_EMITTER)); | ||||
| 
 | ||||
|     /* defaults based on XNA behavior */ | ||||
|     instance->emitter->pCone = NULL; | ||||
|     instance->emitter->ChannelRadius = 1.0f; | ||||
|     instance->emitter->pChannelAzimuths = instance->stereoAzimuth; | ||||
|     instance->emitter->pVolumeCurve = NULL; | ||||
|     instance->emitter->pLFECurve = NULL; | ||||
|     instance->emitter->pLPFDirectCurve = NULL; | ||||
|     instance->emitter->pLPFReverbCurve = NULL; | ||||
|     instance->emitter->pReverbCurve = NULL; | ||||
|     instance->emitter->InnerRadius = 0; | ||||
|     instance->emitter->InnerRadiusAngle = 0; | ||||
| 
 | ||||
|     instance->emitter->ChannelCount = instance->dspSettings.SrcChannelCount; | ||||
|     instance->emitter->CurveDistanceScaler = CURVE_DISTANCE_SCALER; | ||||
|     instance->emitter->DopplerScaler = 1.0f; | ||||
| 
 | ||||
|     instance->emitter->Position.x = x; | ||||
|     instance->emitter->Position.y = y; | ||||
|     instance->emitter->Position.z = z; | ||||
| 
 | ||||
|     instance->emitter->Velocity.x = 0; | ||||
|     instance->emitter->Velocity.y = 0; | ||||
|     instance->emitter->Velocity.z = 0; | ||||
| 
 | ||||
|     instance->emitter->OrientTop.x = 0; | ||||
|     instance->emitter->OrientTop.y = 1; | ||||
|     instance->emitter->OrientTop.z = 0; | ||||
| 
 | ||||
|     instance->emitter->OrientFront.x = 0; | ||||
|     instance->emitter->OrientFront.y = 0; | ||||
|     instance->emitter->OrientFront.z = 1; | ||||
| 
 | ||||
|     FAudioGMS_INTERNAL_Apply3D(instance); | ||||
| } | ||||
| 
 | ||||
| static void FAudioGMS_INTERNAL_SoundInstance_Play(FAudioGMS_SoundInstance* instance) | ||||
| { | ||||
|     if (instance->isStatic) | ||||
|  | @ -693,7 +833,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_Play(FAudioGMS_SoundInstance* insta | |||
| 
 | ||||
| void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double pitch, double volume, double reverb) | ||||
| { | ||||
|     FAudioGMS_StaticSound* staticSound = device->staticSounds[(uint32_t)staticSoundID]; | ||||
|     FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID); | ||||
| 
 | ||||
|     if (staticSound != NULL) | ||||
|     { | ||||
|  | @ -707,9 +847,26 @@ 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) | ||||
| { | ||||
|     FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID); | ||||
| 
 | ||||
|     if (staticSound != NULL) | ||||
|     { | ||||
|         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound, 0, pitch, volume, reverb); | ||||
|         instance->destroyOnFinish = 1; | ||||
|         FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z); | ||||
|         FAudioGMS_INTERNAL_SoundInstance_Play(instance); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         Log("StaticSound_PlayOneOffSpatial: Invalid static sound ID! Did you destroy this sound?"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch, double volume, double reverb, double loop) | ||||
| { | ||||
|     FAudioGMS_StaticSound* staticSound = device->staticSounds[(uint32_t)staticSoundID]; | ||||
|     FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID); | ||||
| 
 | ||||
|     if (staticSound != NULL) | ||||
|     { | ||||
|  | @ -725,9 +882,28 @@ 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) | ||||
| { | ||||
|     FAudioGMS_StaticSound* staticSound = FAudioGMS_INTERNAL_LookupStaticSound((uint32_t)staticSoundID); | ||||
| 
 | ||||
|     if (staticSound != NULL) | ||||
|     { | ||||
|         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound, 0, pitch, volume, reverb); | ||||
|         instance->loop = (uint8_t)loop; | ||||
|         FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z); | ||||
|         FAudioGMS_INTERNAL_SoundInstance_Play(instance); | ||||
|         return (double)instance->id; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         Log("StaticSound_PlaySpatial: Invalid static sound ID! Did you destroy this sound?"); | ||||
|         return -1; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_SoundInstance_Play(double id) | ||||
| { | ||||
|     FAudioGMS_SoundInstance *instance = device->soundInstances[(uint32_t)id]; | ||||
|     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); | ||||
| 
 | ||||
|     if (instance != NULL) | ||||
|     { | ||||
|  | @ -737,7 +913,7 @@ void FAudioGMS_SoundInstance_Play(double id) | |||
| 
 | ||||
| void FAudioGMS_SoundInstance_Pause(double id) | ||||
| { | ||||
|     FAudioGMS_SoundInstance* instance = device->soundInstances[(uint32_t)id]; | ||||
|     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); | ||||
| 
 | ||||
|     if (instance != NULL) | ||||
|     { | ||||
|  | @ -758,7 +934,7 @@ void FAudioGMS_SoundInstance_Pause(double id) | |||
| 
 | ||||
| void FAudioGMS_SoundInstance_Stop(double id) | ||||
| { | ||||
|     FAudioGMS_SoundInstance* instance = device->soundInstances[(uint32_t)id]; | ||||
|     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); | ||||
| 
 | ||||
|     if (instance != NULL) | ||||
|     { | ||||
|  | @ -773,19 +949,82 @@ void FAudioGMS_SoundInstance_Stop(double id) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z) | ||||
| { | ||||
|     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID); | ||||
| 
 | ||||
|     if (instance != NULL) | ||||
|     { | ||||
|         if (!instance->is3D) | ||||
|         { | ||||
|             Log("Not a 3D sound!"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         instance->emitter->Velocity.x = x - instance->emitter->Position.x; | ||||
|         instance->emitter->Velocity.y = y - instance->emitter->Position.y; | ||||
|         instance->emitter->Velocity.z = z - instance->emitter->Position.z; | ||||
| 
 | ||||
|         instance->emitter->Position.x = x; | ||||
|         instance->emitter->Position.y = y; | ||||
|         instance->emitter->Position.z = z; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_SetListenerPosition(double x, double y, double z) | ||||
| { | ||||
|     device->listener.Velocity.x = x - device->listener.Position.x; | ||||
|     device->listener.Velocity.y = y - device->listener.Position.y; | ||||
|     device->listener.Velocity.z = z - device->listener.Position.z; | ||||
| 
 | ||||
|     device->listener.Position.x = x; | ||||
|     device->listener.Position.y = y; | ||||
|     device->listener.Position.z = z; | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_Update() | ||||
| { | ||||
|     uint32_t i; | ||||
| 
 | ||||
|     for (i = 0; i < device->soundInstanceCount; i += 1) | ||||
|     { | ||||
|         FAudioGMS_SoundInstance* instance = device->soundInstances[i]; | ||||
| 
 | ||||
|         if (instance != NULL) | ||||
|         { | ||||
|             if (instance->is3D) | ||||
|             { | ||||
|                 FAudioGMS_INTERNAL_Apply3D(instance); | ||||
|             } | ||||
| 
 | ||||
|             if (instance->destroyOnFinish) | ||||
|             { | ||||
|                 FAudioVoiceState state; | ||||
|                 FAudioSourceVoice_GetState(instance->handle, &state, FAUDIO_VOICE_NOSAMPLESPLAYED); | ||||
| 
 | ||||
|                 if (state.BuffersQueued == 0) | ||||
|                 { | ||||
|                     FAudioGMS_INTERNAL_SoundInstance_Destroy(instance); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void FAudioGMS_Destroy() | ||||
| { | ||||
|     uint32_t i = 0; | ||||
|     for (i = 0; i < device->staticSoundCount; i += 1) | ||||
|     { | ||||
|         FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[i]); | ||||
|     } | ||||
| 
 | ||||
|     for (i = 0; i < device->soundInstanceCount; i += 1) | ||||
|     { | ||||
|         FAudioGMS_INTERNAL_SoundInstance_Destroy(device->soundInstances[i]); | ||||
|     } | ||||
| 
 | ||||
|     for (i = 0; i < device->staticSoundCount; i += 1) | ||||
|     { | ||||
|         FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[i]); | ||||
|     } | ||||
| 
 | ||||
|     FAudio_Release(device->handle); | ||||
|     SDL_free(device); | ||||
|     device = NULL; | ||||
|  |  | |||
|  | @ -39,20 +39,25 @@ | |||
| extern "C" { | ||||
| #endif /* __cplusplus */ | ||||
| 
 | ||||
| FAUDIOGMSAPI void FAudioGMS_Init(); | ||||
| FAUDIOGMSAPI void FAudioGMS_Update(); | ||||
| FAUDIOGMSAPI void FAudioGMS_Init(double speedOfSound); /* recommend about 1500? for 2D game */ | ||||
| 
 | ||||
| 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_Destroy(double id); | ||||
| 
 | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_Play(double id); | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_Pause(double id); | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_Stop(double id); | ||||
| 
 | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z); | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_Destroy(double id); | ||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_DestroyWhenFinished(double id); | ||||
| FAUDIOGMSAPI void FAudioGMS_StaticSound_Destroy(double id); | ||||
| 
 | ||||
| FAUDIOGMSAPI void FAudioGMS_SetListenerPosition(double x, double y, double z); | ||||
| 
 | ||||
| FAUDIOGMSAPI void FAudioGMS_Update(); | ||||
| FAUDIOGMSAPI void FAudioGMS_Destroy(); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue