# HG changeset patch # User Ryan C. Gordon # Date 1019414387 0 # Node ID c97be6e1bd27d688db527ea7692ed42b127349ad # Parent c345a40a8a998a306a261c45169e6f37fbda618b Added framework for Sound_Seek() support. diff -r c345a40a8a99 -r c97be6e1bd27 CHANGELOG --- a/CHANGELOG Sun Apr 21 17:48:11 2002 +0000 +++ b/CHANGELOG Sun Apr 21 18:39:47 2002 +0000 @@ -3,7 +3,9 @@ */ 04212002 - Initial work to add a Sound_Seek() API. Removed the NEEDSEEK - sample flag (replaced it with CANSEEK). + sample flag (replaced it with CANSEEK). Hack to change the internal + Sound_SetError() function to __Sound_SetError(). Added internal + function __Sound_convertMsToBytePos(). 04082002 - Cleaned up the archive support in playsound a little bit, and fixed a PhysicsFS bug in the process. 03252002 - Win32 patches and fixes from Tyler Montbriand: handled "inline" diff -r c345a40a8a99 -r c97be6e1bd27 SDL_sound.c --- a/SDL_sound.c Sun Apr 21 17:48:11 2002 +0000 +++ b/SDL_sound.c Sun Apr 21 18:39:47 2002 +0000 @@ -346,7 +346,7 @@ /* * This is declared in the internal header. */ -void Sound_SetError(const char *str) +void __Sound_SetError(const char *str) { ErrMsg *err; @@ -378,7 +378,17 @@ err->error_available = 1; strncpy(err->error_string, str, sizeof (err->error_string)); err->error_string[sizeof (err->error_string) - 1] = '\0'; -} /* Sound_SetError */ +} /* __Sound_SetError */ + + +Uint32 __Sound_convertMsToBytePos(Sound_AudioInfo *info, Uint32 ms) +{ + /* "frames" == "sample frames" */ + float frames_per_ms = ((float) info->rate) / 1000.0; + Uint32 frame_offset = (Uint32) (frames_per_ms * ((float) ms)); + Uint32 frame_size = (Uint32) ((info->format & 0xFF) / 8) * info->channels; + return(frame_offset * frame_size); +} /* __Sound_convertMsToBytePos */ /* @@ -846,6 +856,26 @@ sample->flags &= !SOUND_SAMPLEFLAG_EAGAIN; sample->flags &= !SOUND_SAMPLEFLAG_ERROR; sample->flags &= !SOUND_SAMPLEFLAG_EOF; + + return(1); +} /* Sound_Rewind */ + + +int Sound_Seek(Sound_Sample *sample, Uint32 ms) +{ + Sound_SampleInternal *internal; + + BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0); + if (!(sample->flags & SOUND_SAMPLEFLAG_CANSEEK)) + BAIL_MACRO(ERR_CANNOT_SEEK, 0); + + internal = (Sound_SampleInternal *) sample->opaque; + BAIL_IF_MACRO(!internal->funcs->seek(sample, ms), NULL, 0); + + sample->flags &= !SOUND_SAMPLEFLAG_EAGAIN; + sample->flags &= !SOUND_SAMPLEFLAG_ERROR; + sample->flags &= !SOUND_SAMPLEFLAG_EOF; + return(1); } /* Sound_Rewind */ diff -r c345a40a8a99 -r c97be6e1bd27 SDL_sound_internal.h --- a/SDL_sound_internal.h Sun Apr 21 17:48:11 2002 +0000 +++ b/SDL_sound_internal.h Sun Apr 21 18:39:47 2002 +0000 @@ -177,6 +177,22 @@ * this method should ever fail! */ int (*rewind)(Sound_Sample *sample); + + /* + * Reposition the decoding to an arbitrary point. Nonzero on + * success, zero on failure. + * + * The purpose of this method is to allow for higher efficiency than + * an application could get by just rewinding the sample and + * decoding to a given point. + * + * The decoder is responsible for calling seek() on the associated + * SDL_RWops. + * + * If there is an error, try to recover so that the next read will + * continue as if nothing happened. + */ + int (*seek)(Sound_Sample *sample, Uint32 ms); } Sound_DecoderFunctions; @@ -225,6 +241,7 @@ #define ERR_COMPRESSION "(De)compression error" #define ERR_PREV_ERROR "Previous decoding already caused an error" #define ERR_PREV_EOF "Previous decoding already triggered EOF" +#define ERR_CANNOT_SEEK "Sample is not seekable" /* * Call this to set the message returned by Sound_GetError(). @@ -233,8 +250,16 @@ * * Calling this with a NULL argument is a safe no-op. */ -void Sound_SetError(const char *err); +void __Sound_SetError(const char *err); + +/* !!! FIXME: Clean up elsewhere and get rid of this. */ +#define Sound_SetError __Sound_SetError +/* + * Call this to convert milliseconds to an actual byte position, based on + * audio data characteristics. + */ +Uint32 __Sound_convertMsToBytePos(Sound_AudioInfo *info, Uint32 ms); /* * Use this if you need a cross-platform stricmp(). @@ -243,8 +268,8 @@ /* These get used all over for lessening code clutter. */ -#define BAIL_MACRO(e, r) { Sound_SetError(e); return r; } -#define BAIL_IF_MACRO(c, e, r) if (c) { Sound_SetError(e); return r; } +#define BAIL_MACRO(e, r) { __Sound_SetError(e); return r; } +#define BAIL_IF_MACRO(c, e, r) if (c) { __Sound_SetError(e); return r; } diff -r c345a40a8a99 -r c97be6e1bd27 decoders/aiff.c --- a/decoders/aiff.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/aiff.c Sun Apr 21 18:39:47 2002 +0000 @@ -66,6 +66,7 @@ static void AIFF_close(Sound_Sample *sample); static Uint32 AIFF_read(Sound_Sample *sample); static int AIFF_rewind(Sound_Sample *sample); +static int AIFF_seek(Sound_Sample *sample, Uint32 ms); static const char *extensions_aiff[] = { "AIFF", NULL }; const Sound_DecoderFunctions __Sound_DecoderFunctions_AIFF = @@ -82,7 +83,8 @@ AIFF_open, /* open() method */ AIFF_close, /* close() method */ AIFF_read, /* read() method */ - AIFF_rewind /* rewind() method */ + AIFF_rewind, /* rewind() method */ + AIFF_seek /* seek() method */ }; @@ -520,7 +522,7 @@ aiff_t *a = (aiff_t *) internal->decoder_private; a->fmt.free(&(a->fmt)); free(a); -} /* WAV_close */ +} /* AIFF_close */ static Uint32 AIFF_read(Sound_Sample *sample) @@ -542,6 +544,12 @@ return(fmt->rewind_sample(sample)); } /* AIFF_rewind */ + +static int AIFF_seek(Sound_Sample *sample, Uint32 ms) +{ + BAIL_MACRO("!!! FIXME: Not implemented", 0); +} /* AIFF_seek */ + #endif /* SOUND_SUPPORTS_AIFF */ /* end of aiff.c ... */ diff -r c345a40a8a99 -r c97be6e1bd27 decoders/au.c --- a/decoders/au.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/au.c Sun Apr 21 18:39:47 2002 +0000 @@ -49,6 +49,7 @@ static void AU_close(Sound_Sample *sample); static Uint32 AU_read(Sound_Sample *sample); static int AU_rewind(Sound_Sample *sample); +static int AU_seek(Sound_Sample *sample, Uint32 ms); /* * Sometimes the extension ".snd" is used for these files (mostly on the NeXT), @@ -70,7 +71,8 @@ AU_open, /* open() method */ AU_close, /* close() method */ AU_read, /* read() method */ - AU_rewind /* rewind() method */ + AU_rewind, /* rewind() method */ + AU_seek /* seek() method */ }; /* no init/deinit needed */ @@ -316,5 +318,11 @@ return(1); } /* AU_rewind */ + +static int AU_seek(Sound_Sample *sample, Uint32 ms) +{ + BAIL_MACRO("!!! FIXME: Not implemented", 0); +} /* AU_seek */ + #endif /* SOUND_SUPPORTS_AU */ diff -r c345a40a8a99 -r c97be6e1bd27 decoders/flac.c --- a/decoders/flac.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/flac.c Sun Apr 21 18:39:47 2002 +0000 @@ -60,6 +60,7 @@ static void FLAC_close(Sound_Sample *sample); static Uint32 FLAC_read(Sound_Sample *sample); static int FLAC_rewind(Sound_Sample *sample); +static int FLAC_seek(Sound_Sample *sample, Uint32 ms); static const char *extensions_flac[] = { "FLAC", "FLA", NULL }; @@ -77,7 +78,8 @@ FLAC_open, /* open() method */ FLAC_close, /* close() method */ FLAC_read, /* read() method */ - FLAC_rewind /* rewind() method */ + FLAC_rewind, /* rewind() method */ + FLAC_seek /* seek() method */ }; /* This is what we store in our internal->decoder_private field. */ @@ -390,6 +392,13 @@ return(1); } /* FLAC_rewind */ + +static int FLAC_seek(Sound_Sample *sample, Uint32 ms) +{ + BAIL_MACRO("!!! FIXME: Not implemented", 0); +} /* FLAC_seek */ + + #endif /* SOUND_SUPPORTS_FLAC */ diff -r c345a40a8a99 -r c97be6e1bd27 decoders/midi.c --- a/decoders/midi.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/midi.c Sun Apr 21 18:39:47 2002 +0000 @@ -53,6 +53,7 @@ static void MIDI_close(Sound_Sample *sample); static Uint32 MIDI_read(Sound_Sample *sample); static int MIDI_rewind(Sound_Sample *sample); +static int MIDI_seek(Sound_Sample *sample, Uint32 ms); static const char *extensions_midi[] = { "MIDI", "MID", NULL }; const Sound_DecoderFunctions __Sound_DecoderFunctions_MIDI = @@ -69,7 +70,8 @@ MIDI_open, /* open() method */ MIDI_close, /* close() method */ MIDI_read, /* read() method */ - MIDI_rewind /* rewind() method */ + MIDI_rewind, /* rewind() method */ + MIDI_seek /* seek() method */ }; @@ -157,6 +159,12 @@ return(1); } /* MIDI_rewind */ + +static int MIDI_seek(Sound_Sample *sample, Uint32 ms) +{ + BAIL_MACRO("!!! FIXME: Not implemented", 0); +} /* MIDI_seek */ + #endif /* SOUND_SUPPORTS_MIDI */ diff -r c345a40a8a99 -r c97be6e1bd27 decoders/mikmod.c --- a/decoders/mikmod.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/mikmod.c Sun Apr 21 18:39:47 2002 +0000 @@ -51,6 +51,7 @@ static void MIKMOD_close(Sound_Sample *sample); static Uint32 MIKMOD_read(Sound_Sample *sample); static int MIKMOD_rewind(Sound_Sample *sample); +static int MIKMOD_seek(Sound_Sample *sample, Uint32 ms); static const char *extensions_mikmod[] = { @@ -89,7 +90,8 @@ MIKMOD_open, /* open() method */ MIKMOD_close, /* close() method */ MIKMOD_read, /* read() method */ - MIKMOD_rewind /* rewind() method */ + MIKMOD_rewind, /* rewind() method */ + MIKMOD_seek /* seek() method */ }; @@ -295,6 +297,10 @@ } /* MIKMOD_rewind */ +static int MIKMOD_seek(Sound_Sample *sample, Uint32 ms) +{ + BAIL_MACRO("!!! FIXME: Not implemented", 0); +} /* MIKMOD_seek */ #endif /* SOUND_SUPPORTS_MIKMOD */ diff -r c345a40a8a99 -r c97be6e1bd27 decoders/modplug.c --- a/decoders/modplug.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/modplug.c Sun Apr 21 18:39:47 2002 +0000 @@ -50,6 +50,7 @@ static void MODPLUG_close(Sound_Sample *sample); static Uint32 MODPLUG_read(Sound_Sample *sample); static int MODPLUG_rewind(Sound_Sample *sample); +static int MODPLUG_seek(Sound_Sample *sample, Uint32 ms); static const char *extensions_modplug[] = { @@ -97,7 +98,8 @@ MODPLUG_open, /* open() method */ MODPLUG_close, /* close() method */ MODPLUG_read, /* read() method */ - MODPLUG_rewind /* rewind() method */ + MODPLUG_rewind, /* rewind() method */ + MODPLUG_seek /* seek() method */ }; @@ -244,6 +246,12 @@ return(1); } /* MODPLUG_rewind */ + +static int MODPLUG_seek(Sound_Sample *sample, Uint32 ms) +{ + BAIL_MACRO("!!! FIXME: Not implemented", 0); +} /* MODPLUG_seek */ + #endif /* SOUND_SUPPORTS_MODPLUG */ diff -r c345a40a8a99 -r c97be6e1bd27 decoders/mpglib.c --- a/decoders/mpglib.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/mpglib.c Sun Apr 21 18:39:47 2002 +0000 @@ -27,8 +27,8 @@ * SMPEG, and, again, doesn't need an external library. You should test both * decoders and use what you find works best for you. * - * mpglib is part of mpg123, which can be found in its original form at: - * http://www.mpg123.de/ + * mpglib is an LGPL'd portion of mpg123, which can be found in its original + * form at: http://www.mpg123.de/ * * Please see the file COPYING in the source's root directory. The included * source code for mpglib falls under the LGPL, which is the same license as @@ -61,6 +61,7 @@ static void MPGLIB_close(Sound_Sample *sample); static Uint32 MPGLIB_read(Sound_Sample *sample); static int MPGLIB_rewind(Sound_Sample *sample); +static int MPGLIB_seek(Sound_Sample *sample, Uint32 ms); static const char *extensions_mpglib[] = { "MP3", NULL }; const Sound_DecoderFunctions __Sound_DecoderFunctions_MPGLIB = @@ -77,7 +78,8 @@ MPGLIB_open, /* open() method */ MPGLIB_close, /* close() method */ MPGLIB_read, /* read() method */ - MPGLIB_rewind /* rewind() method */ + MPGLIB_rewind, /* rewind() method */ + MPGLIB_seek /* seek() method */ }; @@ -286,6 +288,11 @@ } /* MPGLIB_rewind */ +static int MPGLIB_seek(Sound_Sample *sample, Uint32 ms) +{ + BAIL_MACRO("!!! FIXME: Not implemented", 0); +} /* MPGLIB_seek */ + #endif /* SOUND_SUPPORTS_MPGLIB */ diff -r c345a40a8a99 -r c97be6e1bd27 decoders/ogg.c --- a/decoders/ogg.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/ogg.c Sun Apr 21 18:39:47 2002 +0000 @@ -59,6 +59,7 @@ static void OGG_close(Sound_Sample *sample); static Uint32 OGG_read(Sound_Sample *sample); static int OGG_rewind(Sound_Sample *sample); +static int OGG_seek(Sound_Sample *sample, Uint32 ms); static const char *extensions_ogg[] = { "OGG", NULL }; const Sound_DecoderFunctions __Sound_DecoderFunctions_OGG = @@ -75,7 +76,8 @@ OGG_open, /* open() method */ OGG_close, /* close() method */ OGG_read, /* read() method */ - OGG_rewind /* rewind() method */ + OGG_rewind, /* rewind() method */ + OGG_seek /* seek() method */ }; @@ -275,6 +277,12 @@ return(1); } /* OGG_rewind */ + +static int OGG_seek(Sound_Sample *sample, Uint32 ms) +{ + BAIL_MACRO("!!! FIXME: Not implemented", 0); +} /* OGG_seek */ + #endif /* SOUND_SUPPORTS_OGG */ diff -r c345a40a8a99 -r c97be6e1bd27 decoders/raw.c --- a/decoders/raw.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/raw.c Sun Apr 21 18:39:47 2002 +0000 @@ -60,6 +60,7 @@ static void RAW_close(Sound_Sample *sample); static Uint32 RAW_read(Sound_Sample *sample); static int RAW_rewind(Sound_Sample *sample); +static int RAW_seek(Sound_Sample *sample, Uint32 ms); static const char *extensions_raw[] = { "RAW", NULL }; const Sound_DecoderFunctions __Sound_DecoderFunctions_RAW = @@ -76,7 +77,8 @@ RAW_open, /* open() method */ RAW_close, /* close() method */ RAW_read, /* read() method */ - RAW_rewind /* rewind() method */ + RAW_rewind, /* rewind() method */ + RAW_seek /* seek() method */ }; @@ -123,7 +125,7 @@ * We never convert raw samples; what you ask for is what you get. */ memcpy(&sample->actual, &sample->desired, sizeof (Sound_AudioInfo)); - sample->flags = SOUND_SAMPLEFLAG_NONE; + sample->flags = SOUND_SAMPLEFLAG_CANSEEK; return(1); /* we'll handle this data. */ } /* RAW_open */ @@ -170,6 +172,16 @@ } /* RAW_rewind */ +static int RAW_seek(Sound_Sample *sample, Uint32 ms) +{ + Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; + int pos = (int) __Sound_convertMsToBytePos(&sample->actual, ms); + int err = (SDL_RWseek(internal->rw, pos, SEEK_SET) != pos); + BAIL_IF_MACRO(err, ERR_IO_ERROR, 0); + return(1); +} /* RAW_seek */ + + #endif /* SOUND_SUPPORTS_RAW */ diff -r c345a40a8a99 -r c97be6e1bd27 decoders/shn.c --- a/decoders/shn.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/shn.c Sun Apr 21 18:39:47 2002 +0000 @@ -63,6 +63,7 @@ static void SHN_close(Sound_Sample *sample); static Uint32 SHN_read(Sound_Sample *sample); static int SHN_rewind(Sound_Sample *sample); +static int SHN_seek(Sound_Sample *sample, Uint32 ms); static const char *extensions_shn[] = { "SHN", NULL }; const Sound_DecoderFunctions __Sound_DecoderFunctions_SHN = @@ -79,7 +80,8 @@ SHN_open, /* open() method */ SHN_close, /* close() method */ SHN_read, /* read() method */ - SHN_rewind /* rewind() method */ + SHN_rewind, /* rewind() method */ + SHN_seek /* seek() method */ }; @@ -1322,6 +1324,13 @@ #endif } /* SHN_rewind */ + +static int SHN_seek(Sound_Sample *sample, Uint32 ms) +{ + BAIL_MACRO("!!! FIXME: Not implemented", 0); +} /* SHN_seek */ + + #endif /* defined SOUND_SUPPORTS_SHN */ /* end of shn.c ... */ diff -r c345a40a8a99 -r c97be6e1bd27 decoders/skeleton.c --- a/decoders/skeleton.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/skeleton.c Sun Apr 21 18:39:47 2002 +0000 @@ -59,6 +59,7 @@ static void FMT_close(Sound_Sample *sample); static Uint32 FMT_read(Sound_Sample *sample); static int FMT_rewind(Sound_Sample *sample); +static int FMT_seek(Sound_Sample *sample, Uint32 ms); static const char *extensions_fmt[] = { "FMT", NULL }; const Sound_DecoderFunctions __Sound_DecoderFunctions_FMT = @@ -75,7 +76,8 @@ FMT_open, /* open() method */ FMT_close, /* close() method */ FMT_read, /* read() method */ - FMT_rewind /* rewind() method */ + FMT_rewind, /* rewind() method */ + FMT_seek /* seek() method */ }; @@ -161,6 +163,20 @@ return(1); /* success. */ } /* FMT_rewind */ + +static int FMT_seek(Sound_Sample *sample, Uint32 ms) +{ + Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; + + /* seek to the appropriate place... */ + BAIL_IF_MACRO(SDL_RWseek(internal->rw, 0, SEEK_SET) != 0, ERR_IO_ERROR, 0); + + (set state as necessary.) + + return(1); /* success. */ +} /* FMT_seek */ + + #endif /* SOUND_SUPPORTS_FMT */ diff -r c345a40a8a99 -r c97be6e1bd27 decoders/smpeg.c --- a/decoders/smpeg.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/smpeg.c Sun Apr 21 18:39:47 2002 +0000 @@ -61,6 +61,7 @@ static void _SMPEG_close(Sound_Sample *sample); static Uint32 _SMPEG_read(Sound_Sample *sample); static int _SMPEG_rewind(Sound_Sample *sample); +static int _SMPEG_seek(Sound_Sample *sample, Uint32 ms); static const char *extensions_smpeg[] = { "MP3", "MPEG", "MPG", NULL }; const Sound_DecoderFunctions __Sound_DecoderFunctions_SMPEG = @@ -77,7 +78,8 @@ _SMPEG_open, /* open() method */ _SMPEG_close, /* close() method */ _SMPEG_read, /* read() method */ - _SMPEG_rewind /* rewind() method */ + _SMPEG_rewind, /* rewind() method */ + _SMPEG_seek /* seek() method */ }; @@ -272,6 +274,12 @@ return(1); } /* _SMPEG_rewind */ + +static int _SMPEG_seek(Sound_Sample *sample, Uint32 ms) +{ + BAIL_MACRO("!!! FIXME: Not implemented", 0); +} /* _SMPEG_seek */ + #endif /* SOUND_SUPPORTS_SMPEG */ /* end of smpeg.c ... */ diff -r c345a40a8a99 -r c97be6e1bd27 decoders/voc.c --- a/decoders/voc.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/voc.c Sun Apr 21 18:39:47 2002 +0000 @@ -59,6 +59,7 @@ static void VOC_close(Sound_Sample *sample); static Uint32 VOC_read(Sound_Sample *sample); static int VOC_rewind(Sound_Sample *sample); +static int VOC_seek(Sound_Sample *sample, Uint32 ms); static const char *extensions_voc[] = { "VOC", NULL }; const Sound_DecoderFunctions __Sound_DecoderFunctions_VOC = @@ -75,7 +76,8 @@ VOC_open, /* open() method */ VOC_close, /* close() method */ VOC_read, /* read() method */ - VOC_rewind /* rewind() method */ + VOC_rewind, /* rewind() method */ + VOC_seek /* seek() method */ }; @@ -502,6 +504,13 @@ return(1); } /* VOC_rewind */ + +static int VOC_seek(Sound_Sample *sample, Uint32 ms) +{ + BAIL_MACRO("!!! FIXME: Not implemented", 0); +} /* VOC_seek */ + + #endif /* SOUND_SUPPORTS_VOC */ /* end of voc.c ... */ diff -r c345a40a8a99 -r c97be6e1bd27 decoders/wav.c --- a/decoders/wav.c Sun Apr 21 17:48:11 2002 +0000 +++ b/decoders/wav.c Sun Apr 21 18:39:47 2002 +0000 @@ -50,6 +50,7 @@ static void WAV_close(Sound_Sample *sample); static Uint32 WAV_read(Sound_Sample *sample); static int WAV_rewind(Sound_Sample *sample); +static int WAV_seek(Sound_Sample *sample, Uint32 ms); static const char *extensions_wav[] = { "WAV", NULL }; const Sound_DecoderFunctions __Sound_DecoderFunctions_WAV = @@ -66,7 +67,8 @@ WAV_open, /* open() method */ WAV_close, /* close() method */ WAV_read, /* read() method */ - WAV_rewind /* rewind() method */ + WAV_rewind, /* rewind() method */ + WAV_seek /* seek() method */ }; @@ -719,6 +721,12 @@ return(fmt->rewind_sample(sample)); } /* WAV_rewind */ + +static int WAV_seek(Sound_Sample *sample, Uint32 ms) +{ + BAIL_MACRO("!!! FIXME: Not implemented", 0); +} /* WAV_seek */ + #endif /* SOUND_SUPPORTS_WAV */ /* end of wav.c ... */