Index: branches/zorg/src/mpc_decoder.c
===================================================================
--- branches/zorg/src/mpc_decoder.c	(revision 18)
+++ branches/zorg/src/mpc_decoder.c	(revision 21)
@@ -59,4 +59,36 @@
 #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 +108,20 @@
 //------------------------------------------------------------------------------
 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 fastSeeking);
+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);
+
+mpc_uint32_t  Speicher[MPC_DECODER_MEMSIZE];
+MPC_SAMPLE_FORMAT Y_L[36][32];
+MPC_SAMPLE_FORMAT Y_R[36][32];
 
 //------------------------------------------------------------------------------
@@ -129,4 +173,5 @@
 {
     d->dword = 0;
+    d->next = 0;
     d->pos = 0;
     d->Zaehler = 0;
@@ -141,6 +186,14 @@
 }
 
+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 +206,30 @@
     }
     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;
+    size_t    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;
 }
 
@@ -173,6 +242,7 @@
     // load preview and decode
     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 +252,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);
     }
 
@@ -198,6 +266,7 @@
     // load preview and decode
     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 +276,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);
     }
 
@@ -222,6 +289,7 @@
     // load preview and decode
     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 +299,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);
     }
 
@@ -246,6 +312,7 @@
     // load preview and decode
     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 +322,51 @@
     // 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);
     }
 
@@ -279,6 +390,6 @@
 mpc_decoder_reset_y(mpc_decoder *d) 
 {
-    memset(d->Y_L, 0, sizeof d->Y_L);
-    memset(d->Y_R, 0, sizeof d->Y_R);
+    memset(d->Y_L, 0, sizeof Y_L);
+    memset(d->Y_R, 0, sizeof Y_R);
 }
 
@@ -289,9 +400,11 @@
 
     d->DecodedFrames  = 0;
+    d->SeekTableIndex = 0;
+    d->MaxDecodedFrames = 0;
     d->StreamVersion  = 0;
     d->MS_used        = 0;
 
-    memset(d->Y_L          , 0, sizeof d->Y_L           );
-    memset(d->Y_R          , 0, sizeof d->Y_R           );
+    memset(d->Y_L          , 0, sizeof Y_L           );
+    memset(d->Y_R          , 0, sizeof Y_R           );
     memset(d->SCF_Index_L     , 0, sizeof d->SCF_Index_L      );
     memset(d->SCF_Index_R     , 0, sizeof d->SCF_Index_R      );
@@ -314,13 +427,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);
+  if (in_len > sizeof(Speicher)) in_len = sizeof(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 +442,5 @@
     case 0x07:
     case 0x17:
-        mpc_decoder_read_bitstream_sv7(d);
+        mpc_decoder_read_bitstream_sv7(d, FALSE);
         break;
     default:
@@ -350,7 +459,25 @@
     mpc_uint32_t  FrameBitCnt = 0;
 
+    // output the last part of the last frame here, if needed
+    if (d->last_block_samples > 0) {
+        output_frame_length = d->last_block_samples;
+        d->last_block_samples = 0; // it's going to be handled now, so reset it 
+        if (!d->TrueGaplessPresent) {
+            mpc_decoder_reset_y(d);
+        } else {
+            mpc_decoder_bitstream_read(d, 20);
+            mpc_decoder_read_bitstream_sv7(d, FALSE);
+            mpc_decoder_requantisierung(d, d->Max_Band);
+        }
+        mpc_decoder_synthese_filter_float(d, buffer);
+        return output_frame_length;
+    }
+    
     if (d->DecodedFrames >= d->OverallFrames) {
         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 +498,5 @@
     case 0x07:
     case 0x17:
-        mpc_decoder_read_bitstream_sv7(d);
+        mpc_decoder_read_bitstream_sv7(d, FALSE);
         break;
     default:
@@ -378,4 +505,19 @@
     d->FrameWasValid = mpc_decoder_bits_read(d) - FrameBitCnt == d->FwdJumpInfo;
 
+    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 +527,4 @@
 
     mpc_decoder_synthese_filter_float(d, buffer);
-
-    d->DecodedFrames++;
 
     // cut off first MPC_DECODER_SYNTH_DELAY zero-samples
@@ -402,16 +542,7 @@
         // additional FilterDecay samples are needed for decay of synthesis filter
         if (MPC_DECODER_SYNTH_DELAY + mod_block >= MPC_FRAME_LENGTH) {
-            if (!d->TrueGaplessPresent) {
-                mpc_decoder_reset_y(d);
-            } else {
-                mpc_decoder_bitstream_read(d, 20);
-                mpc_decoder_read_bitstream_sv7(d);
-                mpc_decoder_requantisierung(d, d->Max_Band);
-            }
-
-            mpc_decoder_synthese_filter_float(d, buffer + 2304);
-
-            output_frame_length = MPC_FRAME_LENGTH + FilterDecay;
-        }
+            // this variable will be checked for at the top of the function
+            d->last_block_samples = FilterDecay;
+            }
         else {                              // there are only FilterDecay samples needed for this frame
             output_frame_length = FilterDecay;
@@ -428,6 +559,10 @@
             memmove(
                 buffer, 
-                buffer + d->samples_to_skip * 2, 
-                output_frame_length * 2 * sizeof (MPC_SAMPLE_FORMAT));
+                buffer + d->samples_to_skip, 
+                output_frame_length * sizeof (MPC_SAMPLE_FORMAT));
+            memmove(
+                buffer + MPC_FRAME_LENGTH, 
+                buffer + MPC_FRAME_LENGTH + d->samples_to_skip, 
+                output_frame_length * sizeof (MPC_SAMPLE_FORMAT));
             d->samples_to_skip = 0;
         }
@@ -472,5 +607,5 @@
 
         }
-        mpc_decoder_update_buffer(d, RING);
+        mpc_decoder_update_buffer(d);
 
         if (valid_samples > 0) {
@@ -683,6 +818,6 @@
     const HuffmanTyp *x1;
     const HuffmanTyp *x2;
-    mpc_int8_t  *L;
-    mpc_int8_t  *R;
+    mpc_int8_t *L;
+    mpc_int8_t *R;
     mpc_int16_t *QL;
     mpc_int16_t *QR;
@@ -887,5 +1022,5 @@
 /****************************************** SV 7 ******************************************/
 void
-mpc_decoder_read_bitstream_sv7(mpc_decoder *d) 
+mpc_decoder_read_bitstream_sv7(mpc_decoder *d, mpc_bool_t fastSeeking) 
 {
     // these arrays hold decoding results for bundled quantizers (3- and 5-step)
@@ -896,12 +1031,14 @@
     /*static*/ mpc_int32_t idx51[] = { -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2};
 
-    mpc_int32_t n, k;
+    mpc_int32_t n,k;
     mpc_int32_t Max_used_Band=0;
     const HuffmanTyp *Table;
-    mpc_int32_t  idx;
-    mpc_int8_t   *L, *R;
-    mpc_int16_t  *LQ, *RQ;
-    mpc_int8_t   *ResL, *ResR;
+    mpc_int32_t idx;
+    mpc_int8_t *L   ,*R;
+    mpc_int16_t *LQ   ,*RQ;
+    mpc_int8_t *ResL,*ResR;
     mpc_uint32_t tmp;
+    mpc_uint8_t *LUT;
+    mpc_uint8_t max_length;
 
     /***************************** Header *****************************/
@@ -914,4 +1051,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;
     }
 
@@ -933,4 +1072,6 @@
         if (*ResL!=0 || *ResR!=0) {
             Max_used_Band = n;
+        } else {
+            d->MS_Flag[n] = 0;
         }
     }
@@ -957,30 +1098,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) : (int) mpc_decoder_bitstream_read(d, 6);
+                idx = Decode_DSCF ();
+                L[1] = (idx!=8) ? SCF_DIFF(L[0], idx) : (int) 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) : (int) 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) : (int) 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) : (int) 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) : (int) mpc_decoder_bitstream_read(d, 6);
+                idx = Decode_DSCF ();
+                L[1] = (idx!=8) ? SCF_DIFF(L[0], idx) : (int) mpc_decoder_bitstream_read(d, 6);
+                idx = Decode_DSCF ();
+                L[2] = (idx!=8) ? SCF_DIFF(L[1], idx) : (int) mpc_decoder_bitstream_read(d, 6);
                 break;
             default:
@@ -988,39 +1129,36 @@
                 break;
             }
-            // update Reference for DSCF
-            //d->DSCF_Reference_L[n] = L[2];
         }
         if (*ResR)
         {
-            //R[2] = d->DSCF_Reference_R[n];
             switch (d->SCFI_R[n])
             {
             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) : (int) mpc_decoder_bitstream_read(d, 6);
+                idx = Decode_DSCF ();
+                R[1] = (idx!=8) ? SCF_DIFF(R[0], idx) : (int) 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) : (int) 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) : (int) 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) : (int) 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) : (int) mpc_decoder_bitstream_read(d, 6);
+                idx = Decode_DSCF ();
+                R[1] = (idx!=8) ? SCF_DIFF(R[0], idx) : (int) mpc_decoder_bitstream_read(d, 6);
+                idx = Decode_DSCF ();
+                R[2] = (idx!=8) ? SCF_DIFF(R[1], idx) : (int) mpc_decoder_bitstream_read(d, 6);
                 break;
             default:
@@ -1028,13 +1166,15 @@
                 break;
             }
-            // update Reference for DSCF
-            //d->DSCF_Reference_R[n] = R[2];
-        }
-    }
+        }
+    }
+
+    if (fastSeeking)
+        return;
+
     /***************************** Samples ****************************/
     ResL = d->Res_L;
     ResR = d->Res_R;
-    LQ   = d->Q[0].L;
-    RQ   = d->Q[0].R;
+    LQ    = d->Q[0].L;
+    RQ    = d->Q[0].R;
     for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR, LQ+=36, RQ+=36)
     {
@@ -1056,8 +1196,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 +1214,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 +1231,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];
+            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++ = mpc_decoder_huffman_decode(d, Table);
+                    *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 +1324,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 +1342,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 +1359,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];
+            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++ = mpc_decoder_huffman_decode(d, Table);
+                    *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,5 +1450,7 @@
   d->OverallFrames = 0;
   d->DecodedFrames = 0;
+  d->MaxDecodedFrames = 0;
   d->TrueGaplessPresent = 0;
+  d->last_block_samples = 0;
   d->WordsRead = 0;
   d->Max_Band = 0;
@@ -1184,6 +1462,15 @@
   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);
@@ -1192,8 +1479,38 @@
   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 );
+
+  d->Speicher = Speicher;
+  d->Y_L = Y_L;
+  d->Y_R = Y_R;
+
+}
+
+void mpc_decoder_destroy(mpc_decoder *d) {
+
+    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 +1525,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;
+            } else {
+                seekTableSize = min(si->frames, d->Max_SeekTable_Size / sizeof(mpc_uint32_t));
+}
+            d->SeekTable = (mpc_uint32_t*) calloc( sizeof(mpc_uint32_t), seekTableSize);
+            d->SeekTable_Step = si->frames / seekTableSize;
+            if (si->frames % seekTableSize)
+                d->SeekTable_Step+=1;
+        } else {
+            seekTableSize = d->Max_SeekTable_Size / sizeof(mpc_uint32_t);
+            d->SeekTable_Step = si->frames / seekTableSize;
+            if (si->frames % 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;
+
     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 +1585,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 +1594,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 +1608,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 +1649,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);
-
-    memset(d->Y_L          , 0, sizeof d->Y_L           );
-    memset(d->Y_R          , 0, sizeof d->Y_R           );
+void mpc_decoder_reset_state(mpc_decoder *d) {
+
+    memset(d->Y_L             , 0, sizeof Y_L              );
+    memset(d->Y_R             , 0, sizeof 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            );
@@ -1314,30 +1673,144 @@
     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 = 0;        // the bit to seek to
+    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_int32_t  delta = 0;       // direction of seek
+    
+    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;
+    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;
 
-    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++ ) {
+        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 +1821,122 @@
 #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;
+
+}
