Mercurial > SDL_sound_CoreAudio
changeset 231:d3dc34315ac7
Rewind method implemented by Torbj�rn.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Sat, 19 Jan 2002 16:58:34 +0000 |
parents | aa4137f121e4 |
children | 34000a50353b |
files | decoders/flac.c decoders/midi.c decoders/mikmod.c decoders/modplug.c decoders/mp3.c decoders/ogg.c |
diffstat | 6 files changed, 65 insertions(+), 33 deletions(-) [+] |
line wrap: on
line diff
--- a/decoders/flac.c Sat Jan 19 03:11:26 2002 +0000 +++ b/decoders/flac.c Sat Jan 19 16:58:34 2002 +0000 @@ -45,6 +45,12 @@ #define __SDL_SOUND_INTERNAL__ #include "SDL_sound_internal.h" +/* + * libFLAC 1.0.1 added a seekable stream decoder, but if I understand the + * documentation correctly it's still much easier for us to handle the rewind + * method ourselves. + */ + #include "FLAC/stream_decoder.h" @@ -80,6 +86,7 @@ FLAC__StreamDecoder *decoder; SDL_RWops *rw; Sound_Sample *sample; + Uint32 data_starting_offset; Uint32 frame_size; Uint8 is_flac; } flac_t; @@ -302,6 +309,13 @@ FLAC__stream_decoder_init(decoder); /* + * Annoyingly, the rewind method will put the FLAC decoder in a state + * where it expects to read metadata, so we have to set this marker + * before the metadata block. + */ + f->data_starting_offset = SDL_RWtell(f->rw); + + /* * If we are not sure this is a FLAC stream, check for the STREAMINFO * metadata block. If not, we'd have to peek at the first audio frame * and get the sound format from there, but that is not yet @@ -342,12 +356,6 @@ flac_t *f = (flac_t *) internal->decoder_private; Uint32 len; - if (FLAC__stream_decoder_get_state(f->decoder) == FLAC__STREAM_DECODER_END_OF_STREAM) - { - sample->flags |= SOUND_SAMPLEFLAG_EOF; - return(0); - } /* if */ - if (!FLAC__stream_decoder_process_one_frame(f->decoder)) { Sound_SetError("FLAC: Couldn't decode frame."); @@ -355,20 +363,31 @@ return(0); } /* if */ + if (FLAC__stream_decoder_get_state(f->decoder) == FLAC__STREAM_DECODER_END_OF_STREAM) + { + sample->flags |= SOUND_SAMPLEFLAG_EOF; + return(0); + } /* if */ + /* An error may have been signalled through the error callback. */ if (sample->flags & SOUND_SAMPLEFLAG_ERROR) return(0); - + return(f->frame_size); } /* FLAC_read */ static int FLAC_rewind(Sound_Sample *sample) { - /* !!! FIXME. */ - SNDDBG(("FLAC_rewind(): Write me!\n")); - assert(0); - return(0); + Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; + flac_t *f = (flac_t *) internal->decoder_private; + int rc = SDL_RWseek(f->rw, f->data_starting_offset, SEEK_SET); + + BAIL_IF_MACRO(rc != f->data_starting_offset, ERR_IO_ERROR, 0); + BAIL_IF_MACRO(!FLAC__stream_decoder_reset(f->decoder), + "FLAC: could not reset decoder", 0); + FLAC__stream_decoder_process_metadata(f->decoder); + return(1); } /* FLAC_rewind */ #endif /* SOUND_SUPPORTS_FLAC */
--- a/decoders/midi.c Sat Jan 19 03:11:26 2002 +0000 +++ b/decoders/midi.c Sat Jan 19 16:58:34 2002 +0000 @@ -150,13 +150,13 @@ static int MIDI_rewind(Sound_Sample *sample) { - /* !!! FIXME. */ - SNDDBG(("MIDI_rewind(): Write me!\n")); - assert(0); - return(0); + Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; + MidiSong *song = (MidiSong *) internal->decoder_private; + + Timidity_Start(song); + return(1); } /* MIDI_rewind */ - #endif /* SOUND_SUPPORTS_MIDI */
--- a/decoders/mikmod.c Sat Jan 19 03:11:26 2002 +0000 +++ b/decoders/mikmod.c Sat Jan 19 16:58:34 2002 +0000 @@ -287,10 +287,12 @@ static int MIKMOD_rewind(Sound_Sample *sample) { - /* !!! FIXME. */ - SNDDBG(("MIKMOD_rewind(): Write me!\n")); - assert(0); - return(0); + Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; + MODULE *module = (MODULE *) internal->decoder_private; + + Player_Start(module); + Player_SetPosition(0); + return(1); } /* MIKMOD_rewind */
--- a/decoders/modplug.c Sat Jan 19 03:11:26 2002 +0000 +++ b/decoders/modplug.c Sat Jan 19 16:58:34 2002 +0000 @@ -237,10 +237,11 @@ static int MODPLUG_rewind(Sound_Sample *sample) { - /* !!! FIXME. */ - SNDDBG(("MODPLUG_rewind(): Write me!\n")); - assert(0); - return(0); + Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; + ModPlugFile *module = (ModPlugFile *) internal->decoder_private; + + ModPlug_Seek(module, 0); + return(1); } /* MODPLUG_rewind */ #endif /* SOUND_SUPPORTS_MODPLUG */
--- a/decoders/mp3.c Sat Jan 19 03:11:26 2002 +0000 +++ b/decoders/mp3.c Sat Jan 19 16:58:34 2002 +0000 @@ -239,7 +239,7 @@ * We have to clear the buffer because apparently SMPEG_playAudio() * will mix the decoded audio with whatever's already in it. Nasty. */ - memset(internal->buffer, 0, internal->buffer_size); + memset(internal->buffer, '\0', internal->buffer_size); retval = SMPEG_playAudio(smpeg, internal->buffer, internal->buffer_size); if (retval < internal->buffer_size) { @@ -259,10 +259,19 @@ static int MP3_rewind(Sound_Sample *sample) { - /* !!! FIXME. */ - SNDDBG(("MP3_rewind(): Write me!\n")); - assert(0); - return(0); + Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; + SMPEG *smpeg = (SMPEG *) internal->decoder_private; + SMPEGstatus status; + + /* + * SMPEG_rewind() really means "stop and rewind", so we may have to + * restart it afterwards. + */ + status = SMPEG_status(smpeg); + SMPEG_rewind(smpeg); + if (status == SMPEG_PLAYING) + SMPEG_play(smpeg); + return(1); } /* MP3_rewind */ #endif /* SOUND_SUPPORTS_MP3 */
--- a/decoders/ogg.c Sat Jan 19 03:11:26 2002 +0000 +++ b/decoders/ogg.c Sat Jan 19 16:58:34 2002 +0000 @@ -268,10 +268,11 @@ static int OGG_rewind(Sound_Sample *sample) { - /* !!! FIXME. */ - SNDDBG(("OGG_rewind(): Write me!\n")); - assert(0); - return(0); + Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; + OggVorbis_File *vf = (OggVorbis_File *) internal->decoder_private; + + BAIL_IF_MACRO(ov_raw_seek(vf, 0) < 0, ERR_IO_ERROR, 0); + return(1); } /* OGG_rewind */ #endif /* SOUND_SUPPORTS_OGG */