forked from MoonsideGames/FAudioGMS
tweak stream loop behavior
parent
e12914177f
commit
d3708f5e16
|
@ -175,7 +175,7 @@ typedef struct FAudioGMS_StaticSound
|
||||||
} FAudioGMS_StaticSound;
|
} FAudioGMS_StaticSound;
|
||||||
|
|
||||||
/* if we don't triple buffer, we'll microstutter the voice while waiting for decode */
|
/* if we don't triple buffer, we'll microstutter the voice while waiting for decode */
|
||||||
#define STREAMING_BUFFER_COUNT 3
|
#define STREAMING_BUFFER_COUNT 3
|
||||||
#define DEFAULT_STREAMING_BUFFER_SIZE 32768
|
#define DEFAULT_STREAMING_BUFFER_SIZE 32768
|
||||||
|
|
||||||
typedef struct FAudioGMS_StreamingSound
|
typedef struct FAudioGMS_StreamingSound
|
||||||
|
@ -187,7 +187,6 @@ typedef struct FAudioGMS_StreamingSound
|
||||||
uint32_t nextStreamBufferIndex; /* it's a ring buffer! */
|
uint32_t nextStreamBufferIndex; /* it's a ring buffer! */
|
||||||
uint32_t buffersLoadedCount; /* how many buffers are we buffering? */
|
uint32_t buffersLoadedCount; /* how many buffers are we buffering? */
|
||||||
uint32_t mostRecentSampleOffset; /* used for calculating track position */
|
uint32_t mostRecentSampleOffset; /* used for calculating track position */
|
||||||
uint8_t isFinalBuffer; /* used to detect end of playback */
|
|
||||||
} FAudioGMS_StreamingSound;
|
} FAudioGMS_StreamingSound;
|
||||||
|
|
||||||
typedef struct FAudioGMS_SoundInstance FAudioGMS_SoundInstance;
|
typedef struct FAudioGMS_SoundInstance FAudioGMS_SoundInstance;
|
||||||
|
@ -358,23 +357,22 @@ static void FAudioGMS_INTERNAL_OnBufferEndCallback(
|
||||||
|
|
||||||
instance->soundData.streamingSound.mostRecentSampleOffset %= instance->playLength;
|
instance->soundData.streamingSound.mostRecentSampleOffset %= instance->playLength;
|
||||||
|
|
||||||
if (instance->soundData.streamingSound.isFinalBuffer)
|
if (stb_vorbis_get_sample_offset(instance->soundData.streamingSound.fileHandle) >= stb_vorbis_stream_length_in_samples(instance->soundData.streamingSound.fileHandle))
|
||||||
{
|
{
|
||||||
if (instance->loop)
|
FAudioGMS_INTERNAL_SoundInstance_Stop(instance);
|
||||||
{
|
|
||||||
stb_vorbis_seek(instance->soundData.streamingSound.fileHandle, instance->playBegin);
|
|
||||||
instance->soundData.streamingSound.mostRecentSampleOffset = instance->playBegin;
|
|
||||||
FAudioGMS_INTERNAL_SoundInstance_AddBuffers(instance);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FAudioGMS_INTERNAL_SoundInstance_Stop(instance);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else if (instance->soundState != SoundState_Stopped)
|
||||||
{
|
{
|
||||||
FAudioGMS_INTERNAL_SoundInstance_AddBuffers(instance);
|
FAudioGMS_INTERNAL_SoundInstance_AddBuffers(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
SDL_LogInfo(
|
||||||
|
SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"instance ID: %p, current streaming buffer offset: %u",
|
||||||
|
instance,
|
||||||
|
instance->soundData.streamingSound.mostRecentSampleOffset);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instance->soundState == SoundState_Stopped)
|
if (instance->soundState == SoundState_Stopped)
|
||||||
|
@ -1018,6 +1016,22 @@ static void FAudioGMS_INTERNAL_SoundInstance_AddBuffers(FAudioGMS_SoundInstance
|
||||||
.streamBuffer[instance->soundData.streamingSound.nextStreamBufferIndex],
|
.streamBuffer[instance->soundData.streamingSound.nextStreamBufferIndex],
|
||||||
requestedSampleCount * instance->format.nChannels);
|
requestedSampleCount * instance->format.nChannels);
|
||||||
|
|
||||||
|
/* If the stream ran out and we need to loop, seek to beginning of play region and fill in the remaining samples */
|
||||||
|
if (instance->loop && sampleCount < defaultRequestedSampleCount)
|
||||||
|
{
|
||||||
|
uint32_t fillInSampleCount = defaultRequestedSampleCount - sampleCount;
|
||||||
|
stb_vorbis_seek(instance->soundData.streamingSound.fileHandle, instance->playBegin);
|
||||||
|
|
||||||
|
uint32_t remainingSampleCount = stb_vorbis_get_samples_float_interleaved(
|
||||||
|
instance->soundData.streamingSound.fileHandle,
|
||||||
|
instance->format.nChannels,
|
||||||
|
&instance->soundData.streamingSound
|
||||||
|
.streamBuffer[instance->soundData.streamingSound.nextStreamBufferIndex][sampleCount * instance->format.nChannels],
|
||||||
|
fillInSampleCount * instance->format.nChannels);
|
||||||
|
|
||||||
|
sampleCount += remainingSampleCount;
|
||||||
|
}
|
||||||
|
|
||||||
FAudioBuffer buffer;
|
FAudioBuffer buffer;
|
||||||
buffer.AudioBytes = sampleCount * instance->format.nChannels * sizeof(float);
|
buffer.AudioBytes = sampleCount * instance->format.nChannels * sizeof(float);
|
||||||
buffer.pAudioData =
|
buffer.pAudioData =
|
||||||
|
@ -1034,13 +1048,6 @@ static void FAudioGMS_INTERNAL_SoundInstance_AddBuffers(FAudioGMS_SoundInstance
|
||||||
|
|
||||||
FAudioSourceVoice_SubmitSourceBuffer(instance->voice.handle, &buffer, NULL);
|
FAudioSourceVoice_SubmitSourceBuffer(instance->voice.handle, &buffer, NULL);
|
||||||
|
|
||||||
instance->soundData.streamingSound.isFinalBuffer = 0;
|
|
||||||
|
|
||||||
if (sampleCount < defaultRequestedSampleCount)
|
|
||||||
{
|
|
||||||
instance->soundData.streamingSound.isFinalBuffer = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
instance->soundData.streamingSound.nextStreamBufferIndex =
|
instance->soundData.streamingSound.nextStreamBufferIndex =
|
||||||
(instance->soundData.streamingSound.nextStreamBufferIndex + 1) % STREAMING_BUFFER_COUNT;
|
(instance->soundData.streamingSound.nextStreamBufferIndex + 1) % STREAMING_BUFFER_COUNT;
|
||||||
instance->soundData.streamingSound.buffersLoadedCount += 1;
|
instance->soundData.streamingSound.buffersLoadedCount += 1;
|
||||||
|
@ -1081,14 +1088,11 @@ double FAudioGMS_StreamingSound_LoadOGG(char *filePath, double bufferSizeInBytes
|
||||||
|
|
||||||
instance->soundData.streamingSound.streamBufferSize = bufferSizeInBytesInt;
|
instance->soundData.streamingSound.streamBufferSize = bufferSizeInBytesInt;
|
||||||
instance->soundData.streamingSound.mostRecentSampleOffset = 0;
|
instance->soundData.streamingSound.mostRecentSampleOffset = 0;
|
||||||
instance->soundData.streamingSound.isFinalBuffer = 0;
|
|
||||||
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(fileHandle);
|
||||||
|
|
||||||
FAudioGMS_INTERNAL_SoundInstance_AddBuffers(instance);
|
|
||||||
|
|
||||||
return instance->id;
|
return instance->id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1181,6 +1185,10 @@ static void FAudioGMS_INTERNAL_SoundInstance_Play(FAudioGMS_SoundInstance *insta
|
||||||
&instance->soundData.staticSound->buffer,
|
&instance->soundData.staticSound->buffer,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FAudioGMS_INTERNAL_SoundInstance_AddBuffers(instance);
|
||||||
|
}
|
||||||
|
|
||||||
FAudioSourceVoice_Start(instance->voice.handle, 0, 0);
|
FAudioSourceVoice_Start(instance->voice.handle, 0, 0);
|
||||||
instance->soundState = SoundState_Playing;
|
instance->soundState = SoundState_Playing;
|
||||||
|
@ -1230,10 +1238,9 @@ static void FAudioGMS_INTERNAL_SoundInstance_Stop(FAudioGMS_SoundInstance *insta
|
||||||
{
|
{
|
||||||
if (instance != NULL)
|
if (instance != NULL)
|
||||||
{
|
{
|
||||||
|
/* set before flush so we dont refill on OnBufferEnd callback */
|
||||||
instance->soundState =
|
instance->soundState =
|
||||||
SoundState_Stopped; /* set this before so flush
|
SoundState_Stopped;
|
||||||
buffers
|
|
||||||
doesn't trigger buffer add callback */
|
|
||||||
|
|
||||||
FAudioSourceVoice_Stop(instance->voice.handle, 0, 0);
|
FAudioSourceVoice_Stop(instance->voice.handle, 0, 0);
|
||||||
FAudioSourceVoice_FlushSourceBuffers(instance->voice.handle);
|
FAudioSourceVoice_FlushSourceBuffers(instance->voice.handle);
|
||||||
|
@ -1245,8 +1252,6 @@ static void FAudioGMS_INTERNAL_SoundInstance_Stop(FAudioGMS_SoundInstance *insta
|
||||||
stb_vorbis_seek(
|
stb_vorbis_seek(
|
||||||
instance->soundData.streamingSound.fileHandle,
|
instance->soundData.streamingSound.fileHandle,
|
||||||
instance->playBegin); /* back to the start */
|
instance->playBegin); /* back to the start */
|
||||||
FAudioGMS_INTERNAL_SoundInstance_AddBuffers(
|
|
||||||
instance); /* preload so we dont stutter on play */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue