diff --git a/src/SDL_sound_internal.h b/src/SDL_sound_internal.h index b68d2f7..fc8d3f0 100644 --- a/src/SDL_sound_internal.h +++ b/src/SDL_sound_internal.h @@ -260,6 +260,7 @@ typedef struct __SOUND_SAMPLEINTERNAL__ Uint32 buffer_size; void *decoder_private; Sint32 total_time; + Uint32 total_length; Uint32 mix_position; MixFunc mix; } Sound_SampleInternal; diff --git a/src/SDL_sound_vorbis.c b/src/SDL_sound_vorbis.c index b427521..6fdd7a3 100644 --- a/src/SDL_sound_vorbis.c +++ b/src/SDL_sound_vorbis.c @@ -133,6 +133,7 @@ static int VORBIS_open(Sound_Sample *sample, const char *ext) const unsigned int rate = stb->sample_rate; internal->total_time = (num_frames / rate) * 1000; internal->total_time += (num_frames % rate) * 1000 / rate; + internal->total_length = num_frames; } /* else */ return 1; /* we'll handle this data. */ @@ -152,14 +153,23 @@ static Uint32 VORBIS_read(Sound_Sample *sample) Uint32 retval; int rc; int err; + int delta; Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; stb_vorbis *stb = (stb_vorbis *) internal->decoder_private; const int channels = (int) sample->actual.channels; const int want_samples = (int) (internal->buffer_size / sizeof (float)); + const int offset = stb_vorbis_get_playback_sample_offset(stb); + + delta = internal->total_length - offset; stb_vorbis_get_error(stb); /* clear any error state */ rc = stb_vorbis_get_samples_float_interleaved(stb, channels, (float *) internal->buffer, want_samples); - retval = (Uint32) (rc * channels * sizeof (float)); /* rc == number of sample frames read */ + if(delta > 0 && delta < rc) { + retval = (Uint32) (delta * channels * sizeof (float)); /* prevents bug in stb_vorbis */ + } else { + retval = (Uint32) (rc * channels * sizeof (float)); /* rc == number of sample frames read */ + } + err = stb_vorbis_get_error(stb); if (retval == 0)