From 1dfadf4815f5a1ca18f235bc839e9e20dd68ecb0 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@duempel.org>
Date: Sat, 14 Nov 2009 22:30:57 +0100
Subject: decoder/modplug: count frame position

Don't maintain the current time stamp in a floating point variable,
because this is subject to rounding errors.
---
 src/decoder/modplug_plugin.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

(limited to 'src/decoder')

diff --git a/src/decoder/modplug_plugin.c b/src/decoder/modplug_plugin.c
index 3a886471a..6c08c2199 100644
--- a/src/decoder/modplug_plugin.c
+++ b/src/decoder/modplug_plugin.c
@@ -94,10 +94,9 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
 	ModPlug_Settings settings;
 	GByteArray *bdatas;
 	struct audio_format audio_format;
-	float total_time = 0.0;
-	int ret, current;
+	int ret;
 	char audio_buffer[MODPLUG_FRAME_SIZE];
-	float sec_perbyte;
+	unsigned frame_size, current_frame = 0;
 	enum decoder_command cmd = DECODE_COMMAND_NONE;
 
 	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);
 	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,
 			    is->seekable, ModPlug_GetLength(f) / 1000.0);
 
-	total_time = 0;
+	frame_size = audio_format_frame_size(&audio_format);
 
 	do {
 		ret = ModPlug_Read(f, audio_buffer, MODPLUG_FRAME_SIZE);
 		if (ret <= 0)
 			break;
 
-		total_time += ret * sec_perbyte;
+		current_frame += (unsigned)ret / frame_size;
 		cmd = decoder_data(decoder, NULL,
 				   audio_buffer, ret,
-				   total_time, 0, NULL);
+				   (float)current_frame / (float)audio_format.sample_rate,
+				   0, NULL);
 
 		if (cmd == DECODE_COMMAND_SEEK) {
-			total_time = decoder_seek_where(decoder);
-			current = total_time * 1000;
-			ModPlug_Seek(f, current);
+			float where = decoder_seek_where(decoder);
+
+			ModPlug_Seek(f, (int)(where * 1000.0));
+			current_frame = (unsigned)(where * audio_format.sample_rate);
+
 			decoder_command_finished(decoder);
 		}
 
-- 
cgit v1.2.3