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:
parent
f5b9e3c064
commit
1dfadf4815
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user