initial streaming audio implementation
							parent
							
								
									9162b45fd4
								
							
						
					
					
						commit
						bb9b1fef65
					
				
							
								
								
									
										546
									
								
								src/FAudioGMS.c
								
								
								
								
							
							
						
						
									
										546
									
								
								src/FAudioGMS.c
								
								
								
								
							|  | @ -24,13 +24,17 @@ | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include "../lib/SDL/include/SDL.h" | #include "SDL.h" | ||||||
|  | 
 | ||||||
|  | #define DISABLE_XNASONG | ||||||
| 
 | 
 | ||||||
| #include "FAudioGMS.h" | #include "FAudioGMS.h" | ||||||
| #include "../lib/FAudio/include/FAPOBase.h" | 
 | ||||||
| #include "../lib/FAudio/include/FAudioFX.h" | #include "FAPOBase.h" | ||||||
| #include "../lib/FAudio/include/F3DAudio.h" | #include "FAudioFX.h" | ||||||
| #include "../lib/FAudio/include/FAudio.h" | #include "F3DAudio.h" | ||||||
|  | 
 | ||||||
|  | #include "FAudio.h" | ||||||
| 
 | 
 | ||||||
| #define DR_WAV_IMPLEMENTATION | #define DR_WAV_IMPLEMENTATION | ||||||
| #define DRWAV_MALLOC(sz)                   SDL_malloc((sz)) | #define DRWAV_MALLOC(sz)                   SDL_malloc((sz)) | ||||||
|  | @ -40,6 +44,64 @@ | ||||||
| #define DRWAV_ZERO_MEMORY(p, sz)           SDL_memset((p), 0, (sz)) | #define DRWAV_ZERO_MEMORY(p, sz)           SDL_memset((p), 0, (sz)) | ||||||
| #include "../lib/dr_wav.h" | #include "../lib/dr_wav.h" | ||||||
| 
 | 
 | ||||||
|  | /* stb vorbis defines. this is kind of a mess but oh well */ | ||||||
|  | 
 | ||||||
|  | #include "../lib/FAudio/src/FAudio_internal.h" | ||||||
|  | 
 | ||||||
|  | #define malloc FAudio_malloc | ||||||
|  | #define realloc FAudio_realloc | ||||||
|  | #define free FAudio_free | ||||||
|  | #ifdef memset /* Thanks, Apple! */ | ||||||
|  | #undef memset | ||||||
|  | #endif | ||||||
|  | #define memset SDL_memset | ||||||
|  | #ifdef memcpy /* Thanks, Apple! */ | ||||||
|  | #undef memcpy | ||||||
|  | #endif | ||||||
|  | #define memcpy SDL_memcpy | ||||||
|  | #define memcmp FAudio_memcmp | ||||||
|  | 
 | ||||||
|  | #define pow FAudio_pow | ||||||
|  | #define log(x) FAudio_log(x) | ||||||
|  | #define sin(x) FAudio_sin(x) | ||||||
|  | #define cos(x) FAudio_cos(x) | ||||||
|  | #define floor FAudio_floor | ||||||
|  | #define abs(x) FAudio_abs(x) | ||||||
|  | #define ldexp(v, e) FAudio_ldexp((v), (e)) | ||||||
|  | #define exp(x) FAudio_exp(x) | ||||||
|  | 
 | ||||||
|  | #define qsort FAudio_qsort | ||||||
|  | 
 | ||||||
|  | #ifdef assert | ||||||
|  | #undef assert | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | #define assert FAudio_assert | ||||||
|  | 
 | ||||||
|  | #define FILE FAudioIOStream | ||||||
|  | #ifdef SEEK_SET | ||||||
|  | #undef SEEK_SET | ||||||
|  | #endif | ||||||
|  | #ifdef SEEK_END | ||||||
|  | #undef SEEK_END | ||||||
|  | #endif | ||||||
|  | #ifdef EOF | ||||||
|  | #undef EOF | ||||||
|  | #endif | ||||||
|  | #define SEEK_SET FAUDIO_SEEK_SET | ||||||
|  | #define SEEK_END FAUDIO_SEEK_END | ||||||
|  | #define EOF FAUDIO_EOF | ||||||
|  | #define fopen(path, mode) FAudio_fopen(path) | ||||||
|  | #define fopen_s(io, path, mode) (!(*io = FAudio_fopen(path))) | ||||||
|  | #define fclose(io) FAudio_close(io) | ||||||
|  | #define fread(dst, size, count, io) io->read(io->data, dst, size, count) | ||||||
|  | #define fseek(io, offset, whence) io->seek(io->data, offset, whence) | ||||||
|  | #define ftell(io) io->seek(io->data, 0, FAUDIO_SEEK_CUR) | ||||||
|  | 
 | ||||||
|  | #define STB_VORBIS_NO_PUSHDATA_API 1 | ||||||
|  | #define STB_VORBIS_NO_INTEGER_CONVERSION 1 | ||||||
|  | #include "../lib/FAudio/src/stb_vorbis.h" | ||||||
|  | 
 | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| 
 | 
 | ||||||
| static inline void Log(char *string) | static inline void Log(char *string) | ||||||
|  | @ -80,6 +142,52 @@ static inline uint32_t IdStack_Pop(IdStack* stack) | ||||||
|     return stack->array[stack->count]; |     return stack->array[stack->count]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | typedef struct BufferQueue  | ||||||
|  | { | ||||||
|  |     uint32_t head; | ||||||
|  |     uint32_t tail; | ||||||
|  |     uint32_t size; /* DO NOT MUTATE */ | ||||||
|  |     uint32_t count; /* number of currently enqueued elements */ | ||||||
|  |     uint8_t** buffers; | ||||||
|  | } BufferQueue; | ||||||
|  | 
 | ||||||
|  | static inline void BufferQueue_Init(BufferQueue* queue, uint32_t size) | ||||||
|  | { | ||||||
|  |     queue->head = 0; | ||||||
|  |     queue->tail = 0; | ||||||
|  |     queue->size = size; | ||||||
|  |     queue->count = 0; | ||||||
|  |     queue->buffers = SDL_malloc(size * sizeof(uint8_t*)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline uint8_t* BufferQueue_Dequeue(BufferQueue *queue)  | ||||||
|  | { | ||||||
|  |     if (queue->tail == queue->head)  | ||||||
|  |     { | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     uint8_t* buffer = queue->buffers[queue->tail]; | ||||||
|  |     queue->buffers[queue->tail] = NULL; | ||||||
|  |     queue->tail = (queue->tail + 1) % queue->size; | ||||||
|  | 
 | ||||||
|  |     queue->count -= 1; | ||||||
|  |     return buffer; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static inline void BufferQueue_Enqueue(BufferQueue *queue, uint8_t* buffer)  | ||||||
|  | { | ||||||
|  |     if (((queue->head + 1) % queue->size) == queue->tail)  | ||||||
|  |     { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     queue->buffers[queue->head] = buffer; | ||||||
|  |     queue->head = (queue->head + 1) % queue->size; | ||||||
|  | 
 | ||||||
|  |     queue->count += 1; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| typedef enum FAudioGMS_SoundState | typedef enum FAudioGMS_SoundState | ||||||
| { | { | ||||||
|     SoundState_Playing, |     SoundState_Playing, | ||||||
|  | @ -97,6 +205,13 @@ typedef struct FAudioGMS_StaticSound | ||||||
|     uint32_t loopLength; |     uint32_t loopLength; | ||||||
| } FAudioGMS_StaticSound; | } FAudioGMS_StaticSound; | ||||||
| 
 | 
 | ||||||
|  | typedef struct FAudioGMS_StreamingSound | ||||||
|  | { | ||||||
|  |     stb_vorbis* fileHandle; | ||||||
|  |     stb_vorbis_info info; | ||||||
|  |     BufferQueue bufferQueue; | ||||||
|  | } FAudioGMS_StreamingSound; | ||||||
|  | 
 | ||||||
| typedef struct FAudioGMS_SoundInstance | typedef struct FAudioGMS_SoundInstance | ||||||
| { | { | ||||||
|     uint32_t id; |     uint32_t id; | ||||||
|  | @ -127,13 +242,17 @@ typedef struct FAudioGMS_SoundInstance | ||||||
| 
 | 
 | ||||||
|     union |     union | ||||||
|     { |     { | ||||||
|         FAudioGMS_StaticSound *staticSound; |         FAudioGMS_StaticSound *staticSound; /* static sounds are loaded separately, so they do not belong to the instance */ | ||||||
|         /* TODO: streaming */ |         FAudioGMS_StreamingSound streamingSound; | ||||||
|     } parent; |     } soundData; | ||||||
| } FAudioGMS_SoundInstance; | } FAudioGMS_SoundInstance; | ||||||
| 
 | 
 | ||||||
| static const float SPEED_OF_SOUND = 343.5f; | static const float SPEED_OF_SOUND = 343.5f; | ||||||
| static const float DOPPLER_SCALE = 1.0f; | static const float DOPPLER_SCALE = 1.0f; | ||||||
|  | static const uint32_t MINIMUM_BUFFER_CHECK = 3; | ||||||
|  | 
 | ||||||
|  | #define MAX_BUFFER_QUEUE_COUNT 16 | ||||||
|  | #define STREAMING_BUFFER_SIZE 1024 * 128 * sizeof(float) /* FIXME: what should this value be? */ | ||||||
| 
 | 
 | ||||||
| typedef struct FAudioGMS_Device | typedef struct FAudioGMS_Device | ||||||
| { | { | ||||||
|  | @ -153,6 +272,8 @@ typedef struct FAudioGMS_Device | ||||||
|     FAudioGMS_SoundInstance **soundInstances; |     FAudioGMS_SoundInstance **soundInstances; | ||||||
|     uint32_t soundInstanceCount; |     uint32_t soundInstanceCount; | ||||||
|     IdStack soundInstanceIndexStack; |     IdStack soundInstanceIndexStack; | ||||||
|  | 
 | ||||||
|  |     float streamStagingBuffer[STREAMING_BUFFER_SIZE]; | ||||||
| } FAudioGMS_Device; | } FAudioGMS_Device; | ||||||
| 
 | 
 | ||||||
| static FAudioGMS_Device* device = NULL; | static FAudioGMS_Device* device = NULL; | ||||||
|  | @ -291,68 +412,6 @@ void FAudioGMS_Init(double spatialDistanceScale) | ||||||
|     fflush(stdout); |     fflush(stdout); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void FAudioGMS_INTERNAL_SoundInstance_Destroy(FAudioGMS_SoundInstance* instance) |  | ||||||
| { |  | ||||||
|     if (instance != NULL) |  | ||||||
|     { |  | ||||||
|         device->soundInstances[instance->id] = NULL; |  | ||||||
|         IdStack_Push(&device->soundInstanceIndexStack, instance->id); |  | ||||||
|         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); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void FAudioGMS_SoundInstance_Destroy(double 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 = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); |  | ||||||
| 
 |  | ||||||
|     if (instance != NULL) |  | ||||||
|     { |  | ||||||
|         instance->destroyOnFinish = 1; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* FIXME: this will die horribly if a sound is playing */ |  | ||||||
| static void FAudioGMS_INTERNAL_StaticSound_Destroy(FAudioGMS_StaticSound* sound) |  | ||||||
| { |  | ||||||
|     if (sound != NULL) |  | ||||||
|     { |  | ||||||
|         device->staticSounds[sound->id] = NULL; |  | ||||||
|         IdStack_Push(&device->staticSoundIndexStack, sound->id); |  | ||||||
|         SDL_free((void*)sound->buffer.pAudioData); |  | ||||||
|         SDL_free(sound); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void FAudioGMS_StaticSound_Destroy(double id) |  | ||||||
| { |  | ||||||
|     if (id >= 0 && id < device->staticSoundCount) |  | ||||||
|     { |  | ||||||
|         FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[(uint32_t)id]); |  | ||||||
|     } |  | ||||||
|     else |  | ||||||
|     { |  | ||||||
|         Log("Invalid ID for destroy!"); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Taken from https://github.com/FNA-XNA/FNA/blob/master/src/Audio/SoundEffectInstance.cs */ | /* Taken from https://github.com/FNA-XNA/FNA/blob/master/src/Audio/SoundEffectInstance.cs */ | ||||||
| static void SetPanMatrixCoefficients(FAudioGMS_SoundInstance *instance) | static void SetPanMatrixCoefficients(FAudioGMS_SoundInstance *instance) | ||||||
| { | { | ||||||
|  | @ -647,6 +706,18 @@ static void FAudioGMS_INTERNAL_SoundInstance_SetVolume(FAudioGMS_SoundInstance* | ||||||
|     FAudioVoice_SetVolume(instance->handle, volume, 0); |     FAudioVoice_SetVolume(instance->handle, volume, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void FAudioGMS_INTERNAL_SoundInstance_SetProperties(FAudioGMS_SoundInstance* instance, double pan, double pitch, double volume, double reverb) | ||||||
|  | { | ||||||
|  |     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) | static void FAudioGMS_INTERNAL_Apply3D(FAudioGMS_SoundInstance* instance) | ||||||
| { | { | ||||||
|     F3DAUDIO_EMITTER* emitter = instance->emitter; |     F3DAUDIO_EMITTER* emitter = instance->emitter; | ||||||
|  | @ -676,27 +747,23 @@ static void FAudioGMS_INTERNAL_Apply3D(FAudioGMS_SoundInstance* instance) | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound( | static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_Init( | ||||||
|     FAudioGMS_StaticSound *staticSound, |     uint32_t channelCount, | ||||||
|     double pan, |     uint32_t samplesPerSecond | ||||||
|     double pitch, |  | ||||||
|     double volume, |  | ||||||
|     double reverb |  | ||||||
| ) { | ) { | ||||||
|     FAudioGMS_SoundInstance *instance = SDL_malloc(sizeof(FAudioGMS_SoundInstance)); |     FAudioGMS_SoundInstance* instance = SDL_malloc(sizeof(FAudioGMS_SoundInstance)); | ||||||
| 
 | 
 | ||||||
|     instance->handle = NULL; |     instance->handle = NULL; | ||||||
|     instance->parent.staticSound = staticSound; | 
 | ||||||
|     instance->isStatic = 1; |  | ||||||
|     instance->loop = 0; |     instance->loop = 0; | ||||||
|     instance->destroyOnFinish = 0; |     instance->destroyOnFinish = 0; | ||||||
| 
 | 
 | ||||||
|     instance->format.wFormatTag = 3; |     instance->format.wFormatTag = FAUDIO_FORMAT_IEEE_FLOAT; | ||||||
|     instance->format.wBitsPerSample = 32; |     instance->format.wBitsPerSample = 32; | ||||||
|     instance->format.nChannels = staticSound->channels; |     instance->format.nChannels = channelCount; | ||||||
|     instance->format.nBlockAlign = (uint16_t)(4 * staticSound->channels); |     instance->format.nBlockAlign = (uint16_t)(4 * channelCount); | ||||||
|     instance->format.nSamplesPerSec = staticSound->samplesPerSecond; |     instance->format.nSamplesPerSec = samplesPerSecond; | ||||||
|     instance->format.nAvgBytesPerSec = instance->format.nBlockAlign * staticSound->samplesPerSecond; |     instance->format.nAvgBytesPerSec = instance->format.nBlockAlign * samplesPerSecond; | ||||||
| 
 | 
 | ||||||
|     FAudio_CreateSourceVoice( |     FAudio_CreateSourceVoice( | ||||||
|         device->handle, |         device->handle, | ||||||
|  | @ -716,27 +783,22 @@ static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_CreateFromStati | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     instance->dspSettings.DopplerFactor = 1.0f; |     instance->dspSettings.DopplerFactor = 1.0f; | ||||||
|     instance->dspSettings.SrcChannelCount = staticSound->channels; |     instance->dspSettings.SrcChannelCount = channelCount; | ||||||
|     instance->dspSettings.DstChannelCount = device->deviceDetails.OutputFormat.Format.nChannels; |     instance->dspSettings.DstChannelCount = device->deviceDetails.OutputFormat.Format.nChannels; | ||||||
| 
 | 
 | ||||||
|     uint32_t memsize = 4 * instance->dspSettings.SrcChannelCount * instance->dspSettings.DstChannelCount; |     uint32_t memsize = 4 * instance->dspSettings.SrcChannelCount * instance->dspSettings.DstChannelCount; | ||||||
|     instance->dspSettings.pMatrixCoefficients = SDL_malloc(memsize); |     instance->dspSettings.pMatrixCoefficients = SDL_malloc(memsize); | ||||||
|     SDL_memset(instance->dspSettings.pMatrixCoefficients, 0, memsize); |     SDL_memset(instance->dspSettings.pMatrixCoefficients, 0, memsize); | ||||||
| 
 | 
 | ||||||
|     FAudioGMS_INTERNAL_SoundInstance_SetPan(instance, pan); |  | ||||||
|     FAudioGMS_INTERNAL_SoundInstance_SetPitch(instance, pitch); |  | ||||||
|     FAudioGMS_INTERNAL_SoundInstance_SetVolume(instance, volume); |  | ||||||
| 
 |  | ||||||
|     instance->reverbAttached = 0; |     instance->reverbAttached = 0; | ||||||
|     instance->reverb = 0.0f; |     instance->reverb = 0.0f; | ||||||
|     instance->lowPassFilter = 0.0f; |     instance->lowPassFilter = 0.0f; | ||||||
|     instance->highPassFilter = 0.0f; |     instance->highPassFilter = 0.0f; | ||||||
|     instance->bandPassFilter = 0.0f; |     instance->bandPassFilter = 0.0f; | ||||||
| 
 | 
 | ||||||
|     if (reverb > 0.0f) |     FAudioGMS_INTERNAL_SoundInstance_SetPan(instance, 0); | ||||||
|     { |     FAudioGMS_INTERNAL_SoundInstance_SetPitch(instance, 1); | ||||||
|         FAudioGMS_INTERNAL_SoundInstance_SetReverb(instance, reverb); |     FAudioGMS_INTERNAL_SoundInstance_SetVolume(instance, 1); | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     instance->soundState = SoundState_Stopped; |     instance->soundState = SoundState_Stopped; | ||||||
| 
 | 
 | ||||||
|  | @ -762,6 +824,47 @@ static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_CreateFromStati | ||||||
|     return instance; |     return instance; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound( | ||||||
|  |     FAudioGMS_StaticSound *staticSound | ||||||
|  | ) { | ||||||
|  |     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_Init( | ||||||
|  |         staticSound->channels, | ||||||
|  |         staticSound->samplesPerSecond | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     instance->isStatic = 1; | ||||||
|  |     instance->soundData.staticSound = staticSound; | ||||||
|  | 
 | ||||||
|  |     return instance; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | double FAudioGMS_StreamingSound_LoadOGG(char* filePath) | ||||||
|  | { | ||||||
|  |     int error = -1; | ||||||
|  |     stb_vorbis *fileHandle = stb_vorbis_open_filename(filePath, &error, NULL); | ||||||
|  | 
 | ||||||
|  |     if (error != 0) | ||||||
|  |     { | ||||||
|  |         Log("Error opening OGG file!"); | ||||||
|  |         Log(filePath); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     stb_vorbis_info info = stb_vorbis_get_info(fileHandle); | ||||||
|  | 
 | ||||||
|  |     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_Init( | ||||||
|  |         info.channels, | ||||||
|  |         info.sample_rate | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     instance->isStatic = 0; | ||||||
|  |     instance->soundData.streamingSound.fileHandle = fileHandle; | ||||||
|  |     instance->soundData.streamingSound.info = info; | ||||||
|  |     BufferQueue_Init(&instance->soundData.streamingSound.bufferQueue, MAX_BUFFER_QUEUE_COUNT); | ||||||
|  | 
 | ||||||
|  |     return instance->id; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void FAudioGMS_INTERNAL_StaticSound_AddEmitter(FAudioGMS_SoundInstance* instance, float x, float y, float z) | static void FAudioGMS_INTERNAL_StaticSound_AddEmitter(FAudioGMS_SoundInstance* instance, float x, float y, float z) | ||||||
| { | { | ||||||
|     instance->is3D = 1; |     instance->is3D = 1; | ||||||
|  | @ -803,32 +906,126 @@ static void FAudioGMS_INTERNAL_StaticSound_AddEmitter(FAudioGMS_SoundInstance* i | ||||||
|     FAudioGMS_INTERNAL_Apply3D(instance); |     FAudioGMS_INTERNAL_Apply3D(instance); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void FAudioGMS_INTERNAL_SoundInstance_Play(FAudioGMS_SoundInstance* instance) | static void FAudioGMS_INTERNAL_SoundInstance_AddBuffer(FAudioGMS_SoundInstance* instance) | ||||||
| { | { | ||||||
|     if (instance->isStatic) |     /* NOTE: this function returns samples per channel, not total samples */ | ||||||
|     { |     uint32_t samples = stb_vorbis_get_samples_float_interleaved( | ||||||
|         if (instance->soundState == SoundState_Playing) |         instance->soundData.streamingSound.fileHandle, | ||||||
|         { |         instance->format.nChannels, | ||||||
|             return; |         device->streamStagingBuffer, | ||||||
|         } |         STREAMING_BUFFER_SIZE | ||||||
|  |     ); | ||||||
| 
 | 
 | ||||||
|  |     uint32_t sampleCount = samples * instance->format.nChannels; | ||||||
|  |     uint32_t bufferLength = sampleCount * sizeof(float); | ||||||
|  | 
 | ||||||
|  |     uint8_t* nextBuffer = SDL_malloc(bufferLength); | ||||||
|  |     SDL_memcpy(nextBuffer, device->streamStagingBuffer, bufferLength); | ||||||
|  | 
 | ||||||
|  |     BufferQueue_Enqueue(&instance->soundData.streamingSound.bufferQueue, nextBuffer); | ||||||
|  | 
 | ||||||
|  |     if (instance->soundState != SoundState_Stopped) | ||||||
|  |     { | ||||||
|  |         FAudioBuffer buffer; | ||||||
|  |         buffer.AudioBytes = bufferLength; | ||||||
|  |         buffer.pAudioData = nextBuffer; | ||||||
|  |         buffer.PlayLength = | ||||||
|  |             bufferLength / | ||||||
|  |             instance->format.nChannels / | ||||||
|  |             (instance->format.wBitsPerSample / 8); | ||||||
|  |         buffer.PlayBegin = 0; | ||||||
|  | 
 | ||||||
|  |         buffer.Flags = 0; | ||||||
|  |         buffer.LoopBegin = 0; | ||||||
|  |         buffer.LoopCount = 0; | ||||||
|  |         buffer.LoopLength = 0; | ||||||
|  |         buffer.pContext = NULL; | ||||||
|  | 
 | ||||||
|  |         FAudioSourceVoice_SubmitSourceBuffer(instance->handle, &buffer, NULL); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* We have reached the end of the file! */ | ||||||
|  |     if (sampleCount < STREAMING_BUFFER_SIZE) | ||||||
|  |     { | ||||||
|         if (instance->loop) |         if (instance->loop) | ||||||
|         { |         { | ||||||
|             instance->parent.staticSound->buffer.LoopCount = FAUDIO_LOOP_INFINITE; |             stb_vorbis_seek_start(instance->soundData.streamingSound.fileHandle); | ||||||
|             instance->parent.staticSound->buffer.LoopBegin = instance->parent.staticSound->loopStart; |  | ||||||
|             instance->parent.staticSound->buffer.LoopLength = instance->parent.staticSound->loopLength; |  | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             instance->parent.staticSound->buffer.LoopCount = 0; |             instance->soundState = SoundState_Stopped; | ||||||
|             instance->parent.staticSound->buffer.LoopBegin = 0; |         } | ||||||
|             instance->parent.staticSound->buffer.LoopLength = 0; |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void FAudioGMS_INTERNAL_SoundInstance_StreamingUpdate(FAudioGMS_SoundInstance* instance) | ||||||
|  | { | ||||||
|  |     uint32_t i; | ||||||
|  |     FAudioVoiceState voiceState; | ||||||
|  | 
 | ||||||
|  |     if (instance->isStatic) { return; } | ||||||
|  | 
 | ||||||
|  |     FAudioSourceVoice_GetState( | ||||||
|  |         instance->handle, | ||||||
|  |         &voiceState, | ||||||
|  |         FAUDIO_VOICE_NOSAMPLESPLAYED | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     while (instance->soundData.streamingSound.bufferQueue.count > voiceState.BuffersQueued) | ||||||
|  |     { | ||||||
|  |         uint8_t* buffer = BufferQueue_Dequeue(&instance->soundData.streamingSound.bufferQueue); | ||||||
|  |         SDL_free(buffer); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     for (i = MINIMUM_BUFFER_CHECK - instance->soundData.streamingSound.bufferQueue.count; i > 0; i -= 1) | ||||||
|  |     { | ||||||
|  |         FAudioGMS_INTERNAL_SoundInstance_AddBuffer(instance); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void FAudioGMS_INTERNAL_SoundInstance_ClearBuffers(FAudioGMS_SoundInstance* instance) | ||||||
|  | { | ||||||
|  |     uint32_t i; | ||||||
|  |     uint32_t bufferCount = instance->soundData.streamingSound.bufferQueue.count; | ||||||
|  | 
 | ||||||
|  |     for (i = 0; i < bufferCount; i += 1) | ||||||
|  |     { | ||||||
|  |         uint8_t* buffer = BufferQueue_Dequeue(&instance->soundData.streamingSound.bufferQueue); | ||||||
|  |         SDL_free(buffer); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void FAudioGMS_INTERNAL_SoundInstance_Play(FAudioGMS_SoundInstance* instance) | ||||||
|  | { | ||||||
|  |     if (instance->soundState == SoundState_Playing) | ||||||
|  |     { | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (instance->isStatic) | ||||||
|  |     { | ||||||
|  |         if (instance->loop) | ||||||
|  |         { | ||||||
|  |             instance->soundData.staticSound->buffer.LoopCount = FAUDIO_LOOP_INFINITE; | ||||||
|  |             instance->soundData.staticSound->buffer.LoopBegin = instance->soundData.staticSound->loopStart; | ||||||
|  |             instance->soundData.staticSound->buffer.LoopLength = instance->soundData.staticSound->loopLength; | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             instance->soundData.staticSound->buffer.LoopCount = 0; | ||||||
|  |             instance->soundData.staticSound->buffer.LoopBegin = 0; | ||||||
|  |             instance->soundData.staticSound->buffer.LoopLength = 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         FAudioSourceVoice_SubmitSourceBuffer(instance->handle, &instance->parent.staticSound->buffer, NULL); |         FAudioSourceVoice_SubmitSourceBuffer(instance->handle, &instance->soundData.staticSound->buffer, NULL); | ||||||
|         FAudioSourceVoice_Start(instance->handle, 0, 0); |  | ||||||
|         instance->soundState = SoundState_Playing; |  | ||||||
|     } |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         FAudioGMS_INTERNAL_SoundInstance_StreamingUpdate(instance); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     FAudioSourceVoice_Start(instance->handle, 0, 0); | ||||||
|  |     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, double reverb) | ||||||
|  | @ -837,8 +1034,9 @@ void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double p | ||||||
| 
 | 
 | ||||||
|     if (staticSound != NULL) |     if (staticSound != NULL) | ||||||
|     { |     { | ||||||
|         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound, pan, pitch, volume, reverb); |         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound); | ||||||
|         instance->destroyOnFinish = 1; |         instance->destroyOnFinish = 1; | ||||||
|  |         FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, pan, pitch, volume, reverb); | ||||||
|         FAudioGMS_INTERNAL_SoundInstance_Play(instance); |         FAudioGMS_INTERNAL_SoundInstance_Play(instance); | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|  | @ -853,8 +1051,9 @@ void FAudioGMS_StaticSound_PlayOneOffSpatial(double staticSoundID, double x, dou | ||||||
| 
 | 
 | ||||||
|     if (staticSound != NULL) |     if (staticSound != NULL) | ||||||
|     { |     { | ||||||
|         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound, 0, pitch, volume, reverb); |         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound); | ||||||
|         instance->destroyOnFinish = 1; |         instance->destroyOnFinish = 1; | ||||||
|  |         FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, 0, pitch, volume, reverb); | ||||||
|         FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z); |         FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z); | ||||||
|         FAudioGMS_INTERNAL_SoundInstance_Play(instance); |         FAudioGMS_INTERNAL_SoundInstance_Play(instance); | ||||||
|     } |     } | ||||||
|  | @ -870,8 +1069,9 @@ double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, double pitch | ||||||
| 
 | 
 | ||||||
|     if (staticSound != NULL) |     if (staticSound != NULL) | ||||||
|     { |     { | ||||||
|         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound, pan, pitch, volume, reverb); |         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound); | ||||||
|         instance->loop = (uint8_t)loop; |         instance->loop = (uint8_t)loop; | ||||||
|  |         FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, pan, pitch, volume, reverb); | ||||||
|         FAudioGMS_INTERNAL_SoundInstance_Play(instance); |         FAudioGMS_INTERNAL_SoundInstance_Play(instance); | ||||||
|         return (double)instance->id; |         return (double)instance->id; | ||||||
|     } |     } | ||||||
|  | @ -888,8 +1088,9 @@ double FAudioGMS_StaticSound_PlaySpatial(double staticSoundID, double x, double | ||||||
| 
 | 
 | ||||||
|     if (staticSound != NULL) |     if (staticSound != NULL) | ||||||
|     { |     { | ||||||
|         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound, 0, pitch, volume, reverb); |         FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound); | ||||||
|         instance->loop = (uint8_t)loop; |         instance->loop = (uint8_t)loop; | ||||||
|  |         FAudioGMS_INTERNAL_SoundInstance_SetProperties(instance, 0, pitch, volume, reverb); | ||||||
|         FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z); |         FAudioGMS_INTERNAL_StaticSound_AddEmitter(instance, x, y, z); | ||||||
|         FAudioGMS_INTERNAL_SoundInstance_Play(instance); |         FAudioGMS_INTERNAL_SoundInstance_Play(instance); | ||||||
|         return (double)instance->id; |         return (double)instance->id; | ||||||
|  | @ -917,13 +1118,10 @@ void FAudioGMS_SoundInstance_Pause(double id) | ||||||
| 
 | 
 | ||||||
|     if (instance != NULL) |     if (instance != NULL) | ||||||
|     { |     { | ||||||
|         if (instance->isStatic) |         if (instance->soundState == SoundState_Playing) | ||||||
|         { |         { | ||||||
|             if (instance->soundState == SoundState_Playing) |             FAudioSourceVoice_Stop(instance->handle, 0, 0); | ||||||
|             { |             instance->soundState = SoundState_Paused; | ||||||
|                 FAudioSourceVoice_Stop(instance->handle, 0, 0); |  | ||||||
|                 instance->soundState = SoundState_Paused; |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|  | @ -932,16 +1130,16 @@ void FAudioGMS_SoundInstance_Pause(double id) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void FAudioGMS_SoundInstance_Stop(double id) | static void FAudioGMS_INTERNAL_SoundInstance_Stop(FAudioGMS_SoundInstance* instance) | ||||||
| { | { | ||||||
|     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); |  | ||||||
| 
 |  | ||||||
|     if (instance != NULL) |     if (instance != NULL) | ||||||
|     { |     { | ||||||
|         if (instance->isStatic) |         if (instance->isStatic) | ||||||
|         { |         { | ||||||
|             FAudioSourceVoice_ExitLoop(instance->handle, 0); |             FAudioSourceVoice_ExitLoop(instance->handle, 0); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         instance->soundState = SoundState_Stopped; | ||||||
|     } |     } | ||||||
|     else |     else | ||||||
|     { |     { | ||||||
|  | @ -949,6 +1147,38 @@ void FAudioGMS_SoundInstance_Stop(double id) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void FAudioGMS_SoundInstance_Stop(double id) | ||||||
|  | { | ||||||
|  |     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); | ||||||
|  |     FAudioGMS_INTERNAL_SoundInstance_Stop(instance); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void FAudioGMS_INTERNAL_SoundInstance_StopImmediate(FAudioGMS_SoundInstance* instance) | ||||||
|  | { | ||||||
|  |     if (instance != NULL) | ||||||
|  |     { | ||||||
|  |         FAudioSourceVoice_Stop(instance->handle, 0, 0); | ||||||
|  |         FAudioSourceVoice_FlushSourceBuffers(instance->handle); | ||||||
|  | 
 | ||||||
|  |         if (!instance->isStatic) | ||||||
|  |         { | ||||||
|  |             FAudioGMS_INTERNAL_SoundInstance_ClearBuffers(instance); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         instance->soundState = SoundState_Stopped; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         Log("SoundInstance_Stop: Invalid sound instance ID! Did you destroy this instance?"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void FAudioGMS_SoundInstance_StopImmediate(double id) | ||||||
|  | { | ||||||
|  |     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); | ||||||
|  |     FAudioGMS_INTERNAL_SoundInstance_StopImmediate(instance); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z) | void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z) | ||||||
| { | { | ||||||
|     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID); |     FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)soundInstanceID); | ||||||
|  | @ -982,6 +1212,72 @@ void FAudioGMS_SetListenerPosition(double x, double y, double z) | ||||||
|     device->listener.Position.z = z; |     device->listener.Position.z = z; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void FAudioGMS_INTERNAL_SoundInstance_Destroy(FAudioGMS_SoundInstance* instance) | ||||||
|  | { | ||||||
|  |     if (instance != NULL) | ||||||
|  |     { | ||||||
|  |         device->soundInstances[instance->id] = NULL; | ||||||
|  |         IdStack_Push(&device->soundInstanceIndexStack, instance->id); | ||||||
|  |         FAudioGMS_INTERNAL_SoundInstance_StopImmediate(instance); | ||||||
|  |         FAudioVoice_DestroyVoice(instance->handle); | ||||||
|  |         if (!instance->isStatic) | ||||||
|  |         { | ||||||
|  |             SDL_free(instance->soundData.streamingSound.bufferQueue.buffers); | ||||||
|  |             stb_vorbis_close(instance->soundData.streamingSound.fileHandle); | ||||||
|  |         } | ||||||
|  |         if (instance->is3D) | ||||||
|  |         { | ||||||
|  |             SDL_free(instance->emitter); | ||||||
|  |         } | ||||||
|  |         SDL_free(instance->dspSettings.pMatrixCoefficients); | ||||||
|  |         SDL_free(instance); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void FAudioGMS_SoundInstance_Destroy(double 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 = FAudioGMS_INTERNAL_LookupSoundInstance((uint32_t)id); | ||||||
|  | 
 | ||||||
|  |     if (instance != NULL) | ||||||
|  |     { | ||||||
|  |         instance->destroyOnFinish = 1; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* FIXME: this will die horribly if a sound is playing */ | ||||||
|  | static void FAudioGMS_INTERNAL_StaticSound_Destroy(FAudioGMS_StaticSound* sound) | ||||||
|  | { | ||||||
|  |     if (sound != NULL) | ||||||
|  |     { | ||||||
|  |         device->staticSounds[sound->id] = NULL; | ||||||
|  |         IdStack_Push(&device->staticSoundIndexStack, sound->id); | ||||||
|  |         SDL_free((void*)sound->buffer.pAudioData); | ||||||
|  |         SDL_free(sound); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void FAudioGMS_StaticSound_Destroy(double id) | ||||||
|  | { | ||||||
|  |     if (id >= 0 && id < device->staticSoundCount) | ||||||
|  |     { | ||||||
|  |         FAudioGMS_INTERNAL_StaticSound_Destroy(device->staticSounds[(uint32_t)id]); | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         Log("Invalid ID for destroy!"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void FAudioGMS_Update() | void FAudioGMS_Update() | ||||||
| { | { | ||||||
|     uint32_t i; |     uint32_t i; | ||||||
|  | @ -997,6 +1293,12 @@ void FAudioGMS_Update() | ||||||
|                 FAudioGMS_INTERNAL_Apply3D(instance); |                 FAudioGMS_INTERNAL_Apply3D(instance); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             /* Update streaming instance */ | ||||||
|  |             if (!instance->isStatic && instance->soundState == SoundState_Playing) | ||||||
|  |             { | ||||||
|  |                 FAudioGMS_INTERNAL_SoundInstance_StreamingUpdate(instance); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             if (instance->destroyOnFinish) |             if (instance->destroyOnFinish) | ||||||
|             { |             { | ||||||
|                 FAudioVoiceState state; |                 FAudioVoiceState state; | ||||||
|  |  | ||||||
|  | @ -48,9 +48,12 @@ FAUDIOGMSAPI double FAudioGMS_StaticSound_Play(double staticSoundID, double pan, | ||||||
| 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 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_StaticSound_Destroy(double id); | ||||||
| 
 | 
 | ||||||
|  | FAUDIOGMSAPI double FAudioGMS_StreamingSound_LoadOGG(char* filepath); /* returns a sound instance */ | ||||||
|  | 
 | ||||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_Play(double id); | FAUDIOGMSAPI void FAudioGMS_SoundInstance_Play(double id); | ||||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_Pause(double id); | FAUDIOGMSAPI void FAudioGMS_SoundInstance_Pause(double id); | ||||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_Stop(double id); | FAUDIOGMSAPI void FAudioGMS_SoundInstance_Stop(double id); | ||||||
|  | FAUDIOGMSAPI void FAudioGMS_SoundInstance_StopImmediate(double id); | ||||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z); | FAUDIOGMSAPI void FAudioGMS_SoundInstance_Set3DPosition(double soundInstanceID, double x, double y, double z); | ||||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_Destroy(double id); | FAUDIOGMSAPI void FAudioGMS_SoundInstance_Destroy(double id); | ||||||
| FAUDIOGMSAPI void FAudioGMS_SoundInstance_DestroyWhenFinished(double id); | FAUDIOGMSAPI void FAudioGMS_SoundInstance_DestroyWhenFinished(double id); | ||||||
|  |  | ||||||
|  | @ -57,6 +57,10 @@ | ||||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> |   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | ||||||
|     <RunCodeAnalysis>true</RunCodeAnalysis> |     <RunCodeAnalysis>true</RunCodeAnalysis> | ||||||
|     <EnableClangTidyCodeAnalysis>true</EnableClangTidyCodeAnalysis> |     <EnableClangTidyCodeAnalysis>true</EnableClangTidyCodeAnalysis> | ||||||
|  |     <IncludePath>../lib/SDL/include;../lib/FAudio/include;$(IncludePath)</IncludePath> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | ||||||
|  |     <IncludePath>../lib/FAudio/include;../lib/SDL/include;$(IncludePath)</IncludePath> | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
|   <PropertyGroup Label="Vcpkg"> |   <PropertyGroup Label="Vcpkg"> | ||||||
|     <VcpkgEnabled>false</VcpkgEnabled> |     <VcpkgEnabled>false</VcpkgEnabled> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue