decoder/modplug: count frame position

Don't maintain the current time stamp in a floating point variable,
because this is subject to rounding errors.
This commit is contained in:
Max Kellermann 2009-11-14 22:30:57 +01:00
parent f5b9e3c064
commit 1dfadf4815

View File

@ -94,10 +94,9 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
ModPlug_Settings settings; ModPlug_Settings settings;
GByteArray *bdatas; GByteArray *bdatas;
struct audio_format audio_format; struct audio_format audio_format;
float total_time = 0.0; int ret;
int ret, current;
char audio_buffer[MODPLUG_FRAME_SIZE]; char audio_buffer[MODPLUG_FRAME_SIZE];
float sec_perbyte; unsigned frame_size, current_frame = 0;
enum decoder_command cmd = DECODE_COMMAND_NONE; enum decoder_command cmd = DECODE_COMMAND_NONE;
bdatas = mod_loadfile(decoder, is); bdatas = mod_loadfile(decoder, is);
@ -126,29 +125,28 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
audio_format_init(&audio_format, 44100, 16, 2); audio_format_init(&audio_format, 44100, 16, 2);
assert(audio_format_valid(&audio_format)); assert(audio_format_valid(&audio_format));
sec_perbyte =
1.0 / ((audio_format.bits * audio_format.channels / 8.0) *
(float)audio_format.sample_rate);
decoder_initialized(decoder, &audio_format, decoder_initialized(decoder, &audio_format,
is->seekable, ModPlug_GetLength(f) / 1000.0); is->seekable, ModPlug_GetLength(f) / 1000.0);
total_time = 0; frame_size = audio_format_frame_size(&audio_format);
do { do {
ret = ModPlug_Read(f, audio_buffer, MODPLUG_FRAME_SIZE); ret = ModPlug_Read(f, audio_buffer, MODPLUG_FRAME_SIZE);
if (ret <= 0) if (ret <= 0)
break; break;
total_time += ret * sec_perbyte; current_frame += (unsigned)ret / frame_size;
cmd = decoder_data(decoder, NULL, cmd = decoder_data(decoder, NULL,
audio_buffer, ret, audio_buffer, ret,
total_time, 0, NULL); (float)current_frame / (float)audio_format.sample_rate,
0, NULL);
if (cmd == DECODE_COMMAND_SEEK) { if (cmd == DECODE_COMMAND_SEEK) {
total_time = decoder_seek_where(decoder); float where = decoder_seek_where(decoder);
current = total_time * 1000;
ModPlug_Seek(f, current); ModPlug_Seek(f, (int)(where * 1000.0));
current_frame = (unsigned)(where * audio_format.sample_rate);
decoder_command_finished(decoder); decoder_command_finished(decoder);
} }