From 54fc922f6cef70210c34f9ddd5997531f4d6be99 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 13 Aug 2010 01:48:20 +0000 Subject: [PATCH] better error checking while reading streamed data --- include/snd_render.h | 6 ++++-- libs/audio/renderer/flac.c | 7 ++++++- libs/audio/renderer/midi.c | 4 +++- libs/audio/renderer/snd_mem.c | 5 +++-- libs/audio/renderer/snd_mix.c | 10 ++++++++-- libs/audio/renderer/vorbis.c | 4 +++- libs/audio/renderer/wav.c | 4 +++- 7 files changed, 30 insertions(+), 10 deletions(-) diff --git a/include/snd_render.h b/include/snd_render.h index ebf9b437d..bd219de28 100644 --- a/include/snd_render.h +++ b/include/snd_render.h @@ -112,8 +112,9 @@ struct sfxbuffer_s { necessary. Null for chached sounds. \param buffer "this" \param count number of frames to advance + \return true for success, false if an error occured */ - void (*advance) (sfxbuffer_t *buffer, unsigned int count); + int (*advance) (sfxbuffer_t *buffer, unsigned int count); /** Seek to an absolute position within the stream, resetting the ring buffer. \param buffer "this" @@ -134,6 +135,7 @@ struct sfxstream_s { void *file; //!< handle for "file" representing the stream wavinfo_t wavinfo; //!< description of sound data unsigned pos; //!< position of next frame full stream + int error; //!< an error occured while reading void *state; //!< resampler state information /** Read data from the stream. @@ -548,7 +550,7 @@ void SND_StreamRelease (sfx_t *sfx); \param buffer "this" \param count number of samples to advance */ -void SND_StreamAdvance (sfxbuffer_t *buffer, unsigned int count); +int SND_StreamAdvance (sfxbuffer_t *buffer, unsigned int count); /** Seek to an absolute position within the stream, resetting the ring buffer. diff --git a/libs/audio/renderer/flac.c b/libs/audio/renderer/flac.c index cd146b052..dfa32c080 100644 --- a/libs/audio/renderer/flac.c +++ b/libs/audio/renderer/flac.c @@ -340,7 +340,12 @@ flac_stream_read (void *file, float **buf) { sfxstream_t *stream = (sfxstream_t *) file; flacfile_t *ff = (flacfile_t *) stream->file; - FLAC__stream_decoder_process_single (ff->decoder); + int res = FLAC__stream_decoder_process_single (ff->decoder); + + if (!res) { + stream->error = 1; + return -1; + } *buf = ff->buffer; return ff->size; } diff --git a/libs/audio/renderer/midi.c b/libs/audio/renderer/midi.c index 25fed7ba9..73ec31282 100644 --- a/libs/audio/renderer/midi.c +++ b/libs/audio/renderer/midi.c @@ -107,8 +107,10 @@ midi_stream_read (void *file, float **buf) byte *data = alloca (size); res = WildMidi_GetOutput (mf->handle, (char *)data, size); - if (res < 0) + if (res <= 0) { + stream->error = 1; return res; + } res /= CHANNELS * WIDTH; SND_Convert (data, mf->data, res, CHANNELS, WIDTH); *buf = mf->data; diff --git a/libs/audio/renderer/snd_mem.c b/libs/audio/renderer/snd_mem.c index ad2ddceb7..c310f6611 100644 --- a/libs/audio/renderer/snd_mem.c +++ b/libs/audio/renderer/snd_mem.c @@ -225,7 +225,7 @@ SND_StreamSetPos (sfxbuffer_t *buffer, unsigned int pos) fill_buffer (sfx, stream, buffer, info, pos); } -void +int SND_StreamAdvance (sfxbuffer_t *buffer, unsigned int count) { float stepscale; @@ -237,7 +237,7 @@ SND_StreamAdvance (sfxbuffer_t *buffer, unsigned int count) stream->pos += count; count = (stream->pos - buffer->pos) & ~255; if (!count) - return; + return 1; stepscale = (float) info->rate / snd_shm->speed; @@ -291,6 +291,7 @@ SND_StreamAdvance (sfxbuffer_t *buffer, unsigned int count) buffer->tail -= buffer->length; } fill_buffer (sfx, stream, buffer, info, headpos); + return !stream->error; } int diff --git a/libs/audio/renderer/snd_mix.c b/libs/audio/renderer/snd_mix.c index da5e829b9..c5a902684 100644 --- a/libs/audio/renderer/snd_mix.c +++ b/libs/audio/renderer/snd_mix.c @@ -156,8 +156,14 @@ SND_PaintChannels (unsigned endtime) if (count > 0) { if (ch->leftvol || ch->rightvol) { snd_paint_channel (ch, sc, count); - if (sc->advance) - sc->advance (sc, count); + if (sc->advance) { + if (!sc->advance (sc, count)) { + // this channel can no longer be used as its + // source has died. + ch->done = 1; + break; + } + } } ltime += count; } diff --git a/libs/audio/renderer/vorbis.c b/libs/audio/renderer/vorbis.c index e5459741c..2d8bf2453 100644 --- a/libs/audio/renderer/vorbis.c +++ b/libs/audio/renderer/vorbis.c @@ -228,8 +228,10 @@ vorbis_stream_read (void *file, float **buf) if (!vf->data) vf->data = malloc (FRAMES * stream->wavinfo.channels * sizeof (float)); res = vorbis_read (vf->vf, vf->data, FRAMES, &stream->wavinfo); - if (res <= 0) + if (res <= 0) { + stream->error = 1; return res; + } *buf = vf->data; return res; } diff --git a/libs/audio/renderer/wav.c b/libs/audio/renderer/wav.c index 2f0ef77a5..c33fae126 100644 --- a/libs/audio/renderer/wav.c +++ b/libs/audio/renderer/wav.c @@ -112,8 +112,10 @@ wav_stream_read (void *file, float **buf) wf->data = malloc (FRAMES * info->channels * sizeof (float)); res = Qread (wf->file, data, len); - if (res <= 0) + if (res <= 0) { + stream->error = 1; return res; + } res /= (info->channels * info->width); SND_Convert (data, wf->data, res, info->channels, info->width); *buf = wf->data;