Index: /branches/zorg/include/mpcdec/decoder.h
===================================================================
--- /branches/zorg/include/mpcdec/decoder.h	(revision 23)
+++ /branches/zorg/include/mpcdec/decoder.h	(revision 24)
@@ -45,4 +45,5 @@
 
 #define MPC_SUPPORT_SV456
+#define SCF_HACK
 
 enum {
@@ -62,8 +63,10 @@
     //@{
 
+    mpc_uint32_t  next;
     mpc_uint32_t  dword; /// currently decoded 32bit-word
     mpc_uint32_t  pos;   /// bit-position within dword
-    mpc_uint32_t  Speicher[MPC_DECODER_MEMSIZE]; /// read-buffer
+    mpc_uint32_t  *Speicher; /// read-buffer
     mpc_uint32_t  Zaehler; /// actual index within read-buffer
+    mpc_uint32_t  Ring;
 
     mpc_uint32_t  samples_to_skip;
@@ -75,4 +78,7 @@
     mpc_uint32_t  DecodedFrames;
     mpc_uint32_t  OverallFrames;
+    mpc_uint32_t  MaxDecodedFrames;           // Maximum frames decoded (indicates usable seek table entries)
+  	mpc_uint16_t  SeekTableIndex;
+  	mpc_uint32_t  SeekTableCounter;
     mpc_int32_t   SampleRate;                 // Sample frequency
 
@@ -105,4 +111,12 @@
     //mpc_int32_t   DSCF_Reference_R [32];      // holds last frames SCF
     mpc_bool_t    MS_Flag[32];                // MS used?
+
+    mpc_uint32_t* SeekTable;
+    mpc_bool_t    Use_SeekTable;
+    mpc_bool_t    Use_FastSeek;
+    mpc_bool_t    Use_StaticSeekTable;
+    mpc_uint8_t   SeekTable_Step;
+    mpc_uint32_t  Max_SeekTable_Size;
+
 #ifdef MPC_FIXED_POINT
     mpc_uint8_t   SCF_shift[256];
Index: /branches/zorg/include/mpcdec/mpcdec.h
===================================================================
--- /branches/zorg/include/mpcdec/mpcdec.h	(revision 23)
+++ /branches/zorg/include/mpcdec/mpcdec.h	(revision 24)
@@ -134,4 +134,10 @@
 mpc_bool_t mpc_decoder_seek_seconds(mpc_decoder *d, double seconds);
 
+/// Sets the static seek table pointer.
+void mpc_decoder_set_seek_table(mpc_decoder *d, mpc_uint32_t *seek_table, mpc_uint32_t max_table_size);
+
+/// Cleans up the decoder.
+void mpc_decoder_destroy(mpc_decoder *d);
+
 #ifdef __cplusplus
 }
Index: /branches/zorg/src/mpc_decoder.c
===================================================================
--- /branches/zorg/src/mpc_decoder.c	(revision 23)
+++ /branches/zorg/src/mpc_decoder.c	(revision 24)
@@ -59,4 +59,37 @@
 #endif
 
+#ifndef MPC_LITTLE_ENDIAN
+#define SWAP(X) mpc_swap32(X)
+#else
+#define SWAP(X) X
+#endif
+
+#ifdef SCF_HACK
+#define SCF_DIFF(SCF, D) (SCF == -128 ? -128 : SCF + D)
+#else
+#define SCF_DIFF(SCF, D) SCF + D
+#endif
+
+#define LOOKUP(x, e, q) mpc_decoder_make_huffman_lookup ( (q), sizeof(q), (x), (e) )
+#define DECODE_DSCF() HUFFMAN_DECODE_FASTEST ( d, mpc_table_HuffDSCF, LUTDSCF, 6 )
+#define HUFFMAN_DECODE_FASTEST(d,a,b,c) mpc_decoder_huffman_decode_fastest ( (d), (a), (b), 32-(c) )
+#define HUFFMAN_DECODE_FASTERER(d,a,b,c) mpc_decoder_huffman_decode_fasterer ( (d), (a), (b), 32-(c) )
+
+mpc_uint8_t     LUT1_0  [1<< 6];
+mpc_uint8_t     LUT1_1  [1<< 9];            //  576 Bytes
+mpc_uint8_t     LUT2_0  [1<< 7];
+mpc_uint8_t     LUT2_1  [1<<10];            // 1152 Bytes
+mpc_uint8_t     LUT3_0  [1<< 4];
+mpc_uint8_t     LUT3_1  [1<< 5];            //   48 Bytes
+mpc_uint8_t     LUT4_0  [1<< 4];
+mpc_uint8_t     LUT4_1  [1<< 5];            //   48 Bytes
+mpc_uint8_t     LUT5_0  [1<< 6];
+mpc_uint8_t     LUT5_1  [1<< 8];            //  320 Bytes
+mpc_uint8_t     LUT6_0  [1<< 7];
+mpc_uint8_t     LUT6_1  [1<< 7];            //  256 Bytes
+mpc_uint8_t     LUT7_0  [1<< 8];
+mpc_uint8_t     LUT7_1  [1<< 8];            //  512 Bytes
+mpc_uint8_t     LUTDSCF [1<< 6];            //   64 Bytes = 2976 Bytes
+
 //------------------------------------------------------------------------------
 // types
@@ -76,8 +109,16 @@
 //------------------------------------------------------------------------------
 void mpc_decoder_read_bitstream_sv6(mpc_decoder *d);
-void mpc_decoder_read_bitstream_sv7(mpc_decoder *d);
-void mpc_decoder_update_buffer(mpc_decoder *d, mpc_uint32_t RING);
+void mpc_decoder_read_bitstream_sv7(mpc_decoder *d, mpc_bool_t isFastSeeking);
+void mpc_decoder_update_buffer(mpc_decoder *d);
 mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample);
 void mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band);
+void mpc_decoder_seek_to(mpc_decoder *d, mpc_uint32_t bitPos);
+void mpc_decoder_seek_forward(mpc_decoder *d, mpc_uint32_t bits);
+mpc_uint32_t mpc_decoder_jump_frame(mpc_decoder *d);
+void mpc_decoder_fill_buffer(mpc_decoder *d);
+void mpc_decoder_reset_state(mpc_decoder *d);
+static mpc_uint32_t get_initial_fpos(mpc_decoder *d, mpc_uint32_t StreamVersion);
+static __inline mpc_int32_t mpc_decoder_huffman_decode_fastest(mpc_decoder *d, const HuffmanTyp* Table, const mpc_uint8_t* tab, mpc_uint16_t unused_bits);
+static void mpc_move_next(mpc_decoder *d);
 
 //------------------------------------------------------------------------------
@@ -130,4 +171,5 @@
     d->dword = 0;
     d->pos = 0;
+    d->next = 0;
     d->Zaehler = 0;
     d->WordsRead = 0;
@@ -141,6 +183,16 @@
 }
 
+static void
+mpc_move_next(mpc_decoder *d)
+{
+    d->Zaehler = (d->Zaehler + 1) & MEMMASK;
+    d->dword = d->next;
+    d->next = SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]);
+    d->pos -= 32;
+    ++(d->WordsRead);
+}
+
 // read desired number of bits out of the bitstream
-static mpc_uint32_t
+static __inline mpc_uint32_t
 mpc_decoder_bitstream_read(mpc_decoder *d, const mpc_uint32_t bits) 
 {
@@ -153,14 +205,29 @@
     }
     else {
-        d->dword = d->Speicher[d->Zaehler = (d->Zaehler + 1) & MEMMASK];
-        d->pos -= 32;
+        mpc_move_next(d);
         if (d->pos) {
             out <<= d->pos;
             out |= d->dword >> (32 - d->pos);
         }
-        ++(d->WordsRead);
     }
 
     return out & mask[bits];
+}
+
+static void
+mpc_decoder_make_huffman_lookup(
+    mpc_uint8_t* lookup, size_t length, const HuffmanTyp* Table, size_t elements)
+{
+    size_t i, idx  = elements;
+    mpc_uint32_t dval = (mpc_uint32_t)0x80000000L / length * 2;
+    mpc_uint32_t val  = dval - 1;
+
+    for ( i = 0; i < length; i++, val += dval ) {
+        while ( idx > 0  &&  val >= Table[idx-1].Code )
+            idx--;
+        *lookup++ = (mpc_uint8_t)idx;
+    }
+
+    return;
 }
 
@@ -174,5 +241,5 @@
     mpc_uint32_t code  = d->dword << d->pos;
     if (d->pos > 26) {
-        code |= d->Speicher[(d->Zaehler + 1) & MEMMASK] >> (32 - d->pos);
+        code |= d->next >> (32 - d->pos);
     }
     while (code < Table->Code) {
@@ -182,7 +249,5 @@
     // set the new position within bitstream without performing a dummy-read
     if ((d->pos += Table->Length) >= 32) {
-        d->pos -= 32;
-        d->dword = d->Speicher[d->Zaehler = (d->Zaehler+1) & MEMMASK];
-        ++(d->WordsRead);
+         mpc_move_next(d);
     }
 
@@ -199,5 +264,5 @@
     mpc_uint32_t code = d->dword << d->pos;
     if (d->pos > 18) {
-        code |= d->Speicher[(d->Zaehler + 1) & MEMMASK] >> (32 - d->pos);
+        code |= d->next >> (32 - d->pos);
     }
     while (code < Table->Code) {
@@ -207,7 +272,5 @@
     // set the new position within bitstream without performing a dummy-read
     if ((d->pos += Table->Length) >= 32) {
-        d->pos -= 32;
-        d->dword = d->Speicher[d->Zaehler = (d->Zaehler + 1) & MEMMASK];
-        ++(d->WordsRead);
+        mpc_move_next(d);
     }
 
@@ -223,5 +286,5 @@
     mpc_uint32_t code  = d->dword << d->pos;
     if (d->pos > 22) {
-        code |= d->Speicher[(d->Zaehler + 1) & MEMMASK] >> (32 - d->pos);
+        code |= d->next >> (32 - d->pos);
     }
     while (code < Table->Code) {
@@ -231,7 +294,5 @@
     // set the new position within bitstream without performing a dummy-read
     if ((d->pos += Table->Length) >= 32) {
-        d->pos -= 32;
-        d->dword = d->Speicher[d->Zaehler = (d->Zaehler + 1) & MEMMASK];
-        ++(d->WordsRead);
+        mpc_move_next(d);
     }
 
@@ -247,5 +308,5 @@
     mpc_uint32_t code  = d->dword << d->pos;
     if (d->pos > 27) {
-        code |= d->Speicher[(d->Zaehler + 1) & MEMMASK] >> (32 - d->pos);
+        code |= d->next >> (32 - d->pos);
     }
     while (code < Table->Code) {
@@ -255,7 +316,55 @@
     // set the new position within bitstream without performing a dummy-read
     if ((d->pos += Table->Length) >= 32) {
-        d->pos -= 32;
-        d->dword = d->Speicher[d->Zaehler = (d->Zaehler + 1) & MEMMASK];
-        ++(d->WordsRead);
+        mpc_move_next(d);
+    }
+
+    return Table->Value;
+}
+
+/* partial lookup table decode */
+static mpc_int32_t
+mpc_decoder_huffman_decode_fasterer(
+    mpc_decoder *d, 
+    const HuffmanTyp* Table, const mpc_uint8_t* tab, mpc_uint16_t unused_bits)
+{
+    // load preview and decode
+    mpc_uint32_t code  = d->dword << d->pos;
+
+    if (d->pos > 18) { // preview 14 bits
+        code |= d->next >> (32 - d->pos);
+    }
+
+    Table += tab [(size_t)(code >> unused_bits) ];
+
+    while (code < Table->Code) {
+        Table++;
+    }
+
+    // set the new position within bitstream without performing a dummy-read
+    if ((d->pos += Table->Length) >= 32) {
+        mpc_move_next(d);
+    }
+
+    return Table->Value;
+}
+
+/* full decode using lookup table */
+static __inline mpc_int32_t
+mpc_decoder_huffman_decode_fastest(
+    mpc_decoder *d, 
+    const HuffmanTyp* Table, const mpc_uint8_t* tab, mpc_uint16_t unused_bits)
+{
+    // load preview and decode
+    mpc_uint32_t code  = d->dword << d->pos;
+
+    if (d->pos > unused_bits) {
+        code |= d->next >> (32 - d->pos);
+    }
+
+    Table+=tab [(size_t)(code >> unused_bits) ];
+
+    // set the new position within bitstream without performing a dummy-read
+    if ((d->pos += Table->Length) >= 32) {
+        mpc_move_next(d);
     }
 
@@ -289,4 +398,6 @@
 
     d->DecodedFrames  = 0;
+    d->SeekTableIndex = 0;
+    d->MaxDecodedFrames = 0;
     d->StreamVersion  = 0;
     d->MS_used        = 0;
@@ -314,13 +425,9 @@
                          mpc_uint32_t in_len, MPC_SAMPLE_FORMAT *out_buffer)
 {
-  unsigned int i;
   mpc_decoder_reset_bitstream_decode(d);
   if (in_len > sizeof(d->Speicher)) in_len = sizeof(d->Speicher);
   memcpy(d->Speicher, in_buffer, in_len);
-#ifdef MPC_LITTLE_ENDIAN
-  for (i = 0; i < (in_len + 3) / 4; i++)
-    d->Speicher[i] = mpc_swap32(d->Speicher[i]);
-#endif
-  d->dword = d->Speicher[0];
+   d->dword = SWAP(d->Speicher[0]);
+   d->next  = SWAP(d->Speicher[1]);
   switch (d->StreamVersion) {
 #ifdef MPC_SUPPORT_SV456
@@ -333,5 +440,5 @@
     case 0x07:
     case 0x17:
-        mpc_decoder_read_bitstream_sv7(d);
+        mpc_decoder_read_bitstream_sv7(d, FALSE);
         break;
     default:
@@ -353,4 +460,7 @@
         return (mpc_uint32_t)(-1);                           // end of file -> abort decoding
     }
+
+    if (d->DecodedFrames == 0 && d->Use_SeekTable)
+        d->SeekTable[0] = mpc_decoder_bits_read(d);
 
     // read jump-info for validity check of frame
@@ -371,5 +481,5 @@
     case 0x07:
     case 0x17:
-        mpc_decoder_read_bitstream_sv7(d);
+        mpc_decoder_read_bitstream_sv7(d, FALSE);
         break;
     default:
@@ -378,4 +488,21 @@
     d->FrameWasValid = mpc_decoder_bits_read(d) - FrameBitCnt == d->FwdJumpInfo;
 
+    d->DecodedFrames++;
+    if(d->DecodedFrames>13500)
+        printf("%u\n", d->DecodedFrames);
+
+    if (d->Use_SeekTable) {
+        if (d->SeekTable_Step == 1) {
+            d->SeekTable [d->DecodedFrames] = d->FwdJumpInfo + 20;
+        } else {
+            if ((d->DecodedFrames-1) % d->SeekTable_Step == 0) {
+                d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter;
+                d->SeekTableIndex  += 1;
+                d->SeekTableCounter = 0;
+            }
+            d->SeekTableCounter += d->FwdJumpInfo + 20;
+        }
+    }
+
     // synthesize signal
     mpc_decoder_requantisierung(d, d->Max_Band);
@@ -385,6 +512,4 @@
 
     mpc_decoder_synthese_filter_float(d, buffer);
-
-    d->DecodedFrames++;
 
     // cut off first MPC_DECODER_SYNTH_DELAY zero-samples
@@ -406,5 +531,5 @@
             } else {
                 mpc_decoder_bitstream_read(d, 20);
-                mpc_decoder_read_bitstream_sv7(d);
+                mpc_decoder_read_bitstream_sv7(d, FALSE);
                 mpc_decoder_requantisierung(d, d->Max_Band);
             }
@@ -472,5 +597,5 @@
 
         }
-        mpc_decoder_update_buffer(d, RING);
+        mpc_decoder_update_buffer(d);
 
         if (valid_samples > 0) {
@@ -887,5 +1012,5 @@
 /****************************************** SV 7 ******************************************/
 void
-mpc_decoder_read_bitstream_sv7(mpc_decoder *d) 
+mpc_decoder_read_bitstream_sv7(mpc_decoder *d, mpc_bool_t isFastSeeking) 
 {
     // these arrays hold decoding results for bundled quantizers (3- and 5-step)
@@ -904,4 +1029,6 @@
     mpc_int8_t   *ResL, *ResR;
     mpc_uint32_t tmp;
+    mpc_uint8_t *LUT;
+    mpc_uint8_t max_length;
 
     /***************************** Header *****************************/
@@ -914,4 +1041,6 @@
     if (d->MS_used && !(*ResL==0 && *ResR==0)) {
         d->MS_Flag[0] = mpc_decoder_bitstream_read(d, 1);
+    } else {
+        d->MS_Flag[0] = 0;
     }
 
@@ -928,4 +1057,6 @@
         if (d->MS_used && !(*ResL==0 && *ResR==0)) {
             d->MS_Flag[n] = mpc_decoder_bitstream_read(d, 1);
+        } else {
+            d->MS_Flag[n] = 0;
         }
 
@@ -957,30 +1088,30 @@
             {
             case 1:
-                idx  = mpc_decoder_huffman_decode_fast(d, mpc_table_HuffDSCF);
-                L[0] = (idx!=8) ? L[2] + idx : (int) mpc_decoder_bitstream_read(d, 6);
-                idx  = mpc_decoder_huffman_decode_fast(d, mpc_table_HuffDSCF);
-                L[1] = (idx!=8) ? L[0] + idx : (int) mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                L[0] = (idx!=8) ? SCF_DIFF(L[2], idx) : mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                L[1] = (idx!=8) ? SCF_DIFF(L[0], idx) : mpc_decoder_bitstream_read(d, 6);
                 L[2] = L[1];
                 break;
             case 3:
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                L[0] = (idx!=8) ? L[2] + idx : (int) mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                L[0] = (idx!=8) ? SCF_DIFF(L[2], idx) : mpc_decoder_bitstream_read(d, 6);
                 L[1] = L[0];
                 L[2] = L[1];
                 break;
             case 2:
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                L[0] = (idx!=8) ? L[2] + idx : (int) mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                L[0] = (idx!=8) ? SCF_DIFF(L[2], idx) : mpc_decoder_bitstream_read(d, 6);
                 L[1] = L[0];
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                L[2] = (idx!=8) ? L[1] + idx : (int) mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                L[2] = (idx!=8) ? SCF_DIFF(L[1], idx) : mpc_decoder_bitstream_read(d, 6);
                 break;
             case 0:
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                L[0] = (idx!=8) ? L[2] + idx : (int) mpc_decoder_bitstream_read(d, 6);
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                L[1] = (idx!=8) ? L[0] + idx : (int) mpc_decoder_bitstream_read(d, 6);
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                L[2] = (idx!=8) ? L[1] + idx : (int) mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                L[0] = (idx!=8) ? SCF_DIFF(L[2], idx) : mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                L[1] = (idx!=8) ? SCF_DIFF(L[0], idx) : mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                L[2] = (idx!=8) ? SCF_DIFF(L[1], idx) : mpc_decoder_bitstream_read(d, 6);
                 break;
             default:
@@ -997,30 +1128,30 @@
             {
             case 1:
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                R[0] = (idx!=8) ? R[2] + idx : (int) mpc_decoder_bitstream_read(d, 6);
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                R[1] = (idx!=8) ? R[0] + idx : (int) mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                R[0] = (idx!=8) ? SCF_DIFF(R[2], idx) : mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                R[1] = (idx!=8) ? SCF_DIFF(R[0], idx) : mpc_decoder_bitstream_read(d, 6);
                 R[2] = R[1];
                 break;
             case 3:
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                R[0] = (idx!=8) ? R[2] + idx : (int) mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                R[0] = (idx!=8) ? SCF_DIFF(R[2], idx) : mpc_decoder_bitstream_read(d, 6);
                 R[1] = R[0];
                 R[2] = R[1];
                 break;
             case 2:
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                R[0] = (idx!=8) ? R[2] + idx : (int) mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                R[0] = (idx!=8) ? SCF_DIFF(R[2], idx) : mpc_decoder_bitstream_read(d, 6);
                 R[1] = R[0];
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                R[2] = (idx!=8) ? R[1] + idx : (int) mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                R[2] = (idx!=8) ? SCF_DIFF(R[1], idx) : mpc_decoder_bitstream_read(d, 6);
                 break;
             case 0:
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                R[0] = (idx!=8) ? R[2] + idx : (int) mpc_decoder_bitstream_read(d, 6);
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                R[1] = (idx!=8) ? R[0] + idx : (int) mpc_decoder_bitstream_read(d, 6);
-                idx  = mpc_decoder_huffman_decode_fast(d,  mpc_table_HuffDSCF);
-                R[2] = (idx!=8) ? R[1] + idx : (int) mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                R[0] = (idx!=8) ? SCF_DIFF(R[2], idx) : mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                R[1] = (idx!=8) ? SCF_DIFF(R[0], idx) : mpc_decoder_bitstream_read(d, 6);
+                idx  = DECODE_DSCF();
+                R[2] = (idx!=8) ? SCF_DIFF(R[1], idx) : mpc_decoder_bitstream_read(d, 6);
                 break;
             default:
@@ -1032,4 +1163,8 @@
         }
     }
+
+    if(isFastSeeking)
+        return;
+
     /***************************** Samples ****************************/
     ResL = d->Res_L;
@@ -1056,8 +1191,16 @@
             break;
         case 1:
-            Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][1];
+            if (mpc_decoder_bitstream_read(d, 1)) {
+                Table = mpc_table_HuffQ[1][1];
+                LUT = LUT1_1;
+                max_length = 9;
+            } else {
+                Table = mpc_table_HuffQ[0][1];
+                LUT = LUT1_0;
+                max_length = 6;
+            }
             for (k=0; k<12; ++k)
             {
-                idx = mpc_decoder_huffman_decode_fast(d,  Table);
+                idx   = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
                 *LQ++ = idx30[idx];
                 *LQ++ = idx31[idx];
@@ -1066,8 +1209,16 @@
             break;
         case 2:
-            Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][2];
+            if (mpc_decoder_bitstream_read(d, 1)) {
+                Table = mpc_table_HuffQ[1][2];
+                LUT = LUT2_1;
+                max_length = 10;
+            } else {
+                Table = mpc_table_HuffQ[0][2];
+                LUT = LUT2_0;
+                max_length = 7;
+            }
             for (k=0; k<18; ++k)
             {
-                idx = mpc_decoder_huffman_decode_fast(d,  Table);
+                idx   = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
                 *LQ++ = idx50[idx];
                 *LQ++ = idx51[idx];
@@ -1075,24 +1226,76 @@
             break;
         case 3:
+            if (mpc_decoder_bitstream_read(d, 1)) {
+                Table = mpc_table_HuffQ[1][3];
+                LUT = LUT3_1;
+                max_length = 5;
+            } else {
+                Table = mpc_table_HuffQ[0][3];
+                LUT = LUT3_0;
+                max_length = 4;
+            }
+            for (k=0; k<36; ++k)
+                *LQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
+            break;
         case 4:
-            Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResL];
+            if (mpc_decoder_bitstream_read(d, 1)) {
+                Table = mpc_table_HuffQ[1][4];
+                LUT = LUT4_1;
+                max_length = 5;
+            } else {
+                Table = mpc_table_HuffQ[0][4];
+                LUT = LUT4_0;
+                max_length = 4;
+            }
             for (k=0; k<36; ++k)
-                *LQ++ = mpc_decoder_huffman_decode_faster(d, Table);
+                *LQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
             break;
         case 5:
-            Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResL];
+            if (mpc_decoder_bitstream_read(d, 1)) {
+                Table = mpc_table_HuffQ[1][5];
+                LUT = LUT5_1;
+                max_length = 8;
+            } else {
+                Table = mpc_table_HuffQ[0][5];
+                LUT = LUT5_0;
+                max_length = 6;
+            }
             for (k=0; k<36; ++k)
-                *LQ++ = mpc_decoder_huffman_decode_fast(d, Table);
+                *LQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
             break;
         case 6:
+            if (mpc_decoder_bitstream_read(d, 1)) {
+                Table = mpc_table_HuffQ[1][6];
+                LUT = LUT6_1;
+                max_length = 7;
+                for (k=0; k<36; ++k)
+                    *LQ++ = HUFFMAN_DECODE_FASTERER ( d, Table, LUT, max_length );
+            } else {
+                Table = mpc_table_HuffQ[0][6];
+                LUT = LUT6_0;
+                max_length = 7;
+                for (k=0; k<36; ++k)
+                    *LQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
+            }
+            break;
         case 7:
-            Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResL];
-            for (k=0; k<36; ++k)
-                *LQ++ = mpc_decoder_huffman_decode(d, Table);
+            if (mpc_decoder_bitstream_read(d, 1)) {
+                Table = mpc_table_HuffQ[1][7];
+                LUT = LUT7_1;
+                max_length = 8;
+                for (k=0; k<36; ++k)
+                    *LQ++ = HUFFMAN_DECODE_FASTERER ( d, Table, LUT, max_length );
+            } else {
+                Table = mpc_table_HuffQ[0][7];
+                LUT = LUT7_0;
+                max_length = 8;
+                for (k=0; k<36; ++k)
+                    *LQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
+            }
             break;
         case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17:
             tmp = Dc[*ResL];
             for (k=0; k<36; ++k)
-                *LQ++ = (mpc_int32_t)mpc_decoder_bitstream_read(d, Res_bit[*ResL]) - tmp;
+                *LQ++ = (mpc_int16_t) mpc_decoder_bitstream_read(d, Res_bit[*ResL]) - tmp;
             break;
         default:
@@ -1116,8 +1319,16 @@
                 break;
             case 1:
-                Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][1];
+                if (mpc_decoder_bitstream_read(d, 1)) {
+                    Table = mpc_table_HuffQ[1][1];
+                    LUT = LUT1_1;
+                    max_length = 9;
+                } else {
+                    Table = mpc_table_HuffQ[0][1];
+                    LUT = LUT1_0;
+                    max_length = 6;
+                }
                 for (k=0; k<12; ++k)
                 {
-                    idx = mpc_decoder_huffman_decode_fast(d, Table);
+                    idx = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
                     *RQ++ = idx30[idx];
                     *RQ++ = idx31[idx];
@@ -1126,8 +1337,16 @@
                 break;
             case 2:
-                Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][2];
+                if (mpc_decoder_bitstream_read(d, 1)) {
+                    Table = mpc_table_HuffQ[1][2];
+                    LUT = LUT2_1;
+                    max_length = 10;
+                } else {
+                    Table = mpc_table_HuffQ[0][2];
+                    LUT = LUT2_0;
+                    max_length = 7;
+                }
                 for (k=0; k<18; ++k)
                 {
-                    idx = mpc_decoder_huffman_decode_fast(d, Table);
+                    idx = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
                     *RQ++ = idx50[idx];
                     *RQ++ = idx51[idx];
@@ -1135,24 +1354,76 @@
                 break;
             case 3:
+                if (mpc_decoder_bitstream_read(d, 1)) {
+                    Table = mpc_table_HuffQ[1][3];
+                    LUT = LUT3_1;
+                    max_length = 5;
+                } else {
+                    Table = mpc_table_HuffQ[0][3];
+                    LUT = LUT3_0;
+                    max_length = 4;
+                }
+                for (k=0; k<36; ++k)
+                    *RQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
+                break;
             case 4:
-                Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResR];
+                if (mpc_decoder_bitstream_read(d, 1)) {
+                    Table = mpc_table_HuffQ[1][4];
+                    LUT = LUT4_1;
+                    max_length = 5;
+                } else {
+                    Table = mpc_table_HuffQ[0][4];
+                    LUT = LUT4_0;
+                    max_length = 4;
+                }
                 for (k=0; k<36; ++k)
-                    *RQ++ = mpc_decoder_huffman_decode_faster(d, Table);
+                    *RQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
                 break;
             case 5:
-                Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResR];
+                if (mpc_decoder_bitstream_read(d, 1)) {
+                    Table = mpc_table_HuffQ[1][5];
+                    LUT = LUT5_1;
+                    max_length = 8;
+                } else {
+                    Table = mpc_table_HuffQ[0][5];
+                    LUT = LUT5_0;
+                    max_length = 6;
+                }
                 for (k=0; k<36; ++k)
-                    *RQ++ = mpc_decoder_huffman_decode_fast(d, Table);
+                    *RQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
                 break;
             case 6:
+                if (mpc_decoder_bitstream_read(d, 1)) {
+                    Table = mpc_table_HuffQ[1][6];
+                    LUT = LUT6_1;
+                    max_length = 7;
+                    for (k=0; k<36; ++k)
+                        *RQ++ = HUFFMAN_DECODE_FASTERER ( d, Table, LUT, max_length );
+                } else {
+                    Table = mpc_table_HuffQ[0][6];
+                    LUT = LUT6_0;
+                    max_length = 7;
+                    for (k=0; k<36; ++k)
+                        *RQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
+                }
+                break;
             case 7:
-                Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResR];
-                for (k=0; k<36; ++k)
-                    *RQ++ = mpc_decoder_huffman_decode(d, Table);
+                if (mpc_decoder_bitstream_read(d, 1)) {
+                    Table = mpc_table_HuffQ[1][7];
+                    LUT = LUT7_1;
+                    max_length = 8;
+                    for (k=0; k<36; ++k)
+                        *RQ++ = HUFFMAN_DECODE_FASTERER ( d, Table, LUT, max_length );
+                } else {
+                    Table = mpc_table_HuffQ[0][7];
+                    LUT = LUT7_0;
+                    max_length = 8;
+                    for (k=0; k<36; ++k)
+                        *RQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length );
+                }
                 break;
             case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17:
                 tmp = Dc[*ResR];
                 for (k=0; k<36; ++k)
-                    *RQ++ = (mpc_int32_t)mpc_decoder_bitstream_read(d, Res_bit[*ResR]) - tmp;
+                    *RQ++ = (mpc_int16_t) mpc_decoder_bitstream_read(d, Res_bit[*ResR]) - tmp;
                 break;
             default:
@@ -1174,4 +1445,5 @@
   d->OverallFrames = 0;
   d->DecodedFrames = 0;
+  d->MaxDecodedFrames = 0;
   d->TrueGaplessPresent = 0;
   d->WordsRead = 0;
@@ -1184,16 +1456,50 @@
   d->pos = 0;
   d->Zaehler = 0;
+  d->Ring = 0;
   d->WordsRead = 0;
   d->Max_Band = 0;
+  d->SeekTable = NULL;
+  d->Use_FastSeek = TRUE;
+  d->Use_SeekTable = TRUE;
+  d->Use_StaticSeekTable = FALSE;
+  d->SeekTable_Step = 1;
+  d->SeekTableIndex = 0;
+  d->SeekTableCounter = 0;
+  d->Max_SeekTable_Size = 0;
 
   mpc_decoder_initialisiere_quantisierungstabellen(d, 1.0f);
 #if 0
-  mpc_decoder_init_huffman_sv6(d);
-  mpc_decoder_init_huffman_sv7(d);
+    mpc_decoder_init_huffman_sv6(d);
+    mpc_decoder_init_huffman_sv7(d);
 #endif
+
+  LOOKUP ( mpc_table_HuffQ[0][1], 27, LUT1_0  );
+  LOOKUP ( mpc_table_HuffQ[1][1], 27, LUT1_1  );
+  LOOKUP ( mpc_table_HuffQ[0][2], 25, LUT2_0  );
+  LOOKUP ( mpc_table_HuffQ[1][2], 25, LUT2_1  );
+  LOOKUP ( mpc_table_HuffQ[0][3], 7,  LUT3_0  );
+  LOOKUP ( mpc_table_HuffQ[1][3], 7,  LUT3_1  );
+  LOOKUP ( mpc_table_HuffQ[0][4], 9,  LUT4_0  );
+  LOOKUP ( mpc_table_HuffQ[1][4], 9,  LUT4_1  );
+  LOOKUP ( mpc_table_HuffQ[0][5], 15, LUT5_0  );
+  LOOKUP ( mpc_table_HuffQ[1][5], 15, LUT5_1  );
+  LOOKUP ( mpc_table_HuffQ[0][6], 31, LUT6_0  );
+  LOOKUP ( mpc_table_HuffQ[1][6], 31, LUT6_1  );
+  LOOKUP ( mpc_table_HuffQ[0][7], 63, LUT7_0  );
+  LOOKUP ( mpc_table_HuffQ[1][7], 63, LUT7_1  );
+  LOOKUP ( mpc_table_HuffDSCF,    16, LUTDSCF );
+}
+
+void mpc_decoder_destroy(mpc_decoder *d)
+{
+    free(d->Speicher);
+    if (d->SeekTable != NULL && d->Use_StaticSeekTable == FALSE)
+        free(d->SeekTable);
 }
 
 void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si)
 {
+    mpc_uint16_t seekTableSize;
+
     mpc_decoder_reset_synthesis(d);
     mpc_decoder_reset_globals(d);
@@ -1208,23 +1514,50 @@
 
     d->samples_to_skip = MPC_DECODER_SYNTH_DELAY;
+
+    if (d->SeekTable != NULL && d->Use_StaticSeekTable == FALSE)
+        free(d->SeekTable);
+
+    if (d->Use_SeekTable) {
+        if (d->Use_StaticSeekTable == FALSE) {
+            if (d->Max_SeekTable_Size == 0) {
+                seekTableSize = si->frames +1;
+            } else {
+                seekTableSize = min(si->frames +1, d->Max_SeekTable_Size / sizeof(mpc_uint32_t));
+            }
+            d->SeekTable = (mpc_uint32_t*) calloc(seekTableSize, sizeof(mpc_uint32_t));
+            d->SeekTable_Step = (si->frames +1) / seekTableSize;
+            if ((si->frames +1) % seekTableSize)
+                d->SeekTable_Step+=1;
+        } else {
+            seekTableSize = d->Max_SeekTable_Size / sizeof(mpc_uint32_t);
+            d->SeekTable_Step = (si->frames +1) / seekTableSize;
+            if ((si->frames +1) % seekTableSize)
+                d->SeekTable_Step+=1;
+        }
+    }
 }
 
 mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si) 
 {
+    mpc_uint32_t bitPos;
+    mpc_uint32_t fpos;
+
+    d->Speicher = malloc(MPC_DECODER_MEMSIZE * sizeof(mpc_uint32_t));
     mpc_decoder_set_streaminfo(d, si);
 
-    // AB: setting position to the beginning of the data-bitstream
-    switch (d->StreamVersion) {
-    case 0x04: f_seek(d, 4 + d->MPCHeaderPos); d->pos = 16; break;  // Geht auch über eine der Helperfunktionen
-    case 0x05:
-    case 0x06: f_seek(d, 8 + d->MPCHeaderPos); d->pos =  0; break;
-    case 0x07:
-    case 0x17: /*f_seek ( 24 + d->MPCHeaderPos );*/ d->pos =  8; break;
-    default: return FALSE;
-    }
-
-    // AB: fill buffer and initialize decoder
+     // setting position to the beginning of the data-bitstream
+     bitPos = get_initial_fpos(d, d->StreamVersion);
+     fpos = bitPos >> 5;
+
+    // fill buffer and initialize decoder
+  	f_seek(d, fpos*4 + d->MPCHeaderPos);
     f_read_dword(d, d->Speicher, MEMSIZE );
-    d->dword = d->Speicher[d->Zaehler = 0];
+    d->Ring = 0;
+    d->Zaehler = 0;
+    d->pos = bitPos & 31;
+    d->WordsRead = fpos;
+    d->dword = SWAP(d->Speicher[0]);
+    d->next = SWAP(d->Speicher[1]);
+    d->SeekTable_Step = 1;
 
     return TRUE;
@@ -1241,8 +1574,7 @@
     f_seek(d, (bitpos >> 5) * 4 + d->MPCHeaderPos);
     f_read_dword(d, d->Speicher, 2);
-    d->dword = d->Speicher[d->Zaehler = 0];
+    d->dword = SWAP(d->Speicher[d->Zaehler = 0]);
     d->pos = bitpos & 31;
 }
-#endif
 
 static void
@@ -1251,9 +1583,8 @@
     f_seek(d, (bitpos>>5) * 4 + d->MPCHeaderPos);
     f_read_dword(d, d->Speicher, MEMSIZE);
-    d->dword = d->Speicher[d->Zaehler = 0];
+    d->dword = SWAP(d->Speicher[d->Zaehler = 0]);
     d->pos = bitpos & 31;
 }
 
-#if 0
 static void
 helper3(mpc_decoder *d, mpc_uint32_t bitpos, mpc_uint32_t* buffoffs) 
@@ -1266,7 +1597,25 @@
         f_read_dword(d, d->Speicher, MEMSIZE );
     }
-    d->dword = d->Speicher[d->Zaehler = bitpos - *buffoffs ];
+    d->dword = SWAP(d->Speicher[d->Zaehler = bitpos - *buffoffs ]);
 }
 #endif
+
+// jumps over the current frame
+mpc_uint32_t mpc_decoder_jump_frame(mpc_decoder *d) {
+
+    mpc_uint32_t frameSize;
+
+    // ensure the buffer is full
+    mpc_decoder_update_buffer(d);
+
+    // bits in frame
+    frameSize = mpc_decoder_bitstream_read(d, 20);
+
+    // jump forward
+    mpc_decoder_seek_forward(d, frameSize);
+
+    return frameSize + 20;
+
+}
 
 static mpc_uint32_t get_initial_fpos(mpc_decoder *d, mpc_uint32_t StreamVersion)
@@ -1289,16 +1638,15 @@
 }
 
-mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample) 
-{
-    mpc_uint32_t fpos;
-    mpc_uint32_t fwd;
-
-    fwd = (mpc_uint32_t) (destsample / MPC_FRAME_LENGTH);
-    d->samples_to_skip = MPC_DECODER_SYNTH_DELAY + (mpc_uint32_t)(destsample % MPC_FRAME_LENGTH);
+void mpc_decoder_reset_state(mpc_decoder *d) {
 
     memset(d->Y_L          , 0, sizeof d->Y_L           );
     memset(d->Y_R          , 0, sizeof d->Y_R           );
+#ifdef SCF_HACK
+    memset(d->SCF_Index_L     , -128, sizeof d->SCF_Index_L      );
+    memset(d->SCF_Index_R     , -128, sizeof d->SCF_Index_R      );
+#else
     memset(d->SCF_Index_L     , 0, sizeof d->SCF_Index_L      );
     memset(d->SCF_Index_R     , 0, sizeof d->SCF_Index_R      );
+#endif
     memset(d->Res_L           , 0, sizeof d->Res_L            );
     memset(d->Res_R           , 0, sizeof d->Res_R            );
@@ -1313,31 +1661,167 @@
     memset(d->Q               , 0, sizeof d->Q                );
     memset(d->MS_Flag         , 0, sizeof d->MS_Flag          );
-
-    // resetting synthesis filter to avoid "clicks"
-    mpc_decoder_reset_synthesis(d);
+}
+
+mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample) 
+{
+    mpc_uint32_t fpos;
+    mpc_uint32_t seekFrame = 0;   // the frame to seek to
+    mpc_uint32_t lastFrame = 0;   // last frame to seek to before scanning scale factors
+    mpc_uint32_t delta = 0;       // direction of seeks
+
+     destsample += MPC_DECODER_SYNTH_DELAY;
+     seekFrame = (mpc_uint32_t) ((destsample) / MPC_FRAME_LENGTH);
+     d->samples_to_skip = (mpc_uint32_t)((destsample) % MPC_FRAME_LENGTH);
 
     // prevent from desired position out of allowed range
-    fwd = fwd < d->OverallFrames  ?  fwd  :  d->OverallFrames;
-
-    // reset number of decoded frames
-    d->DecodedFrames = 0;
-
-    fpos = get_initial_fpos(d, d->StreamVersion);
-    if (fpos == 0) {
-        return FALSE;
-    }
-
-    helper2(d, fpos);
-
-    // read the last 32 frames before the desired position to scan the scalefactors (artifactless jumping)
-    for ( ; d->DecodedFrames < fwd; d->DecodedFrames++ ) {
+    seekFrame = seekFrame < d->OverallFrames  ?  seekFrame  :  d->OverallFrames;
+
+    // seek direction (note: avoids casting to int64)
+    delta = (d->DecodedFrames > seekFrame ? -(mpc_int32_t)(d->DecodedFrames - seekFrame) : (mpc_int32_t)(seekFrame - d->DecodedFrames));
+
+    // update max decoded frames
+    if (d->DecodedFrames > d->MaxDecodedFrames)
+        d->MaxDecodedFrames = d->DecodedFrames;
+
+    if (seekFrame > 33)
+        lastFrame = seekFrame - 33 + 1 - d->SeekTable_Step;
+
+    if ((!d->Use_SeekTable && delta < 0) || d->MaxDecodedFrames == 0)
+    {
+
+        mpc_decoder_reset_state(d);
+
+        // starts from the beginning since no frames have been decoded yet, or not using seek table
+        fpos = get_initial_fpos(d, d->StreamVersion);
+
+        // seek to the first frame
+        mpc_decoder_seek_to(d, fpos);
+
+        // reset number of decoded frames
+        d->DecodedFrames = 0;
+
+        if (d->Use_SeekTable)
+        {
+            // jump to the last frame, updating seek table
+            if (d->SeekTable_Step == 1)
+            {
+                d->SeekTable[0] = (mpc_uint32_t)fpos;
+                for (;d->DecodedFrames < lastFrame; d->DecodedFrames++)
+                    d->SeekTable[d->DecodedFrames+1] = mpc_decoder_jump_frame(d);
+            }
+            else
+            {
+                d->SeekTableIndex = 0;
+                d->SeekTableCounter = (mpc_uint32_t)fpos;
+                for (;d->DecodedFrames < lastFrame; d->DecodedFrames++)
+                {
+                    if (d->DecodedFrames % d->SeekTable_Step == 0)
+                    {
+                        d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter;
+                        d->SeekTableIndex += 1;
+                        d->SeekTableCounter = 0;
+                    }
+                    d->SeekTableCounter += mpc_decoder_jump_frame(d);
+                }
+            }
+        }
+        else
+        {
+            // just jump to the last frame
+            for (;d->DecodedFrames < lastFrame; d->DecodedFrames++)
+                mpc_decoder_jump_frame(d);
+        }
+    } 
+    else if (delta < 0)
+    {
+
+        mpc_decoder_reset_state(d);
+
+        // jumps backwards using the seek table
+        fpos = d->SeekTable[0];
+        if (d->SeekTable_Step == 1)
+        {
+            for (d->DecodedFrames = 0;d->DecodedFrames < lastFrame; d->DecodedFrames++)
+            fpos += d->SeekTable[d->DecodedFrames+1];
+        }
+        else
+        {
+            d->SeekTableIndex = 0;
+            //d->SeekTableCounter = 0;
+            for (d->DecodedFrames = 0;d->DecodedFrames < lastFrame; d->DecodedFrames+=d->SeekTable_Step, d->SeekTableIndex++)
+                fpos += d->SeekTable[d->SeekTableIndex+1];
+            d->SeekTableCounter = d->SeekTable[d->SeekTableIndex];
+        }
+        mpc_decoder_seek_to(d, fpos);
+
+    }
+    else if (delta > 33)
+    {
+
+        mpc_decoder_reset_state(d);
+
+        // jumps forward from the current position
+        if (d->Use_SeekTable)
+        {
+            if (d->MaxDecodedFrames > lastFrame) // REVIEW: Correct?? or (d->MaxDecodedFrames > d->DecodedFrames)
+            { 
+                // jump to the last usable position in the seek table
+                if (d->SeekTable_Step == 1)
+                {
+                    fpos = mpc_decoder_bits_read(d);
+                    for (; d->DecodedFrames < d->MaxDecodedFrames && d->DecodedFrames < lastFrame; d->DecodedFrames++)
+                        fpos += d->SeekTable[d->DecodedFrames+1];
+                } 
+                else
+                {
+                    // could test SeekTable offset and jump to next entry but this is easier for now...
+                    //d->SeekTableIndex = 0;
+                    //d->SeekTableCounter = 0;
+                    fpos = d->SeekTable[0];
+                    d->SeekTableIndex = 0;
+                    for (d->DecodedFrames = 0;d->DecodedFrames < d->MaxDecodedFrames && d->DecodedFrames < lastFrame; d->DecodedFrames+=d->SeekTable_Step, d->SeekTableIndex++)
+                        fpos += d->SeekTable[d->SeekTableIndex+1];
+                    d->SeekTableCounter = d->SeekTable[d->SeekTableIndex];
+                }
+                mpc_decoder_seek_to(d, fpos);
+            }
+
+            if (d->SeekTable_Step == 1) 
+            {
+                for (;d->DecodedFrames < lastFrame; d->DecodedFrames++)
+                    d->SeekTable[d->DecodedFrames+1] = mpc_decoder_jump_frame(d);
+            }
+            else 
+            {
+                for (;d->DecodedFrames < lastFrame; d->DecodedFrames++)
+                {
+                    if (d->DecodedFrames % d->SeekTable_Step == 0)
+                    {
+                        d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter;
+                        d->SeekTableIndex += 1;
+                        d->SeekTableCounter = 0;
+                    }
+                    d->SeekTableCounter += mpc_decoder_jump_frame(d);
+                }
+            }
+        } 
+        else 
+        {
+            for (;d->DecodedFrames < lastFrame; d->DecodedFrames++)
+                mpc_decoder_jump_frame(d);
+        }
+    }
+
+    // REVIEW: Needed?
+    mpc_decoder_update_buffer(d);
+
+    for (;d->DecodedFrames < seekFrame; d->DecodedFrames++) {
         mpc_uint32_t   FrameBitCnt;
-        mpc_uint32_t   RING;
-        RING         = d->Zaehler;
         d->FwdJumpInfo  = mpc_decoder_bitstream_read(d, 20);    // read jump-info
         d->ActDecodePos = (d->Zaehler << 5) + d->pos;
-        FrameBitCnt  = mpc_decoder_bits_read(d);  // scanning the scalefactors and check for validity of frame
+        FrameBitCnt  = mpc_decoder_bits_read(d);
+  	    // scanning the scalefactors (and check for validity of frame)
         if (d->StreamVersion >= 7)  {
-            mpc_decoder_read_bitstream_sv7(d);
+            mpc_decoder_read_bitstream_sv7(d, d->Use_FastSeek && (d->DecodedFrames < seekFrame - 1));
         }
         else {
@@ -1348,27 +1832,114 @@
 #endif
         }
-        if (mpc_decoder_bits_read(d) - FrameBitCnt != d->FwdJumpInfo ) {
-            // Box ("Bug in perform_jump");
+        FrameBitCnt = mpc_decoder_bits_read(d) - FrameBitCnt;
+
+        if (d->Use_FastSeek && d->FwdJumpInfo > FrameBitCnt)
+            mpc_decoder_seek_forward(d, d->FwdJumpInfo - FrameBitCnt);
+        else if (FrameBitCnt != d->FwdJumpInfo )
+            // Bug in perform_jump;
             return FALSE;
-        }
+
+        // REVIEW: Only if decodedFrames < maxDecodedFrames??
+        if (d->Use_SeekTable)
+        {
+            if (d->SeekTable_Step == 1)
+            {
+                // check that the frame length corresponds with any data already in the seek table
+                if (d->SeekTable[d->DecodedFrames+1] != 0 && d->SeekTable[d->DecodedFrames+1] != d->FwdJumpInfo + 20)
+                    return FALSE;
+                d->SeekTable [d->DecodedFrames+1] = d->FwdJumpInfo + 20;
+            }
+            else
+            {
+                if (d->DecodedFrames % d->SeekTable_Step == 0)
+                {
+                    if (d->SeekTable[d->SeekTableIndex] != 0 && d->SeekTable[d->SeekTableIndex] != d->SeekTableCounter)
+                        return FALSE;
+                    d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter;
+                    d->SeekTableIndex += 1;
+                    d->SeekTableCounter = 0;
+                }
+                d->SeekTableCounter += d->FwdJumpInfo + 20;
+            }
+        }
+
         // update buffer
-        if ((RING ^ d->Zaehler) & MEMSIZE2) {
-            f_read_dword(d, d->Speicher + (RING & MEMSIZE2),  MEMSIZE2);
-        }
-    }
-
-    // LastBitsRead = BitsRead ();
-    // LastFrame = d->DecodedFrames;
+        mpc_decoder_update_buffer(d);
+
+        if (d->DecodedFrames == seekFrame - 1)
+        {
+            // initialize the synth correctly for perfect decoding
+            mpc_decoder_requantisierung(d, d->Max_Band);
+            mpc_decoder_synthese_filter_float(d, NULL);
+        }
+    }
 
     return TRUE;
 }
 
-void mpc_decoder_update_buffer(mpc_decoder *d, mpc_uint32_t RING) 
-{
-    if ((RING ^ d->Zaehler) & MEMSIZE2 ) {
+void mpc_decoder_fill_buffer(mpc_decoder *d)
+{
+    f_read_dword(d, d->Speicher, MEMSIZE);
+    d->dword = SWAP(d->Speicher[d->Zaehler = 0]);
+    d->next = SWAP(d->Speicher[1]);
+    d->Ring = 0;
+}
+
+void mpc_decoder_update_buffer(mpc_decoder *d) 
+{
+    if ((d->Ring ^ d->Zaehler) & MEMSIZE2) {
         // update buffer
-        f_read_dword(d, d->Speicher + (RING & MEMSIZE2), MEMSIZE2);
-    }
-}
-
-
+        f_read_dword(d, d->Speicher + (d->Ring & MEMSIZE2), MEMSIZE2);
+        d->Ring = d->Zaehler;
+    }
+}
+
+
+void mpc_decoder_seek_to(mpc_decoder *d, mpc_uint32_t bitPos)
+{
+    // required dword
+    mpc_uint32_t fpos = (bitPos >> 5);
+    mpc_uint32_t bufferStart = d->WordsRead - d->Zaehler;
+    if ((d->Zaehler & MEMSIZE2) != FALSE)
+        bufferStart += MEMSIZE2;
+
+    if (fpos >= bufferStart && fpos < bufferStart + MEMSIZE)
+    {
+        // required position is within the buffer, no need to seek
+        d->Zaehler = (fpos - bufferStart + ((d->Zaehler & MEMSIZE2) != FALSE ? MEMSIZE2 : 0)) & MEMMASK;
+        d->pos = bitPos & 31;
+        d->WordsRead = fpos;
+        d->dword = SWAP(d->Speicher[d->Zaehler]);
+        d->next = SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]);
+
+        mpc_decoder_update_buffer(d);
+    } 
+    else
+    {
+        // DWORD aligned
+        f_seek(d, fpos*4 + d->MPCHeaderPos);
+        d->Zaehler = 0;
+        d->pos = bitPos & 31;
+        d->WordsRead = fpos;
+
+        mpc_decoder_fill_buffer(d);
+    }
+}
+
+void mpc_decoder_seek_forward(mpc_decoder *d, mpc_uint32_t bits)
+{  	 
+    bits += d->pos;
+    d->pos = bits & 31;
+    bits = bits >> 5; // to DWORDs
+    d->Zaehler = (d->Zaehler + bits) & MEMMASK;
+    d->dword = SWAP(d->Speicher[d->Zaehler]);
+    d->next = SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]);
+    d->WordsRead += bits;
+}
+
+void mpc_decoder_set_seek_table(mpc_decoder *d, mpc_uint32_t *seek_table, mpc_uint32_t max_table_size)
+{
+    d->Use_StaticSeekTable = TRUE;
+    d->SeekTable = seek_table;
+    d->Max_SeekTable_Size = max_table_size;
+}
Index: /branches/zorg/src/sample.cpp
===================================================================
--- /branches/zorg/src/sample.cpp	(revision 23)
+++ /branches/zorg/src/sample.cpp	(revision 24)
@@ -329,4 +329,5 @@
     }
 
+    mpc_decoder_destroy(&decoder);
 #ifdef WIN32
     assert(_CrtCheckMemory());
