# HG changeset patch # User Ryan C. Gordon # Date 1084328100 0 # Node ID 3e705c9180e5dbe35cb7cee5aef854d8c881c826 # Parent f0b8865577dbacc281b0aff735e8bc1110d175e2 Fixed binary compatibility, added Sound_GetDuration(). diff -r f0b8865577db -r 3e705c9180e5 CHANGELOG --- a/CHANGELOG Sat May 08 22:06:14 2004 +0000 +++ b/CHANGELOG Wed May 12 02:15:00 2004 +0000 @@ -2,7 +2,9 @@ * CHANGELOG. */ - +05112004 - Added Sound_GetDuration() and moved total_time out of Sound_Sample + struct and into it's opaque data...this fixes binary compatibility + with apps written for SDL_sound 1.0. 05082004 - Started 1.1.0 development branch with code to determine the total length of a sample (thanks to Wesley, Eric, Wang, and Ahilan!)... this patch was originally committed to CVS on 10252003, but it is diff -r f0b8865577db -r 3e705c9180e5 SDL_sound.c --- a/SDL_sound.c Sat May 08 22:06:14 2004 +0000 +++ b/SDL_sound.c Wed May 12 02:15:00 2004 +0000 @@ -901,5 +901,12 @@ } /* Sound_Rewind */ +Sint32 Sound_GetDuration(Sound_Sample *sample) +{ + BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, -1); + Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; + return(internal->total_time); +} /* Sound_GetDuration */ + /* end of SDL_sound.c ... */ diff -r f0b8865577db -r 3e705c9180e5 SDL_sound.h --- a/SDL_sound.h Sat May 08 22:06:14 2004 +0000 +++ b/SDL_sound.h Wed May 12 02:15:00 2004 +0000 @@ -185,7 +185,6 @@ void *buffer; /**< Decoded sound data lands in here. */ Uint32 buffer_size; /**< Current size of (buffer), in bytes (Uint8). */ Sound_SampleFlags flags; /**< Flags relating to this sample. */ - Sint32 total_time; /**< Total length of song or track */ } Sound_Sample; @@ -501,6 +500,31 @@ /** + * \fn Sint32 Sound_GetDuration(Sound_Sample *sample) + * \brief Retrieve total play time of sample, in milliseconds. + * + * Report total time length of sample, in milliseconds. This is a fast + * call. Duration is calculated during Sound_NewSample*, so this is just + * an accessor into otherwise opaque data. + * + * Please note that not all formats can determine a total time, some can't + * be exact without fully decoding the data, and thus will estimate the + * duration. Many decoders will require the ability to seek in the data + * stream to calculate this, so even if we can tell you how long an .ogg + * file will be, the same data set may fail if it's, say, streamed over an + * HTTP connection. Plan accordingly. + * + * Most people won't need this function to just decode and playback, but it + * can be useful for informational purposes in, say, a music player's UI. + * + * \param sample Sound_Sample from which to retrieve duration information. + * \return Sample length in milliseconds, or -1 if duration can't be + * determined for any reason. + */ +SNDDECLSPEC Sint32 SDLCALL Sound_GetDuration(Sound_Sample *sample); + + +/** * \fn int Sound_SetBufferSize(Sound_Sample *sample, Uint32 new_size) * \brief Change the current buffer size for a sample. * diff -r f0b8865577db -r 3e705c9180e5 SDL_sound_internal.h --- a/SDL_sound_internal.h Sat May 08 22:06:14 2004 +0000 +++ b/SDL_sound_internal.h Wed May 12 02:15:00 2004 +0000 @@ -255,6 +255,7 @@ void *buffer; Uint32 buffer_size; void *decoder_private; + Sint32 total_time; } Sound_SampleInternal; diff -r f0b8865577db -r 3e705c9180e5 decoders/aiff.c --- a/decoders/aiff.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/aiff.c Wed May 12 02:15:00 2004 +0000 @@ -477,9 +477,9 @@ sample->actual.rate = c.sampleRate; /* Really, sample->total_time = (c.numSampleFrames*1000) c.sampleRate */ - sample->total_time = (c.numSampleFrames / c.sampleRate) * 1000; - sample->total_time += (c.numSampleFrames % c.sampleRate) - * 1000 / c.sampleRate; + internal->total_time = (c.numSampleFrames / c.sampleRate) * 1000; + internal->total_time += (c.numSampleFrames % c.sampleRate) + * 1000 / c.sampleRate; if (c.sampleSize <= 8) { diff -r f0b8865577db -r 3e705c9180e5 decoders/au.c --- a/decoders/au.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/au.c Wed May 12 02:15:00 2004 +0000 @@ -246,10 +246,10 @@ bytes_per_second = ( ( dec->encoding == AU_ENC_LINEAR_16 ) ? 2 : 1 ) * sample->actual.rate * sample->actual.channels ; - sample->total_time = ((dec->remaining == -1) ? (-1) : - ( ( dec->remaining / bytes_per_second ) * 1000 ) + - ( ( dec->remaining % bytes_per_second ) * 1000 / - bytes_per_second ) ); + internal->total_time = ((dec->remaining == -1) ? (-1) : + ( ( dec->remaining / bytes_per_second ) * 1000 ) + + ( ( dec->remaining % bytes_per_second ) * 1000 / + bytes_per_second ) ); sample->flags = SOUND_SAMPLEFLAG_CANSEEK; dec->total = dec->remaining; diff -r f0b8865577db -r 3e705c9180e5 decoders/flac.c --- a/decoders/flac.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/flac.c Wed May 12 02:15:00 2004 +0000 @@ -233,6 +233,8 @@ void *client_data) { flac_t *f = (flac_t *) client_data; + Sound_Sample *sample = f->sample; + Sound_SampleInternal *internal = (Sound_SampleInternal *) sample->opaque; SNDDBG(("FLAC: Metadata callback.\n")); @@ -244,24 +246,27 @@ SNDDBG(("FLAC: Metadata is streaminfo.\n")); f->is_flac = 1; - f->sample->actual.channels = metadata->data.stream_info.channels; - f->sample->actual.rate = metadata->data.stream_info.sample_rate; + sample->actual.channels = metadata->data.stream_info.channels; + sample->actual.rate = metadata->data.stream_info.sample_rate; - if (metadata->data.stream_info.sample_rate == 0 || + if (metadata->data.stream_info.sample_rate == 0 || metadata->data.stream_info.total_samples == 0) - f->sample->total_time = -1; - else { - f->sample->total_time = (metadata->data.stream_info.total_samples) + { + internal->total_time = -1; + } /* if */ + else + { + internal->total_time = (metadata->data.stream_info.total_samples) / metadata->data.stream_info.sample_rate * 1000; - f->sample->total_time += (metadata->data.stream_info.total_samples + internal->total_time += (metadata->data.stream_info.total_samples % metadata->data.stream_info.sample_rate) * 1000 / metadata->data.stream_info.sample_rate; - } + } /* else */ if (metadata->data.stream_info.bits_per_sample > 8) - f->sample->actual.format = AUDIO_S16MSB; + sample->actual.format = AUDIO_S16MSB; else - f->sample->actual.format = AUDIO_S8; + sample->actual.format = AUDIO_S8; } /* if */ } /* metadata_callback */ diff -r f0b8865577db -r 3e705c9180e5 decoders/midi.c --- a/decoders/midi.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/midi.c Wed May 12 02:15:00 2004 +0000 @@ -107,13 +107,13 @@ SNDDBG(("MIDI: Accepting data stream.\n")); internal->decoder_private = (void *) song; + internal->total_time = Timidity_GetSongLength(song); sample->actual.channels = 2; sample->actual.rate = 44100; sample->actual.format = AUDIO_S16SYS; + sample->flags = SOUND_SAMPLEFLAG_CANSEEK; - sample->total_time = Timidity_GetSongLength(song); - sample->flags = SOUND_SAMPLEFLAG_CANSEEK; return(1); /* we'll handle this data. */ } /* MIDI_open */ diff -r f0b8865577db -r 3e705c9180e5 decoders/mikmod.c --- a/decoders/mikmod.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/mikmod.c Wed May 12 02:15:00 2004 +0000 @@ -282,9 +282,9 @@ /* * module->sngtime = current song time in 2^-10 seconds - * sample->total_time = (module->sngtime * 1000) / (1<<10) + * internal->total_time = (module->sngtime * 1000) / (1<<10) */ - sample->total_time = (module->sngtime * 1000) / (1<<10); + internal->total_time = (module->sngtime * 1000) / (1<<10); SNDDBG(("MIKMOD: Name: %s\n", module->songname)); SNDDBG(("MIKMOD: Type: %s\n", module->modtype)); @@ -322,7 +322,7 @@ * For each position (which corresponds to a particular pattern), * get the speed values and compute the time length of the segment */ - sample->total_time = 0; + internal->total_time = 0; for (i = 0; i < module->numpos; i++) { Player_SetPosition(i); @@ -378,7 +378,7 @@ 125.0 / module->bpm); } /* for */ /* Now convert to milliseconds and store the value */ - sample->total_time = (Sint32)(segment_time * 1000); + internal->total_time = (Sint32)(segment_time * 1000); /* Reset the sample to the beginning */ Player_SetPosition(0); @@ -462,7 +462,7 @@ return(1); } /* if */ - if (ms >= sample->total_time) + if (ms >= internal->total_time) Player_SetPosition(module->numpos); /* Convert time to seconds (double) to make comparisons easier */ diff -r f0b8865577db -r 3e705c9180e5 decoders/modplug.c --- a/decoders/modplug.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/modplug.c Wed May 12 02:15:00 2004 +0000 @@ -270,7 +270,7 @@ if (modplug_mutex != NULL) SDL_UnlockMutex(modplug_mutex); - sample->total_time = ModPlug_GetLength(module); + internal->total_time = ModPlug_GetLength(module); SNDDBG(("MODPLUG: [%d ms] %s\n", ModPlug_GetLength(module), ModPlug_GetName(module))); diff -r f0b8865577db -r 3e705c9180e5 decoders/mpglib.c --- a/decoders/mpglib.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/mpglib.c Wed May 12 02:15:00 2004 +0000 @@ -197,8 +197,8 @@ if (SDL_RWseek(internal->rw, pos, SEEK_SET) != pos) { BAIL_MACRO("MPGLIB: Cannot go back to save spot in file.", 0); } - sample->total_time = total_byte_size / mpg->mp.fr.bitrate * 8.0; - sample->total_time += (total_byte_size % mpg->mp.fr.bitrate) * 8.0 + internal->total_time = total_byte_size / mpg->mp.fr.bitrate * 8.0; + internal->total_time += (total_byte_size % mpg->mp.fr.bitrate) * 8.0 / mpg->mp.fr.bitrate; } diff -r f0b8865577db -r 3e705c9180e5 decoders/ogg.c --- a/decoders/ogg.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/ogg.c Wed May 12 02:15:00 2004 +0000 @@ -212,9 +212,9 @@ sample->actual.channels = (Uint8) info->channels; total_time = ov_time_total(vf, -1); if (OV_EINVAL == total_time) - sample->total_time = -1; + internal->total_time = -1; else - sample->total_time = (Sint32)(total_time * 1000.0 + 0.5); + internal->total_time = (Sint32)(total_time * 1000.0 + 0.5); /* diff -r f0b8865577db -r 3e705c9180e5 decoders/quicktime.c --- a/decoders/quicktime.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/quicktime.c Wed May 12 02:15:00 2004 +0000 @@ -547,7 +547,7 @@ instance = QT_open_internal(sample, ext); internal->decoder_private = (void*)instance; - sample->total_time = -1; /* return -1 for total time of song for now */ + internal->total_time = -1; /* return -1 for total time of song for now */ return(instance != NULL); diff -r f0b8865577db -r 3e705c9180e5 decoders/raw.c --- a/decoders/raw.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/raw.c Wed May 12 02:15:00 2004 +0000 @@ -135,8 +135,8 @@ sample_rate = (sample->actual.rate * sample->actual.channels * ( (sample->actual.format & 0x0018) >> 3) ); - sample->total_time = ( pos ) / sample_rate * 1000; - sample->total_time += (pos % sample_rate) * 1000 / sample_rate; + internal->total_time = ( pos ) / sample_rate * 1000; + internal->total_time += (pos % sample_rate) * 1000 / sample_rate; return(1); /* we'll handle this data. */ } /* RAW_open */ diff -r f0b8865577db -r 3e705c9180e5 decoders/shn.c --- a/decoders/shn.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/shn.c Wed May 12 02:15:00 2004 +0000 @@ -580,8 +580,8 @@ BAIL_IF_MACRO(!verb_ReadLE32(shn, rw, &u32), NULL, 0); /* 'data' header */ BAIL_IF_MACRO(u32 != dataID, "SHN: No 'data' header.", 0); BAIL_IF_MACRO(!verb_ReadLE32(shn, rw, &u32), NULL, 0); /* chunksize */ - sample->total_time = u32 / bytes_per_second * 1000; - sample->total_time += (u32 % bytes_per_second) * 1000 / bytes_per_second; + internal->total_time = u32 / bytes_per_second * 1000; + internal->total_time += (u32 % bytes_per_second) * 1000 / bytes_per_second; return(1); } /* parse_riff_header */ diff -r f0b8865577db -r 3e705c9180e5 decoders/smpeg.c --- a/decoders/smpeg.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/smpeg.c Wed May 12 02:15:00 2004 +0000 @@ -212,7 +212,7 @@ sample->actual.rate = spec.freq; sample->actual.channels = spec.channels; sample->flags = SOUND_SAMPLEFLAG_CANSEEK; - sample->total_time = smpeg_info.total_time * 1000; + internal->total_time = smpeg_info.total_time * 1000; internal->decoder_private = smpeg; SMPEG_play(smpeg); diff -r f0b8865577db -r 3e705c9180e5 decoders/voc.c --- a/decoders/voc.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/voc.c Wed May 12 02:15:00 2004 +0000 @@ -245,9 +245,9 @@ bytes_per_second = sample->actual.rate * sample->actual.channels; - sample->total_time += ( v->rest ) / bytes_per_second * 1000; - sample->total_time += (v->rest % bytes_per_second) * 1000 - / bytes_per_second; + internal->total_time += ( v->rest ) / bytes_per_second * 1000; + internal->total_time += (v->rest % bytes_per_second) * 1000 + / bytes_per_second; return 1; case VOC_DATA_16: @@ -281,11 +281,11 @@ return 0; v->rest = sblen - 12; - bytes_per_second = ((v->size == ST_SIZE_WORD) ? (2) : (1)) * - sample->actual.rate * v->channels; - sample->total_time += v->rest / bytes_per_second * 1000; - sample->total_time += ( v->rest % bytes_per_second ) * 1000 - / bytes_per_second; + bytes_per_second = ((v->size == ST_SIZE_WORD) ? (2) : (1)) * + sample->actual.rate * v->channels; + internal->total_time += v->rest / bytes_per_second * 1000; + internal->total_time += ( v->rest % bytes_per_second ) * 1000 + / bytes_per_second; return 1; case VOC_CONT: @@ -315,8 +315,8 @@ v->rest = period; v->silent = 1; - sample->total_time += (period) / (v->rate) * 1000; - sample->total_time += (period % v->rate) * 1000 / v->rate; + internal->total_time += (period) / (v->rate) * 1000; + internal->total_time += (period % v->rate) * 1000 / v->rate; return 1; case VOC_LOOP: diff -r f0b8865577db -r 3e705c9180e5 decoders/wav.c --- a/decoders/wav.c Sat May 08 22:06:14 2004 +0000 +++ b/decoders/wav.c Wed May 12 02:15:00 2004 +0000 @@ -724,9 +724,9 @@ sample->actual.channels ); internal->decoder_private = (void *) w; - sample->total_time = (fmt->total_bytes / fmt->dwAvgBytesPerSec) * 1000; - sample->total_time += (fmt->total_bytes % fmt->dwAvgBytesPerSec) - * 1000 / fmt->dwAvgBytesPerSec; + internal->total_time = (fmt->total_bytes / fmt->dwAvgBytesPerSec) * 1000; + internal->total_time += (fmt->total_bytes % fmt->dwAvgBytesPerSec) + * 1000 / fmt->dwAvgBytesPerSec; sample->flags = SOUND_SAMPLEFLAG_NONE; if (fmt->seek_sample != NULL)