Index: libmpc/branches/r2d/libmpcdec/mpc_demux.c
===================================================================
--- libmpc/branches/r2d/libmpcdec/mpc_demux.c	(revision 143)
+++ libmpc/branches/r2d/libmpcdec/mpc_demux.c	(revision 146)
@@ -107,5 +107,5 @@
 /**
  * seek to a bit position in the stream
- * @param d
+ * @param d demuxer context
  * @param fpos position in the stream in bits from the beginning of mpc datas
  * @param min_bytes number of bytes to load after seeking
@@ -133,4 +133,14 @@
 	d->bits_reader.buff += bit_offset >> 3;
 	d->bits_reader.count = 8 - (bit_offset & 7);
+}
+
+/**
+ * return the current position in the stream (in bits)
+ * @param d demuxer context
+ * @return current stream position in bits
+ */
+static mpc_size_t mpc_demux_pos(mpc_demux * d)
+{
+	return ((d->r->tell(d->r) - d->bytes_total + d->bits_reader.buff - d->buffer) << 3) + 8 - d->bits_reader.count;
 }
 
@@ -198,7 +208,11 @@
 		p_tmp->r = p_reader;
 		mpc_demux_clear_buff(p_tmp);
-		// lire entÃªte
 		if (mpc_demux_header(p_tmp) == MPC_STATUS_OK) {
-			// initialisation decodeur
+			p_tmp->seek_pwr = 6;
+			if (p_tmp->si.block_pwr > p_tmp->seek_pwr)
+				p_tmp->seek_pwr = p_tmp->si.block_pwr;
+			p_tmp->seek_table = malloc((1 + p_tmp->si.samples / (MPC_FRAME_LENGTH << p_tmp->seek_pwr)) * sizeof(mpc_uint32_t));
+			p_tmp->seek_table[0] = mpc_demux_pos(p_tmp);
+			p_tmp->seek_table_size = 1;
 			p_tmp->d = mpc_decoder_init(&p_tmp->si);
 		} else {
@@ -214,4 +228,5 @@
 {
 	mpc_decoder_exit(d->d);
+	free(d->seek_table);
 	free(d);
 }
@@ -222,6 +237,13 @@
 }
 
+#include <stdio.h>
+
 void mpc_demux_decode(mpc_demux * d, mpc_frame_info * i)
 {
+	if (d->d->decoded_samples == (d->seek_table_size << d->seek_pwr) * MPC_FRAME_LENGTH) {
+		d->seek_table[d->seek_table_size] = mpc_demux_pos(d);
+		d->seek_table_size ++;
+	}
+
 	if (d->si.stream_version >= 8) {
 		mpc_bits_reader r;
@@ -263,30 +285,12 @@
 mpc_status mpc_demux_seek_sample(mpc_demux * d, mpc_int64_t destsample)
 {
-	mpc_uint32_t fwd, samples_to_skip, fpos = 32, i;
+	mpc_uint32_t fwd, samples_to_skip, fpos, i;
+	mpc_uint32_t block_samples = MPC_FRAME_LENGTH << d->si.block_pwr;
 
 	if (destsample > d->si.samples) destsample = d->si.samples;
-	fwd = (mpc_uint32_t) (destsample / (MPC_FRAME_LENGTH * d->si.frames_per_block));
-	samples_to_skip = MPC_DECODER_SYNTH_DELAY + (mpc_uint32_t)
-			(destsample % (MPC_FRAME_LENGTH * d->si.frames_per_block));
-
-	// FIXME : we start seeking from the beginning of the file, easier but not optimal
-	d->d->decoded_samples = 0;
-
-	if (d->si.stream_version >= 8) {
-		mpc_block b;
-		int size;
-		mpc_demux_seek(d, fpos, 11);
-		size = mpc_bits_get_block(&d->bits_reader, &b);
-		for( i = 0; i < fwd; ){
-			if (memcmp(b.key, "AD", 2) == 0){
-				i++;
-				d->d->decoded_samples += MPC_FRAME_LENGTH * d->si.frames_per_block;
-			}
-			fpos += (b.size + size) * 8;
-			mpc_demux_seek(d, fpos, 11);
-			size = mpc_bits_get_block(&d->bits_reader, &b);
-		}
-		d->bits_reader.buff -= size;
-	} else {
+	fwd = (mpc_uint32_t) (destsample / block_samples);
+	samples_to_skip = MPC_DECODER_SYNTH_DELAY +
+			(mpc_uint32_t) (destsample % block_samples);
+	if (d->si.stream_version == 7) {
 		if (fwd > 32) {
 			fwd -= 32;
@@ -296,11 +300,43 @@
 			fwd = 0;
 		}
+	}
+
+	i = fwd >> (d->seek_pwr - d->si.block_pwr);
+	if (i >= d->seek_table_size)
+		i = d->seek_table_size - 1;
+	fpos = d->seek_table[i];
+	i <<= d->seek_pwr - d->si.block_pwr;
+	d->d->decoded_samples = i * block_samples;
+
+	if (d->si.stream_version >= 8) {
+		mpc_block b;
+		int size;
+		mpc_demux_seek(d, fpos, 11);
+		size = mpc_bits_get_block(&d->bits_reader, &b);
+		while(i < fwd) {
+			if (memcmp(b.key, "AD", 2) == 0) {
+				if (d->d->decoded_samples == (d->seek_table_size << d->seek_pwr) * MPC_FRAME_LENGTH) {
+					d->seek_table[d->seek_table_size] = mpc_demux_pos(d) - 8 * size;
+					d->seek_table_size ++;
+				}
+				d->d->decoded_samples += block_samples;
+				i++;
+			}
+			fpos += (b.size + size) * 8;
+			mpc_demux_seek(d, fpos, 11);
+			size = mpc_bits_get_block(&d->bits_reader, &b);
+		}
+		d->bits_reader.buff -= size;
+	} else {
 		mpc_decoder_reset_scf(d->d);
-		fpos += 21 * 8;
 		mpc_demux_seek(d, fpos, 4);
-		for( i = 0; i < fwd; i++){
+		for( ; i < fwd; i++){
+			if (d->d->decoded_samples == (d->seek_table_size << d->seek_pwr) * MPC_FRAME_LENGTH) {
+				d->seek_table[d->seek_table_size] = mpc_demux_pos(d);
+				d->seek_table_size ++;
+			}
+			d->d->decoded_samples += block_samples;
 			fpos += mpc_bits_read(&d->bits_reader, 20) + 20;
 			mpc_demux_seek(d, fpos, 4);
-			d->d->decoded_samples += MPC_FRAME_LENGTH;
 		}
 	}
