From f449b135c2585e67d821b21f187f7bc760397634 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 22 Oct 2021 19:34:16 -0700 Subject: [PATCH] playing sound effects --- .gitmodules | 3 + lib/SDL | 1 + src/FAudioGMS.c | 540 +++++++++++++++++++++++++++++--------- src/FAudioGMS.h | 13 +- visualc/FAudioGMS.sln | 18 ++ visualc/FAudioGMS.vcxproj | 12 + 6 files changed, 462 insertions(+), 125 deletions(-) create mode 160000 lib/SDL diff --git a/.gitmodules b/.gitmodules index 46ad875..e151b21 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "FAudio"] path = lib/FAudio url = https://github.com/FNA-XNA/FAudio +[submodule "lib/SDL"] + path = lib/SDL + url = https://github.com/libsdl-org/SDL.git diff --git a/lib/SDL b/lib/SDL new file mode 160000 index 0000000..25f9ed8 --- /dev/null +++ b/lib/SDL @@ -0,0 +1 @@ +Subproject commit 25f9ed87ff6947d9576fc9d79dee0784e638ac58 diff --git a/src/FAudioGMS.c b/src/FAudioGMS.c index db6f1d3..9ce961e 100644 --- a/src/FAudioGMS.c +++ b/src/FAudioGMS.c @@ -24,6 +24,8 @@ * */ +#include "../lib/SDL/include/SDL.h" + #include "FAudioGMS.h" #include "../lib/FAudio/include/FAPOBase.h" #include "../lib/FAudio/include/FAudioFX.h" @@ -33,12 +35,11 @@ #define DR_WAV_IMPLEMENTATION #include "../lib/dr_wav.h" -#include #include static inline void Log(char *string) { - printf("%s", string); + printf("%s\n", string); fflush(stdout); } @@ -75,6 +76,19 @@ typedef struct FAudioGMS_SoundInstance float lowPassFilter; float highPassFilter; float bandPassFilter; + + uint8_t reverbAttached; + FAudioSubmixVoice* reverbVoice; + FAudioVoiceSends reverbSends; + + uint8_t isStatic; + uint8_t destroyOnFinish; + + union + { + FAudioGMS_StaticSound *staticSound; + /* TODO: streaming */ + } parent; } FAudioGMS_SoundInstance; typedef struct FAudioGMS_Device @@ -82,28 +96,26 @@ typedef struct FAudioGMS_Device FAudio* handle; FAudioDeviceDetails deviceDetails; FAudioMasteringVoice *masteringVoice; - FAudioSubmixVoice *reverbVoice; - FAudioVoiceSends reverbSends; FAudioGMS_StaticSound **staticSounds; uint32_t staticSoundCount; - FAudioGMS_SoundInstance **staticSoundInstances; - uint32_t staticSoundInstanceCount; + FAudioGMS_SoundInstance **soundInstances; + uint32_t soundInstanceCount; } FAudioGMS_Device; static FAudioGMS_Device *device = NULL; void FAudioGMS_Init() { - device = malloc(sizeof(FAudioGMS_Device)); + device = SDL_malloc(sizeof(FAudioGMS_Device)); uint32_t result = FAudioCreate(&device->handle, 0, FAUDIO_DEFAULT_PROCESSOR); if (result != 0) { Log("Failed to create device! Bailing!"); - free(device); + SDL_free(device); device = NULL; return; } @@ -117,7 +129,7 @@ void FAudioGMS_Init() { Log("No audio devices found! Bailing!"); FAudio_Release(device->handle); - free(device); + SDL_free(device); device = NULL; return; } @@ -162,96 +174,88 @@ void FAudioGMS_Init() { Log("No mastering voice found! Bailing!"); FAudio_Release(device->handle); - free(device); + SDL_free(device); device = NULL; return; } - /* Init reverb */ - - FAPO *reverb = malloc(sizeof(FAPO)); - - FAudioCreateReverb(&reverb, 0); - - FAudioEffectChain *reverbChain = malloc(sizeof(FAudioEffectChain)); - - reverbChain->EffectCount = 1; - reverbChain->pEffectDescriptors = 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, - &device->reverbVoice, - 1, /* omnidirectional reverb */ - device->deviceDetails.OutputFormat.Format.nSamplesPerSec, - 0, - 0, - NULL, - reverbChain); - - FAPOBase_Release((FAPOBase*)reverb); - free(reverb); - free(reverbChain->pEffectDescriptors); - free(reverbChain); - - FAudioFXReverbParameters *reverbParams = 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( - device->reverbVoice, - 0, - reverbParams, - sizeof(FAudioFXReverbParameters), - 0); - - free(reverbParams); - - /* Init reverb sends */ - - device->reverbSends.SendCount = 2; - device->reverbSends.pSends = malloc(2 * sizeof(FAudioSendDescriptor)); - - device->reverbSends.pSends[0].Flags = 0; - device->reverbSends.pSends[0].pOutputVoice = device->masteringVoice; - device->reverbSends.pSends[1].Flags = 0; - device->reverbSends.pSends[1].pOutputVoice = device->reverbVoice; - device->staticSounds = NULL; device->staticSoundCount = 0; + device->soundInstances = NULL; + device->soundInstanceCount = 0; + Log("FAudio initialized successfully!"); + printf("Device: %ls", device->deviceDetails.DisplayName); + fflush(stdout); +} + +static void FAudioGMS_INTERNAL_SoundInstance_Destroy(FAudioGMS_SoundInstance* instance) +{ + if (instance != NULL) + { + device->soundInstances[instance->id] = NULL; + FAudioSourceVoice_Stop(instance->handle, 0, 0); + FAudioSourceVoice_FlushSourceBuffers(instance->handle); + FAudioVoice_DestroyVoice(instance->handle); + SDL_free(instance->dspSettings.pMatrixCoefficients); + SDL_free(instance); + } +} + +void FAudioGMS_SoundInstance_Destroy(double id) +{ + FAudioGMS_INTERNAL_SoundInstance_Destroy(device->soundInstances[(uint32_t)id]); +} + +void FAudioGMS_SoundInstance_DestroyWhenFinished(double id) +{ + FAudioGMS_SoundInstance *instance = device->soundInstances[(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; + SDL_free((void*)sound->buffer.pAudioData); + SDL_free(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) + { + 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); + } + } + } + } } /* Taken from https://github.com/FNA-XNA/FNA/blob/master/src/Audio/SoundEffectInstance.cs */ @@ -313,7 +317,7 @@ double FAudioGMS_StaticSound_LoadWAV(char *filePath) { drwav_uint64 frameCount; - FAudioGMS_StaticSound *sound = malloc(sizeof(FAudioGMS_StaticSound)); + FAudioGMS_StaticSound *sound = SDL_malloc(sizeof(FAudioGMS_StaticSound)); float *pSampleData = drwav_open_file_and_read_pcm_frames_f32(filePath, &sound->channels, &sound->samplesPerSecond, &frameCount, NULL); if (pSampleData == NULL) { @@ -337,19 +341,210 @@ double FAudioGMS_StaticSound_LoadWAV(char *filePath) /* FIXME: id re-use system */ sound->id = device->staticSoundCount; - device->staticSounds = realloc(device->staticSounds, (device->staticSoundCount + 1) * sizeof(FAudioGMS_StaticSound*)); + device->staticSounds = SDL_realloc(device->staticSounds, (device->staticSoundCount + 1) * sizeof(FAudioGMS_StaticSound*)); device->staticSounds[device->staticSoundCount] = sound; device->staticSoundCount += 1; return (double)sound->id; } -double FAudioGMS_SoundInstance_CreateFromStaticSound(double id) +static void FAudioGMS_INTERNAL_SoundInstance_AttachReverb(FAudioGMS_SoundInstance* instance) { - FAudioGMS_StaticSound *staticSound = device->staticSounds[(uint32_t)id]; - FAudioGMS_SoundInstance *instance = malloc(sizeof(FAudioGMS_SoundInstance)); + 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; + p.Type = FAudioLowPassFilter; + p.Frequency = lowPassFilter; + p.OneOverQ = 1.0f; + + FAudioVoice_SetFilterParameters(instance->handle, &p, 0); + + instance->lowPassFilter = lowPassFilter; +} + +static void FAudioGMS_INTERNAL_SoundInstance_SetHighPassFilter(FAudioGMS_SoundInstance* instance, float highPassFilter) +{ + FAudioFilterParameters p; + p.Type = FAudioHighPassFilter; + p.Frequency = highPassFilter; + p.OneOverQ = 1.0f; + + FAudioVoice_SetFilterParameters(instance->handle, &p, 0); + + instance->highPassFilter = highPassFilter; +} + +static void FAudioGMS_INTERNAL_SoundInstance_SetBandPassFilter(FAudioGMS_SoundInstance* instance, float bandPassFilter) +{ + FAudioFilterParameters p; + p.Type = FAudioBandPassFilter; + p.Frequency = bandPassFilter; + p.OneOverQ = 1.0f; + + FAudioVoice_SetFilterParameters(instance->handle, &p, 0); + + instance->bandPassFilter = bandPassFilter; +} + +static void FAudioGMS_INTERNAL_SoundInstance_SetPan(FAudioGMS_SoundInstance* instance, float pan) +{ + instance->pan = pan; + SetPanMatrixCoefficients(instance); + + FAudioVoice_SetOutputMatrix( + instance->handle, + device->masteringVoice, + instance->dspSettings.SrcChannelCount, + instance->dspSettings.DstChannelCount, + instance->dspSettings.pMatrixCoefficients, + 0 + ); +} + +static void FAudioGMS_INTERNAL_SoundInstance_SetPitch(FAudioGMS_SoundInstance* instance, float pitch) +{ + instance->pitch = pitch; + + pitch -= 1.0; /* default pitch is 1.0 as per GM standard */ + pitch = SDL_max(-1.0, SDL_min(1.0, pitch)); + + FAudioSourceVoice_SetFrequencyRatio( + instance->handle, + SDL_powf(2.0f, pitch), + 0 + ); +} + +static void FAudioGMS_INTERNAL_SoundInstance_SetVolume(FAudioGMS_SoundInstance* instance, float volume) +{ + FAudioVoice_SetVolume(instance->handle, volume, 0); +} + +static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound( + FAudioGMS_StaticSound *staticSound, + double pan, + double pitch, + double volume, + double reverb +) { + FAudioGMS_SoundInstance *instance = SDL_malloc(sizeof(FAudioGMS_SoundInstance)); instance->handle = NULL; + instance->parent.staticSound = staticSound; + instance->isStatic = 1; + instance->loop = 0; + instance->destroyOnFinish = 0; + instance->format.wFormatTag = 3; instance->format.wBitsPerSample = 32; instance->format.nChannels = staticSound->channels; @@ -370,8 +565,8 @@ double FAudioGMS_SoundInstance_CreateFromStaticSound(double id) if (instance->handle == NULL) { Log("SoundInstance failed to initialize!"); - free(instance); - return -1; + SDL_free(instance); + return NULL; } instance->dspSettings.DopplerFactor = 1.0f; @@ -379,55 +574,162 @@ double FAudioGMS_SoundInstance_CreateFromStaticSound(double id) instance->dspSettings.DstChannelCount = device->deviceDetails.OutputFormat.Format.nChannels; uint32_t memsize = 4 * instance->dspSettings.SrcChannelCount * instance->dspSettings.DstChannelCount; - instance->dspSettings.pMatrixCoefficients = malloc(memsize); - memset(instance->dspSettings.pMatrixCoefficients, 0, memsize); + instance->dspSettings.pMatrixCoefficients = SDL_malloc(memsize); + SDL_memset(instance->dspSettings.pMatrixCoefficients, 0, memsize); - SetPanMatrixCoefficients(instance); + FAudioGMS_INTERNAL_SoundInstance_SetPan(instance, pan); + FAudioGMS_INTERNAL_SoundInstance_SetPitch(instance, pitch); + FAudioGMS_INTERNAL_SoundInstance_SetVolume(instance, volume); - FAudioVoice_SetOutputVoices( - instance->handle, - &device->reverbSends); + instance->reverbAttached = 0; + instance->reverb = 0.0f; + instance->lowPassFilter = 0.0f; + instance->highPassFilter = 0.0f; + instance->bandPassFilter = 0.0f; + + if (reverb > 0.0f) + { + FAudioGMS_INTERNAL_SoundInstance_SetReverb(instance, reverb); + } instance->soundState = SoundState_Stopped; /* FIXME: id re-use system */ - instance->id = device->staticSoundInstanceCount; + instance->id = device->soundInstanceCount; - device->staticSoundInstances = realloc(device->staticSoundInstances, (device->staticSoundCount + 1) * sizeof(FAudioGMS_SoundInstance*)); - device->staticSoundInstances[device->staticSoundInstanceCount] = instance; - device->staticSoundInstanceCount += 1; + device->soundInstances = SDL_realloc(device->soundInstances, (device->soundInstanceCount + 1) * sizeof(FAudioGMS_SoundInstance*)); + device->soundInstances[device->soundInstanceCount] = instance; + device->soundInstanceCount += 1; - return (double)instance->id; + return instance; } -void FAudioGMS_SoundInstance_Destroy(double id) +static void FAudioGMS_INTERNAL_SoundInstance_Play(FAudioGMS_SoundInstance* instance) { - FAudioGMS_SoundInstance *instance = device->staticSoundInstances[(uint32_t)id]; - - if (instance != NULL) + if (instance->isStatic) { - FAudioVoice_DestroyVoice(instance->handle); - free(instance->dspSettings.pMatrixCoefficients); - free(instance); - device->staticSoundInstances[(uint32_t)id] = NULL; + if (instance->soundState == SoundState_Playing) + { + return; + } + + if (instance->loop) + { + instance->parent.staticSound->buffer.LoopCount = FAUDIO_LOOP_INFINITE; + instance->parent.staticSound->buffer.LoopBegin = instance->parent.staticSound->loopStart; + instance->parent.staticSound->buffer.LoopLength = instance->parent.staticSound->loopLength; + } + else + { + instance->parent.staticSound->buffer.LoopCount = 0; + instance->parent.staticSound->buffer.LoopBegin = 0; + instance->parent.staticSound->buffer.LoopLength = 0; + } + + FAudioSourceVoice_SubmitSourceBuffer(instance->handle, &instance->parent.staticSound->buffer, NULL); + FAudioSourceVoice_Start(instance->handle, 0, 0); + instance->soundState = SoundState_Playing; } } -void FAudioGMS_StaticSound_Destroy(double id) +void FAudioGMS_StaticSound_PlayOneOff(double staticSoundID, double pan, double pitch, double volume, double reverb) { - FAudioGMS_StaticSound *sound = device->staticSounds[(uint32_t)id]; + FAudioGMS_StaticSound* staticSound = device->staticSounds[(uint32_t)staticSoundID]; - if (sound != NULL) + if (staticSound != NULL) { - free((void*)sound->buffer.pAudioData); - free(sound); - device->staticSounds[(uint32_t)id] = NULL; + FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound, pan, pitch, volume, reverb); + instance->destroyOnFinish = 1; + FAudioGMS_INTERNAL_SoundInstance_Play(instance); + } + else + { + Log("StaticSound_PlayOneOff: 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]; + + if (staticSound != NULL) + { + FAudioGMS_SoundInstance* instance = FAudioGMS_INTERNAL_SoundInstance_CreateFromStaticSound(staticSound, pan, pitch, volume, reverb); + instance->loop = (uint8_t)loop; + FAudioGMS_INTERNAL_SoundInstance_Play(instance); + return (double)instance->id; + } + else + { + Log("StaticSound_Play: 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]; + + if (instance != NULL) + { + FAudioGMS_INTERNAL_SoundInstance_Play(instance); + } +} + +void FAudioGMS_SoundInstance_Pause(double id) +{ + FAudioGMS_SoundInstance* instance = device->soundInstances[(uint32_t)id]; + + if (instance != NULL) + { + if (instance->isStatic) + { + if (instance->soundState == SoundState_Playing) + { + FAudioSourceVoice_Stop(instance->handle, 0, 0); + instance->soundState = SoundState_Paused; + } + } + } + else + { + Log("SoundInstance_Pause: Invalid sound instance ID! Did you destroy this instance?"); + } +} + +void FAudioGMS_SoundInstance_Stop(double id) +{ + FAudioGMS_SoundInstance* instance = device->soundInstances[(uint32_t)id]; + + if (instance != NULL) + { + if (instance->isStatic) + { + FAudioSourceVoice_ExitLoop(instance->handle, 0); + } + } + else + { + Log("SoundInstance_Stop: Invalid sound instance ID! Did you destroy this 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]); + } + FAudio_Release(device->handle); - free(device); + SDL_free(device); device = NULL; + + Log("FAudio cleaned up successfully!"); } diff --git a/src/FAudioGMS.h b/src/FAudioGMS.h index 1cb8427..9fedcda 100644 --- a/src/FAudioGMS.h +++ b/src/FAudioGMS.h @@ -27,10 +27,6 @@ #ifndef FAUDIOGMS_H #define FAUDIOGMS_H -#include -#include -#include - #ifdef _WIN32 #define FAUDIOGMSAPI __declspec(dllexport) #define FAUDIOGMSCALL __cdecl @@ -46,11 +42,16 @@ extern "C" { FAUDIOGMSAPI void FAudioGMS_Init(); FAUDIOGMSAPI void FAudioGMS_Update(); -FAUDIOGMSAPI double FAudioGMS_StaticSound_LoadWAV(char *filePath); +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 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_SoundInstance_CreateFromStaticSound(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_Destroy(double id); +FAUDIOGMSAPI void FAudioGMS_SoundInstance_DestroyWhenFinished(double id); FAUDIOGMSAPI void FAudioGMS_StaticSound_Destroy(double id); FAUDIOGMSAPI void FAudioGMS_Destroy(); diff --git a/visualc/FAudioGMS.sln b/visualc/FAudioGMS.sln index 5ff8c05..eb33c39 100644 --- a/visualc/FAudioGMS.sln +++ b/visualc/FAudioGMS.sln @@ -9,6 +9,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FAudioGMS", "FAudioGMS.vcxp EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FAudio", "..\lib\FAudio\visualc\FAudio.vcxproj", "{90A103EF-E403-47D4-BBBB-0F206B9FA7F2}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDL2", "..\lib\SDL\VisualC\SDL\SDL.vcxproj", "{81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -53,6 +55,22 @@ Global {90A103EF-E403-47D4-BBBB-0F206B9FA7F2}.RelWithDebInfo|x64.Build.0 = Release|x64 {90A103EF-E403-47D4-BBBB-0F206B9FA7F2}.RelWithDebInfo|x86.ActiveCfg = Release|Win32 {90A103EF-E403-47D4-BBBB-0F206B9FA7F2}.RelWithDebInfo|x86.Build.0 = Release|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.ActiveCfg = Debug|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x64.Build.0 = Debug|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x86.ActiveCfg = Debug|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Debug|x86.Build.0 = Debug|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.MinSizeRel|x64.ActiveCfg = Debug|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.MinSizeRel|x64.Build.0 = Debug|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.MinSizeRel|x86.ActiveCfg = Debug|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.MinSizeRel|x86.Build.0 = Debug|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.ActiveCfg = Release|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x64.Build.0 = Release|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x86.ActiveCfg = Release|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.Release|x86.Build.0 = Release|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.RelWithDebInfo|x64.ActiveCfg = Release|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.RelWithDebInfo|x64.Build.0 = Release|x64 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.RelWithDebInfo|x86.ActiveCfg = Release|Win32 + {81CE8DAF-EBB2-4761-8E45-B71ABCCA8C68}.RelWithDebInfo|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/visualc/FAudioGMS.vcxproj b/visualc/FAudioGMS.vcxproj index 47bb094..63a0fea 100644 --- a/visualc/FAudioGMS.vcxproj +++ b/visualc/FAudioGMS.vcxproj @@ -68,10 +68,18 @@ Level3 Disabled Default + MultiThreadedDebugDLL + true + $(OutDir) DebugFull + NotSet + SetupAPI.lib;Version.lib;Winmm.lib;Imm32.lib;libucrt.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + false + @@ -83,6 +91,7 @@ true true + SetupAPI.lib;Version.lib;Winmm.lib;Imm32.lib;libucrt.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) @@ -95,6 +104,9 @@ {90a103ef-e403-47d4-bbbb-0f206b9fa7f2} + + {81ce8daf-ebb2-4761-8e45-b71abcca8c68} +