load OGG into memory to avoid disk bottleneck

main
cosmonaut 2021-12-14 19:57:45 -08:00
parent 30cb6959e0
commit 4a3d2e25d4
2 changed files with 26 additions and 18 deletions

Binary file not shown.

View File

@ -180,7 +180,8 @@ typedef struct FAudioGMS_StaticSound
typedef struct FAudioGMS_StreamingSound typedef struct FAudioGMS_StreamingSound
{ {
stb_vorbis *fileHandle; stb_vorbis *vorbisHandle;
void *vorbisData;
stb_vorbis_info info; stb_vorbis_info info;
float *streamBuffer[STREAMING_BUFFER_COUNT]; float *streamBuffer[STREAMING_BUFFER_COUNT];
uint32_t streamBufferSize; uint32_t streamBufferSize;
@ -357,7 +358,7 @@ static void FAudioGMS_INTERNAL_OnBufferEndCallback(
instance->soundData.streamingSound.mostRecentSampleOffset %= instance->playLength; 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); FAudioGMS_INTERNAL_SoundInstance_Stop(instance);
} }
@ -1004,13 +1005,13 @@ static void FAudioGMS_INTERNAL_SoundInstance_AddBuffers(FAudioGMS_SoundInstance
{ {
uint32_t distanceToEndPoint = uint32_t distanceToEndPoint =
(instance->playBegin + instance->playLength) - (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); requestedSampleCount = SDL_min(requestedSampleCount, distanceToEndPoint);
} }
/* NOTE: this function returns samples per channel, not total samples */ /* NOTE: this function returns samples per channel, not total samples */
uint32_t sampleCount = stb_vorbis_get_samples_float_interleaved( uint32_t sampleCount = stb_vorbis_get_samples_float_interleaved(
instance->soundData.streamingSound.fileHandle, instance->soundData.streamingSound.vorbisHandle,
instance->format.nChannels, instance->format.nChannels,
instance->soundData.streamingSound instance->soundData.streamingSound
.streamBuffer[instance->soundData.streamingSound.nextStreamBufferIndex], .streamBuffer[instance->soundData.streamingSound.nextStreamBufferIndex],
@ -1020,10 +1021,10 @@ static void FAudioGMS_INTERNAL_SoundInstance_AddBuffers(FAudioGMS_SoundInstance
if (instance->loop && sampleCount < defaultRequestedSampleCount) if (instance->loop && sampleCount < defaultRequestedSampleCount)
{ {
uint32_t fillInSampleCount = defaultRequestedSampleCount - sampleCount; 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( uint32_t remainingSampleCount = stb_vorbis_get_samples_float_interleaved(
instance->soundData.streamingSound.fileHandle, instance->soundData.streamingSound.vorbisHandle,
instance->format.nChannels, instance->format.nChannels,
&instance->soundData.streamingSound &instance->soundData.streamingSound
.streamBuffer[instance->soundData.streamingSound.nextStreamBufferIndex][sampleCount * instance->format.nChannels], .streamBuffer[instance->soundData.streamingSound.nextStreamBufferIndex][sampleCount * instance->format.nChannels],
@ -1060,7 +1061,12 @@ double FAudioGMS_StreamingSound_LoadOGG(char *filePath, double bufferSizeInBytes
uint32_t i; uint32_t i;
int error = 0; int error = 0;
uint32_t bufferSizeInBytesInt = (uint32_t)bufferSizeInBytes; 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) if (error != 0)
{ {
@ -1074,12 +1080,13 @@ double FAudioGMS_StreamingSound_LoadOGG(char *filePath, double bufferSizeInBytes
bufferSizeInBytesInt = DEFAULT_STREAMING_BUFFER_SIZE; /* A reasonable default! */ 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_SoundInstance *instance =
FAudioGMS_INTERNAL_SoundInstance_Init(info.channels, info.sample_rate, 32, 0); 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; instance->soundData.streamingSound.info = info;
for (i = 0; i < STREAMING_BUFFER_COUNT; i += 1) 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.nextStreamBufferIndex = 0;
instance->soundData.streamingSound.buffersLoadedCount = 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; 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 RETURN_ON_NULL_DEVICE_VOID
FAudioGMS_SoundInstance *instance = 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 RETURN_ON_NULL_DEVICE_VOID
FAudio_CommitOperationSet(device->handle, 1); FAudio_CommitOperationSet(device->handle, 1);
@ -1268,7 +1275,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_Stop(FAudioGMS_SoundInstance *insta
instance->soundData.streamingSound.buffersLoadedCount = 0; instance->soundData.streamingSound.buffersLoadedCount = 0;
stb_vorbis_seek( stb_vorbis_seek(
instance->soundData.streamingSound.fileHandle, instance->soundData.streamingSound.vorbisHandle,
instance->playBegin); /* back to the start */ instance->playBegin); /* back to the start */
} }
} }
@ -1449,7 +1456,7 @@ void FAudioGMS_SoundInstance_SetTrackPositionInSeconds(
else else
{ {
instance->soundData.streamingSound.buffersLoadedCount = 0; 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); FAudioGMS_INTERNAL_SoundInstance_AddBuffers(instance);
} }
@ -1521,7 +1528,7 @@ void FAudioGMS_SoundInstance_SetPlayRegion(
{ {
FAudioSourceVoice_FlushSourceBuffers(instance->voice.handle); FAudioSourceVoice_FlushSourceBuffers(instance->voice.handle);
instance->soundData.streamingSound.buffersLoadedCount = 0; 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); FAudioGMS_INTERNAL_SoundInstance_AddBuffers(instance);
} }
} }
@ -1604,7 +1611,7 @@ double FAudioGMS_SoundInstance_GetTrackLengthInSeconds(double soundInstanceID)
else else
{ {
return stb_vorbis_stream_length_in_seconds( return stb_vorbis_stream_length_in_seconds(
instance->soundData.streamingSound.fileHandle); instance->soundData.streamingSound.vorbisHandle);
} }
} }
else else
@ -1685,7 +1692,8 @@ void FAudioGMS_SetListenerOrientation(
{ {
SDL_free(instance->soundData.streamingSound.streamBuffer[i]); 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) if (instance->is3D)
{ {