From 4a3d2e25d4130df1f30504419f5ce11390414b93 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Tue, 14 Dec 2021 19:57:45 -0800 Subject: [PATCH] load OGG into memory to avoid disk bottleneck --- gamemaker/extensions/FAudioGMS/FAudioGMS.dll | 2 +- src/FAudioGMS.c | 42 ++++++++++++-------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/gamemaker/extensions/FAudioGMS/FAudioGMS.dll b/gamemaker/extensions/FAudioGMS/FAudioGMS.dll index 2afdb95..e3bc0f0 100644 --- a/gamemaker/extensions/FAudioGMS/FAudioGMS.dll +++ b/gamemaker/extensions/FAudioGMS/FAudioGMS.dll @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0ec97d81ca716b4d2ccb36f45fbdda5acc529ae89fd3b2d54f9285b9bb7ee2a1 +oid sha256:21c45d674003ac89a5227f8984941cbd26d358f7b089b21c5bdbe75442491acc size 1522176 diff --git a/src/FAudioGMS.c b/src/FAudioGMS.c index 669c754..80cfd06 100644 --- a/src/FAudioGMS.c +++ b/src/FAudioGMS.c @@ -180,7 +180,8 @@ typedef struct FAudioGMS_StaticSound typedef struct FAudioGMS_StreamingSound { - stb_vorbis *fileHandle; + stb_vorbis *vorbisHandle; + void *vorbisData; stb_vorbis_info info; float *streamBuffer[STREAMING_BUFFER_COUNT]; uint32_t streamBufferSize; @@ -357,7 +358,7 @@ static void FAudioGMS_INTERNAL_OnBufferEndCallback( instance->soundData.streamingSound.mostRecentSampleOffset %= instance->playLength; - if (stb_vorbis_get_sample_offset(instance->soundData.streamingSound.fileHandle) >= stb_vorbis_stream_length_in_samples(instance->soundData.streamingSound.fileHandle)) + if (stb_vorbis_get_sample_offset(instance->soundData.streamingSound.vorbisHandle) >= stb_vorbis_stream_length_in_samples(instance->soundData.streamingSound.vorbisHandle)) { FAudioGMS_INTERNAL_SoundInstance_Stop(instance); } @@ -1004,13 +1005,13 @@ static void FAudioGMS_INTERNAL_SoundInstance_AddBuffers(FAudioGMS_SoundInstance { uint32_t distanceToEndPoint = (instance->playBegin + instance->playLength) - - stb_vorbis_get_sample_offset(instance->soundData.streamingSound.fileHandle); + stb_vorbis_get_sample_offset(instance->soundData.streamingSound.vorbisHandle); requestedSampleCount = SDL_min(requestedSampleCount, distanceToEndPoint); } /* NOTE: this function returns samples per channel, not total samples */ uint32_t sampleCount = stb_vorbis_get_samples_float_interleaved( - instance->soundData.streamingSound.fileHandle, + instance->soundData.streamingSound.vorbisHandle, instance->format.nChannels, instance->soundData.streamingSound .streamBuffer[instance->soundData.streamingSound.nextStreamBufferIndex], @@ -1020,10 +1021,10 @@ static void FAudioGMS_INTERNAL_SoundInstance_AddBuffers(FAudioGMS_SoundInstance if (instance->loop && sampleCount < defaultRequestedSampleCount) { uint32_t fillInSampleCount = defaultRequestedSampleCount - sampleCount; - stb_vorbis_seek(instance->soundData.streamingSound.fileHandle, instance->playBegin); + stb_vorbis_seek(instance->soundData.streamingSound.vorbisHandle, instance->playBegin); uint32_t remainingSampleCount = stb_vorbis_get_samples_float_interleaved( - instance->soundData.streamingSound.fileHandle, + instance->soundData.streamingSound.vorbisHandle, instance->format.nChannels, &instance->soundData.streamingSound .streamBuffer[instance->soundData.streamingSound.nextStreamBufferIndex][sampleCount * instance->format.nChannels], @@ -1060,7 +1061,12 @@ double FAudioGMS_StreamingSound_LoadOGG(char *filePath, double bufferSizeInBytes uint32_t i; int error = 0; uint32_t bufferSizeInBytesInt = (uint32_t)bufferSizeInBytes; - stb_vorbis *fileHandle = stb_vorbis_open_filename(filePath, &error, NULL); + + /* load entire vorbis file into memory first */ + size_t vorbisSize; + void *vorbisData = SDL_LoadFile(filePath, &vorbisSize); + + stb_vorbis *vorbisHandle = stb_vorbis_open_memory(vorbisData, (int)vorbisSize, &error, NULL); if (error != 0) { @@ -1074,12 +1080,13 @@ double FAudioGMS_StreamingSound_LoadOGG(char *filePath, double bufferSizeInBytes bufferSizeInBytesInt = DEFAULT_STREAMING_BUFFER_SIZE; /* A reasonable default! */ } - stb_vorbis_info info = stb_vorbis_get_info(fileHandle); + stb_vorbis_info info = stb_vorbis_get_info(vorbisHandle); FAudioGMS_SoundInstance *instance = FAudioGMS_INTERNAL_SoundInstance_Init(info.channels, info.sample_rate, 32, 0); - instance->soundData.streamingSound.fileHandle = fileHandle; + instance->soundData.streamingSound.vorbisData = vorbisData; + instance->soundData.streamingSound.vorbisHandle = vorbisHandle; instance->soundData.streamingSound.info = info; for (i = 0; i < STREAMING_BUFFER_COUNT; i += 1) { @@ -1091,7 +1098,7 @@ double FAudioGMS_StreamingSound_LoadOGG(char *filePath, double bufferSizeInBytes instance->soundData.streamingSound.nextStreamBufferIndex = 0; instance->soundData.streamingSound.buffersLoadedCount = 0; - instance->playLength = stb_vorbis_stream_length_in_samples(fileHandle); + instance->playLength = stb_vorbis_stream_length_in_samples(vorbisHandle); return instance->id; } @@ -1206,7 +1213,7 @@ void FAudioGMS_SoundInstance_Play(double soundInstanceID) } } -FAUDIOGMSAPI void FAudioGMS_SoundInstance_QueueSyncPlay(double soundInstanceID) +FAUDIOGMSAPI void FAudioGMS_SoundInstance_QueueSyncPlay(double soundInstanceID) { RETURN_ON_NULL_DEVICE_VOID FAudioGMS_SoundInstance *instance = @@ -1218,7 +1225,7 @@ FAUDIOGMSAPI void FAudioGMS_SoundInstance_QueueSyncPlay(double soundInstanceID) } } -void FAudioGMS_SoundInstance_SyncPlay() +void FAudioGMS_SoundInstance_SyncPlay() { RETURN_ON_NULL_DEVICE_VOID FAudio_CommitOperationSet(device->handle, 1); @@ -1268,7 +1275,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_Stop(FAudioGMS_SoundInstance *insta instance->soundData.streamingSound.buffersLoadedCount = 0; stb_vorbis_seek( - instance->soundData.streamingSound.fileHandle, + instance->soundData.streamingSound.vorbisHandle, instance->playBegin); /* back to the start */ } } @@ -1449,7 +1456,7 @@ void FAudioGMS_SoundInstance_SetTrackPositionInSeconds( else { instance->soundData.streamingSound.buffersLoadedCount = 0; - stb_vorbis_seek(instance->soundData.streamingSound.fileHandle, sampleFrame); + stb_vorbis_seek(instance->soundData.streamingSound.vorbisHandle, sampleFrame); FAudioGMS_INTERNAL_SoundInstance_AddBuffers(instance); } @@ -1521,7 +1528,7 @@ void FAudioGMS_SoundInstance_SetPlayRegion( { FAudioSourceVoice_FlushSourceBuffers(instance->voice.handle); instance->soundData.streamingSound.buffersLoadedCount = 0; - stb_vorbis_seek(instance->soundData.streamingSound.fileHandle, instance->playBegin); + stb_vorbis_seek(instance->soundData.streamingSound.vorbisHandle, instance->playBegin); FAudioGMS_INTERNAL_SoundInstance_AddBuffers(instance); } } @@ -1604,7 +1611,7 @@ double FAudioGMS_SoundInstance_GetTrackLengthInSeconds(double soundInstanceID) else { return stb_vorbis_stream_length_in_seconds( - instance->soundData.streamingSound.fileHandle); + instance->soundData.streamingSound.vorbisHandle); } } else @@ -1685,7 +1692,8 @@ void FAudioGMS_SetListenerOrientation( { SDL_free(instance->soundData.streamingSound.streamBuffer[i]); } - stb_vorbis_close(instance->soundData.streamingSound.fileHandle); + stb_vorbis_close(instance->soundData.streamingSound.vorbisHandle); + SDL_free(instance->soundData.streamingSound.vorbisData); } if (instance->is3D) {