diff --git a/src/FAudioGMS.c b/src/FAudioGMS.c index f4c4efc..78377c4 100644 --- a/src/FAudioGMS.c +++ b/src/FAudioGMS.c @@ -164,6 +164,8 @@ typedef struct FAudioGMS_StreamingSound { stb_vorbis* fileHandle; stb_vorbis_info info; + float* streamBuffer; + uint32_t streamBufferSize; } FAudioGMS_StreamingSound; typedef struct FAudioGMS_SoundInstance @@ -226,8 +228,6 @@ typedef struct FAudioGMS_EffectChain static const float SPEED_OF_SOUND = 343.5f; static const float DOPPLER_SCALE = 1.0f; -#define STREAMING_BUFFER_SIZE 1024 * 16 * sizeof(float) /* FIXME: what should this value be? */ - typedef struct FAudioGMS_Device { FAudio* handle; @@ -253,7 +253,6 @@ typedef struct FAudioGMS_Device uint32_t effectChainCount; IdStack effectChainIndexStack; - float streamStagingBuffer[STREAMING_BUFFER_SIZE]; double timestep; } FAudioGMS_Device; @@ -788,30 +787,33 @@ static FAudioGMS_SoundInstance* FAudioGMS_INTERNAL_SoundInstance_CreateFromStati static void FAudioGMS_INTERNAL_SoundInstance_AddBuffer(FAudioGMS_SoundInstance* instance) { + uint32_t requestedSampleCount = instance->format.nSamplesPerSec / 4; + + uint32_t requiredStagingBufferSize = requestedSampleCount * instance->format.nChannels * sizeof(float); + if (instance->soundData.streamingSound.streamBufferSize < requiredStagingBufferSize) + { + instance->soundData.streamingSound.streamBuffer = SDL_realloc(instance->soundData.streamingSound.streamBuffer, requiredStagingBufferSize); + } + /* NOTE: this function returns samples per channel, not total samples */ - uint32_t samples = stb_vorbis_get_samples_float_interleaved( + uint32_t sampleCount = stb_vorbis_get_samples_float_interleaved( instance->soundData.streamingSound.fileHandle, instance->format.nChannels, - device->streamStagingBuffer, - STREAMING_BUFFER_SIZE + instance->soundData.streamingSound.streamBuffer, + requestedSampleCount * instance->format.nChannels ); - 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); - FAudioBuffer buffer; - buffer.AudioBytes = bufferLength; - buffer.pAudioData = nextBuffer; - buffer.PlayLength = - bufferLength / - instance->format.nChannels / - (instance->format.wBitsPerSample / 8); + buffer.AudioBytes = sampleCount * instance->format.nChannels * sizeof(float); + buffer.pAudioData = (uint8_t*) instance->soundData.streamingSound.streamBuffer; buffer.PlayBegin = 0; + buffer.PlayLength = sampleCount; buffer.Flags = 0; + /*(sampleCount < instance->soundData.streamingSound.info.sample_rate) ? + FAUDIO_END_OF_STREAM : + 0; + */ buffer.LoopBegin = 0; buffer.LoopCount = 0; buffer.LoopLength = 0; @@ -820,7 +822,8 @@ static void FAudioGMS_INTERNAL_SoundInstance_AddBuffer(FAudioGMS_SoundInstance* FAudioSourceVoice_SubmitSourceBuffer(instance->handle, &buffer, NULL); /* We have reached the end of the file! */ - if (sampleCount < STREAMING_BUFFER_SIZE) + /* FIXME: maybe move this to a OnStreamEnd callback? */ + if (sampleCount < requestedSampleCount) { if (instance->loop) { @@ -856,6 +859,8 @@ double FAudioGMS_StreamingSound_LoadOGG(char* filePath) instance->soundData.streamingSound.fileHandle = fileHandle; instance->soundData.streamingSound.info = info; + instance->soundData.streamingSound.streamBuffer = NULL; + instance->soundData.streamingSound.streamBufferSize = 0; FAudioGMS_INTERNAL_SoundInstance_AddBuffer(instance); @@ -1247,6 +1252,7 @@ static void FAudioGMS_INTERNAL_SoundInstance_Destroy(FAudioGMS_SoundInstance* in FAudioVoice_DestroyVoice(instance->handle); if (!instance->isStatic) { + SDL_free(instance->soundData.streamingSound.streamBuffer); stb_vorbis_close(instance->soundData.streamingSound.fileHandle); } if (instance->is3D)