Index: mpc.c =================================================================== RCS file: /cvsroot/rockbox/apps/codecs/mpc.c,v retrieving revision 1.23 diff -u -r1.23 mpc.c --- mpc.c 15 Apr 2006 02:03:11 -0000 1.23 +++ mpc.c 18 Apr 2006 07:18:48 -0000 @@ -5,7 +5,7 @@ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ - * $Id: mpc.c,v 1.23 2006-04-15 02:03:11 lostlogic Exp $ + * $Id: mpc.c,v 1.22 2006-03-22 19:51:40 amiconn Exp $ * * Copyright (C) 2005 Thom Johansen * @@ -103,6 +103,9 @@ reader.canseek = canseek_impl; reader.data = ci; + /* Ensure that SeekTable is clear since decoder is reused */ + decoder.SeekTable = NULL; + next_track: if (codec_init(api)) { retval = CODEC_ERROR; @@ -115,7 +118,7 @@ retval = CODEC_ERROR; goto exit; } - frequency = info.sample_freq; + frequency = info.sample_freq / 1000; ci->configure(DSP_SET_FREQUENCY, (long *)(long)info.sample_freq); /* set playback engine up for correct number of channels */ @@ -141,21 +144,22 @@ /* This is the decoding loop. */ samplesdone = 0; do { - #if 0 - /* Complete seek handler. This will be extremely slow and unresponsive - on target, so has been disabledt. */ + #if 1 + /* Complete seek handler. */ if (ci->seek_time) { - mpc_int64_t new_offset = (ci->seek_time - 1)*info.sample_freq/1000; + /* hack to improve seek time if filebuf goes empty */ + ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (long *)(1024*512)); + mpc_int64_t new_offset = (ci->seek_time - 1) * frequency; if (mpc_decoder_seek_sample(&decoder, new_offset)) { samplesdone = new_offset; ci->set_elapsed(ci->seek_time); } ci->seek_complete(); + /* reset chunksize */ + ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (long *)(1024*16)); } #else - /* Seek to start of track handler. This is the only case that isn't slow - as hell, and needs to be supported for the back button to function as - wanted. */ + /* Seek to start of track handler. */ if (ci->seek_time == 1) { if (mpc_decoder_seek_sample(&decoder, 0)) { samplesdone = 0; @@ -178,7 +182,7 @@ status*sizeof(MPC_SAMPLE_FORMAT))) ci->yield(); samplesdone += status; - ci->set_elapsed(samplesdone/(frequency/1000)); + ci->set_elapsed(samplesdone / frequency); } } while (status != 0); @@ -187,6 +191,7 @@ retval = CODEC_OK; exit: + mpc_decoder_destroy(&decoder); return retval; } cvs diff: Diffing libmad cvs diff: Diffing libmusepack Index: libmusepack/config_types.h =================================================================== RCS file: /cvsroot/rockbox/apps/codecs/libmusepack/config_types.h,v retrieving revision 1.2 diff -u -r1.2 config_types.h --- libmusepack/config_types.h 30 Jan 2006 01:00:40 -0000 1.2 +++ libmusepack/config_types.h 18 Apr 2006 06:39:16 -0000 @@ -40,6 +40,8 @@ #define FALSE 0 /* these are filled in by configure */ +typedef char mpc_int8_t; +typedef unsigned char mpc_uint8_t; typedef short mpc_int16_t; typedef unsigned short mpc_uint16_t; typedef int mpc_int32_t; Index: libmusepack/decoder.h =================================================================== RCS file: /cvsroot/rockbox/apps/codecs/libmusepack/decoder.h,v retrieving revision 1.3 diff -u -r1.3 decoder.h --- libmusepack/decoder.h 30 Jan 2006 01:00:40 -0000 1.3 +++ libmusepack/decoder.h 4 Apr 2006 22:50:40 -0000 @@ -44,6 +44,7 @@ #include "streaminfo.h" #define MPC_SUPPORT_SV456 +#define SCF_HACK enum { MPC_V_MEM = 2304, @@ -61,10 +62,12 @@ /// @name internal state variables //@{ + 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 Zaehler; /// actual index within read-buffer + mpc_uint32_t Ring; mpc_uint32_t samples_to_skip; @@ -74,6 +77,7 @@ mpc_uint32_t DecodedFrames; mpc_uint32_t OverallFrames; + mpc_uint32_t MaxDecodedFrames; // Maximum frames decoded (indicates usable seek table entries) mpc_int32_t SampleRate; // Sample frequency mpc_uint32_t StreamVersion; // version of bitstream @@ -102,6 +106,11 @@ mpc_int32_t DSCF_Reference_L [32]; mpc_int32_t DSCF_Reference_R [32]; // holds last frames SCF mpc_bool_t MS_Flag[32]; // MS used? + + mpc_uint16_t* SeekTable; + mpc_bool_t Use_SeekTable; + mpc_bool_t Use_FastSeek; + #ifdef MPC_FIXED_POINT unsigned char SCF_shift[256]; #endif Index: libmusepack/huffman.h =================================================================== RCS file: /cvsroot/rockbox/apps/codecs/libmusepack/huffman.h,v retrieving revision 1.2 diff -u -r1.2 huffman.h --- libmusepack/huffman.h 30 Jan 2006 01:00:40 -0000 1.2 +++ libmusepack/huffman.h 18 Apr 2006 07:59:46 -0000 @@ -46,8 +46,8 @@ /// Huffman table entry. typedef struct huffman_type_t { mpc_uint32_t Code; - mpc_uint16_t Length; - mpc_int16_t Value; + mpc_uint8_t Length; + mpc_int8_t Value; } HuffmanTyp; #endif // _mpcdec_huffman_h_ Index: libmusepack/huffsv7.c =================================================================== RCS file: /cvsroot/rockbox/apps/codecs/libmusepack/huffsv7.c,v retrieving revision 1.2 diff -u -r1.2 huffsv7.c --- libmusepack/huffsv7.c 30 Jan 2006 01:00:40 -0000 1.2 +++ libmusepack/huffsv7.c 18 Apr 2006 07:23:16 -0000 @@ -39,38 +39,38 @@ #include #include -const HuffmanTyp mpc_table_HuffHdr [10] = +const HuffmanTyp mpc_table_HuffHdr [10] ICONST_ATTR = {{2147483648u,1,0},{1610612736u,3,1},{1577058304u,7,-4},{1568669696u,9,3},{1560281088u,9,4},{1543503872u,8,-5},{1476395008u,6,2},{1342177280u,5,-3},{1073741824u,4,-2},{0u,2,-1},}; -const HuffmanTyp mpc_table_HuffSCFI [ 4] = +const HuffmanTyp mpc_table_HuffSCFI [ 4] ICONST_ATTR = {{2147483648u,1,1},{1610612736u,3,2},{1073741824u,3,0},{0u,2,3},}; -const HuffmanTyp mpc_table_HuffDSCF [16] = +const HuffmanTyp mpc_table_HuffDSCF [16] ICONST_ATTR = {{4160749568u,5,5},{4026531840u,5,-4},{3758096384u,4,3},{3489660928u,4,-3},{3221225472u,4,8},{2684354560u,3,1},{2415919104u,4,0},{2281701376u,5,-5},{2214592512u,6,7},{2147483648u,6,-7},{1610612736u,3,-1},{1073741824u,3,2},{805306368u,4,4},{671088640u,5,6},{536870912u,5,-6},{0u,3,-2},}; -static const HuffmanTyp mpc_table_HuffQ1 [2] [3*3*3] = { +static const HuffmanTyp mpc_table_HuffQ1 [2] [3*3*3] ICONST_ATTR = { {{3758096384u,3,13},{3690987520u,6,26},{3623878656u,6,0},{3556769792u,6,20},{3489660928u,6,6},{3221225472u,4,14},{2952790016u,4,12},{2684354560u,4,4},{2415919104u,4,22},{2348810240u,6,8},{2281701376u,6,18},{2214592512u,6,24},{2147483648u,6,2},{1879048192u,4,16},{1610612736u,4,10},{1476395008u,5,17},{1342177280u,5,9},{1207959552u,5,1},{1073741824u,5,25},{939524096u,5,5},{805306368u,5,21},{671088640u,5,3},{536870912u,5,11},{402653184u,5,15},{268435456u,5,23},{134217728u,5,19},{0u,5,7},}, {{2147483648u,1,13},{2113929216u,7,15},{2080374784u,7,1},{2046820352u,7,11},{2013265920u,7,7},{1979711488u,7,17},{1946157056u,7,25},{1912602624u,7,19},{1904214016u,9,8},{1895825408u,9,18},{1887436800u,9,2},{1879048192u,9,24},{1845493760u,7,3},{1811939328u,7,23},{1778384896u,7,21},{1744830464u,7,5},{1728053248u,8,0},{1711276032u,8,26},{1694498816u,8,6},{1677721600u,8,20},{1610612736u,6,9},{1342177280u,4,14},{1073741824u,4,12},{805306368u,4,4},{536870912u,4,22},{268435456u,4,16},{0u,4,10},}, }; -static const HuffmanTyp mpc_table_HuffQ2 [2] [5*5] = { +static const HuffmanTyp mpc_table_HuffQ2 [2] [5*5] ICONST_ATTR = { {{4026531840u,4,13},{3758096384u,4,17},{3489660928u,4,7},{3221225472u,4,11},{3154116608u,6,1},{3087007744u,6,23},{3053453312u,7,4},{3019898880u,7,20},{2986344448u,7,0},{2952790016u,7,24},{2818572288u,5,22},{2684354560u,5,10},{2147483648u,3,12},{2013265920u,5,2},{1879048192u,5,14},{1610612736u,4,6},{1342177280u,4,18},{1073741824u,4,8},{805306368u,4,16},{671088640u,5,9},{536870912u,5,5},{402653184u,5,15},{268435456u,5,21},{134217728u,5,19},{0u,5,3},}, {{4160749568u,5,18},{4026531840u,5,6},{3892314112u,5,8},{3875536896u,8,3},{3871342592u,10,24},{3867148288u,10,4},{3862953984u,10,0},{3858759680u,10,20},{3825205248u,7,23},{3791650816u,7,1},{3758096384u,7,19},{3623878656u,5,16},{3590324224u,7,15},{3556769792u,7,21},{3523215360u,7,9},{3489660928u,7,5},{3422552064u,6,2},{3355443200u,6,10},{3288334336u,6,14},{3221225472u,6,22},{2147483648u,2,12},{1610612736u,3,13},{1073741824u,3,17},{536870912u,3,11},{0u,3,7},}, }; -static const HuffmanTyp mpc_table_HuffQ3 [2] [ 7] = { +static const HuffmanTyp mpc_table_HuffQ3 [2] [ 7] ICONST_ATTR = { {{3758096384u,3,1},{3489660928u,4,3},{3221225472u,4,-3},{2684354560u,3,2},{2147483648u,3,-2},{1073741824u,2,0},{0u,2,-1},}, {{3221225472u,2,0},{2147483648u,2,-1},{1073741824u,2,1},{805306368u,4,-2},{671088640u,5,3},{536870912u,5,-3},{0u,3,2},}, }; -static const HuffmanTyp mpc_table_HuffQ4 [2] [ 9] = { +static const HuffmanTyp mpc_table_HuffQ4 [2] [ 9] ICONST_ATTR = { {{3758096384u,3,0},{3221225472u,3,-1},{2684354560u,3,1},{2147483648u,3,-2},{1610612736u,3,2},{1342177280u,4,-4},{1073741824u,4,4},{536870912u,3,3},{0u,3,-3},}, {{3758096384u,3,1},{3489660928u,4,2},{3221225472u,4,-3},{2147483648u,2,0},{1610612736u,3,-2},{1342177280u,4,3},{1207959552u,5,-4},{1073741824u,5,4},{0u,2,-1},}, }; -static const HuffmanTyp mpc_table_HuffQ5 [2] [15] = { +static const HuffmanTyp mpc_table_HuffQ5 [2] [15] ICONST_ATTR = { {{4026531840u,4,2},{3892314112u,5,5},{3825205248u,6,-7},{3758096384u,6,7},{3489660928u,4,-3},{3221225472u,4,3},{3087007744u,5,-6},{2952790016u,5,6},{2684354560u,4,-4},{2415919104u,4,4},{2147483648u,4,-5},{1610612736u,3,0},{1073741824u,3,-1},{536870912u,3,1},{0u,3,-2},}, {{4026531840u,4,3},{3892314112u,5,4},{3858759680u,7,6},{3841982464u,8,-7},{3825205248u,8,7},{3758096384u,6,-6},{3221225472u,3,0},{2684354560u,3,-1},{2147483648u,3,1},{1610612736u,3,-2},{1073741824u,3,2},{939524096u,5,-5},{805306368u,5,5},{536870912u,4,-4},{0u,3,-3},}, }; -static const HuffmanTyp mpc_table_HuffQ6 [2] [31] = { +static const HuffmanTyp mpc_table_HuffQ6 [2] [31] ICONST_ATTR = { {{4160749568u,5,3},{4026531840u,5,-4},{3959422976u,6,-11},{3892314112u,6,12},{3758096384u,5,4},{3623878656u,5,6},{3489660928u,5,-5},{3355443200u,5,5},{3221225472u,5,7},{3087007744u,5,-7},{3019898880u,6,-12},{2952790016u,6,-13},{2818572288u,5,-6},{2684354560u,5,8},{2550136832u,5,-8},{2415919104u,5,9},{2281701376u,5,-9},{2214592512u,6,13},{2181038080u,7,-15},{2147483648u,7,15},{1879048192u,4,0},{1744830464u,5,-10},{1610612736u,5,10},{1342177280u,4,-1},{1073741824u,4,2},{805306368u,4,1},{536870912u,4,-2},{469762048u,6,14},{402653184u,6,-14},{268435456u,5,11},{0u,4,-3},}, {{4160749568u,5,-6},{4026531840u,5,6},{3758096384u,4,1},{3489660928u,4,-1},{3456106496u,7,10},{3422552064u,7,-10},{3405774848u,8,-11},{3397386240u,9,-12},{3395289088u,11,13},{3394764800u,13,15},{3394240512u,13,-14},{3393716224u,13,14},{3393191936u,13,-15},{3388997632u,10,-13},{3372220416u,8,11},{3355443200u,8,12},{3288334336u,6,-9},{3221225472u,6,9},{2952790016u,4,-2},{2684354560u,4,2},{2415919104u,4,3},{2147483648u,4,-3},{2013265920u,5,-7},{1879048192u,5,7},{1610612736u,4,-4},{1342177280u,4,4},{1207959552u,5,-8},{1073741824u,5,8},{805306368u,4,5},{536870912u,4,-5},{0u,3,0},}, }; -static const HuffmanTyp mpc_table_HuffQ7 [2] [63] = { +static const HuffmanTyp mpc_table_HuffQ7 [2] [63] ICONST_ATTR = { {{4227858432u,6,7},{4160749568u,6,8},{4093640704u,6,9},{4026531840u,6,-8},{3959422976u,6,11},{3925868544u,7,21},{3909091328u,8,-28},{3892314112u,8,28},{3825205248u,6,-9},{3791650816u,7,-22},{3758096384u,7,-21},{3690987520u,6,-10},{3623878656u,6,-11},{3556769792u,6,10},{3489660928u,6,12},{3422552064u,6,-13},{3388997632u,7,22},{3355443200u,7,23},{3288334336u,6,-12},{3221225472u,6,13},{3154116608u,6,14},{3087007744u,6,-14},{3053453312u,7,-23},{3036676096u,8,-29},{3019898880u,8,29},{2952790016u,6,-15},{2885681152u,6,15},{2818572288u,6,16},{2751463424u,6,-16},{2717908992u,7,-24},{2684354560u,7,24},{2617245696u,6,17},{2583691264u,7,-25},{2566914048u,8,-30},{2550136832u,8,30},{2483027968u,6,-17},{2415919104u,6,18},{2348810240u,6,-18},{2315255808u,7,25},{2281701376u,7,26},{2214592512u,6,19},{2181038080u,7,-26},{2147483648u,7,-27},{2013265920u,5,2},{1946157056u,6,-19},{1879048192u,6,20},{1744830464u,5,-1},{1728053248u,8,-31},{1711276032u,8,31},{1677721600u,7,27},{1610612736u,6,-20},{1476395008u,5,1},{1342177280u,5,-5},{1207959552u,5,-3},{1073741824u,5,3},{939524096u,5,0},{805306368u,5,-2},{671088640u,5,-4},{536870912u,5,4},{402653184u,5,5},{268435456u,5,-6},{134217728u,5,6},{0u,5,-7},}, {{4160749568u,5,-1},{4026531840u,5,2},{3892314112u,5,-2},{3758096384u,5,3},{3741319168u,8,-20},{3737124864u,10,24},{3736862720u,14,28},{3736600576u,14,-28},{3736338432u,14,-30},{3736076288u,14,30},{3735027712u,12,-27},{3734765568u,14,29},{3734503424u,14,-29},{3734241280u,14,31},{3733979136u,14,-31},{3732930560u,12,27},{3724541952u,9,-22},{3690987520u,7,-17},{3623878656u,6,-11},{3489660928u,5,-3},{3355443200u,5,4},{3221225472u,5,-4},{3187671040u,7,17},{3170893824u,8,20},{3162505216u,9,22},{3158310912u,10,-25},{3154116608u,10,-26},{3087007744u,6,12},{2952790016u,5,5},{2818572288u,5,-5},{2684354560u,5,6},{2550136832u,5,-6},{2483027968u,6,-12},{2449473536u,7,-18},{2415919104u,7,18},{2348810240u,6,13},{2281701376u,6,-13},{2147483648u,5,-7},{2080374784u,6,14},{2063597568u,8,21},{2046820352u,8,-21},{2013265920u,7,-19},{1879048192u,5,7},{1744830464u,5,8},{1677721600u,6,-14},{1610612736u,6,-15},{1476395008u,5,-8},{1409286144u,6,15},{1375731712u,7,19},{1371537408u,10,25},{1367343104u,10,26},{1358954496u,9,-23},{1350565888u,9,23},{1342177280u,9,-24},{1207959552u,5,-9},{1073741824u,5,9},{1006632960u,6,16},{939524096u,6,-16},{805306368u,5,10},{536870912u,4,0},{402653184u,5,-10},{268435456u,5,11},{0u,4,1},}, }; Index: libmusepack/mpc_decoder.c =================================================================== RCS file: /cvsroot/rockbox/apps/codecs/libmusepack/mpc_decoder.c,v retrieving revision 1.9 diff -u -r1.9 mpc_decoder.c --- libmusepack/mpc_decoder.c 30 Jan 2006 01:42:23 -0000 1.9 +++ libmusepack/mpc_decoder.c 18 Apr 2006 07:23:58 -0000 @@ -58,6 +58,39 @@ #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] IBSS_ATTR; +mpc_uint8_t LUT1_1 [1<< 9] IBSS_ATTR; // 576 Bytes +mpc_uint8_t LUT2_0 [1<< 7] IBSS_ATTR; +mpc_uint8_t LUT2_1 [1<<10] IBSS_ATTR; // 1152 Bytes +mpc_uint8_t LUT3_0 [1<< 4] IBSS_ATTR; +mpc_uint8_t LUT3_1 [1<< 5] IBSS_ATTR; // 48 Bytes +mpc_uint8_t LUT4_0 [1<< 4] IBSS_ATTR; +mpc_uint8_t LUT4_1 [1<< 5] IBSS_ATTR; // 48 Bytes +mpc_uint8_t LUT5_0 [1<< 6] IBSS_ATTR; +mpc_uint8_t LUT5_1 [1<< 8] IBSS_ATTR; // 320 Bytes +mpc_uint8_t LUT6_0 [1<< 7] IBSS_ATTR; +mpc_uint8_t LUT6_1 [1<< 7] IBSS_ATTR; // 256 Bytes +mpc_uint8_t LUT7_0 [1<< 8] IBSS_ATTR; +mpc_uint8_t LUT7_1 [1<< 8] IBSS_ATTR; // 512 Bytes +mpc_uint8_t LUTDSCF [1<< 6] IBSS_ATTR; // 64 Bytes = 2976 Bytes + //------------------------------------------------------------------------------ // types //------------------------------------------------------------------------------ @@ -75,10 +108,17 @@ // forward declarations //------------------------------------------------------------------------------ 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 mpc_int32_t mpc_decoder_huffman_decode_fastest(mpc_decoder *d, const HuffmanTyp* Table, const mpc_uint8_t* tab, mpc_uint16_t unused_bits) ICODE_ATTR; //------------------------------------------------------------------------------ // utility functions @@ -96,12 +136,6 @@ static mpc_int32_t f_read_dword(mpc_decoder *d, mpc_uint32_t * ptr, mpc_uint32_t count) { count = f_read(d, ptr, count << 2) >> 2; -#ifndef MPC_LITTLE_ENDIAN - mpc_uint32_t n; - for(n = 0; n< count; n++) { - ptr[n] = mpc_swap32(ptr[n]); - } -#endif return count; } @@ -127,6 +161,7 @@ mpc_decoder_reset_bitstream_decode(mpc_decoder *d) { d->dword = 0; + d->next = 0; d->pos = 0; d->Zaehler = 0; d->WordsRead = 0; @@ -151,7 +186,9 @@ out >>= (32 - d->pos); } else { - d->dword = d->Speicher[d->Zaehler = (d->Zaehler + 1) & MEMMASK]; + d->dword = d->next; + d->Zaehler = (d->Zaehler + 1) & MEMMASK; + d->next = SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]); d->pos -= 32; if (d->pos) { out <<= d->pos; @@ -163,6 +200,24 @@ 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; +} + // decode SCFI-bundle (sv4,5,6) static void mpc_decoder_scfi_bundle_read( @@ -171,8 +226,9 @@ { // 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) { Table++; @@ -180,8 +236,10 @@ // set the new position within bitstream without performing a dummy-read if ((d->pos += Table->Length) >= 32) { + d->Zaehler = (d->Zaehler + 1) & MEMMASK; + d->dword = d->next; + d->next = SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]); d->pos -= 32; - d->dword = d->Speicher[d->Zaehler = (d->Zaehler+1) & MEMMASK]; ++(d->WordsRead); } @@ -196,8 +254,9 @@ { // 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) { Table++; @@ -205,8 +264,10 @@ // set the new position within bitstream without performing a dummy-read if ((d->pos += Table->Length) >= 32) { + d->Zaehler = (d->Zaehler + 1) & MEMMASK; + d->dword = d->next; + d->next = SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]); d->pos -= 32; - d->dword = d->Speicher[d->Zaehler = (d->Zaehler + 1) & MEMMASK]; ++(d->WordsRead); } @@ -220,8 +281,9 @@ { // 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); + + if (d->pos > 22) { + code |= d->next >> (32 - d->pos); } while (code < Table->Code) { Table++; @@ -229,8 +291,10 @@ // set the new position within bitstream without performing a dummy-read if ((d->pos += Table->Length) >= 32) { + d->Zaehler = (d->Zaehler + 1) & MEMMASK; + d->dword = d->next; + d->next = SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]); d->pos -= 32; - d->dword = d->Speicher[d->Zaehler = (d->Zaehler + 1) & MEMMASK]; ++(d->WordsRead); } @@ -244,8 +308,9 @@ { // 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); + + if (d->pos > 27) { + code |= d->next >> (32 - d->pos); } while (code < Table->Code) { Table++; @@ -253,8 +318,64 @@ // set the new position within bitstream without performing a dummy-read if ((d->pos += Table->Length) >= 32) { + d->Zaehler = (d->Zaehler + 1) & MEMMASK; + d->dword = d->next; + d->next = SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]); d->pos -= 32; - d->dword = d->Speicher[d->Zaehler = (d->Zaehler + 1) & MEMMASK]; + ++(d->WordsRead); + } + + 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) { + d->Zaehler = (d->Zaehler + 1) & MEMMASK; + d->dword = d->next; + d->next = SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]); + d->pos -= 32; + ++(d->WordsRead); + } + + return Table->Value; +} + +/* full decode using lookup table */ +static 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) { + d->Zaehler = (d->Zaehler + 1) & MEMMASK; + d->dword = d->next; + d->next = SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]); + d->pos -= 32; ++(d->WordsRead); } @@ -291,6 +412,7 @@ mpc_decoder_reset_bitstream_decode(d); d->DecodedFrames = 0; + d->MaxDecodedFrames = 0; d->StreamVersion = 0; d->MS_used = 0; @@ -314,16 +436,11 @@ mpc_decoder_decode_frame(mpc_decoder *d, mpc_uint32_t *in_buffer, 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 - (void)i; /* avoid warning */ - d->dword = d->Speicher[0]; + d->dword = SWAP(d->Speicher[0]); + d->next = SWAP(d->Speicher[1]); switch (d->StreamVersion) { #ifdef MPC_SUPPORT_SV456 case 0x04: @@ -334,7 +451,7 @@ #endif case 0x07: case 0x17: - mpc_decoder_read_bitstream_sv7(d); + mpc_decoder_read_bitstream_sv7(d, FALSE); break; default: return (mpc_uint32_t)(-1); @@ -355,6 +472,9 @@ 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 d->FwdJumpInfo = mpc_decoder_bitstream_read(d, 20); @@ -372,13 +492,18 @@ #endif case 0x07: case 0x17: - mpc_decoder_read_bitstream_sv7(d); + mpc_decoder_read_bitstream_sv7(d, FALSE); break; default: return (mpc_uint32_t)(-1); } d->FrameWasValid = mpc_decoder_bits_read(d) - FrameBitCnt == d->FwdJumpInfo; + d->DecodedFrames++; + + if (d->Use_SeekTable) + d->SeekTable [d->DecodedFrames] = d->FwdJumpInfo + 20; + // synthesize signal mpc_decoder_requantisierung(d, d->Max_Band); @@ -387,8 +512,6 @@ mpc_decoder_synthese_filter_float(d, buffer); - d->DecodedFrames++; - // cut off first MPC_DECODER_SYNTH_DELAY zero-samples if (d->DecodedFrames == d->OverallFrames && d->StreamVersion >= 6) { // reconstruct exact filelength @@ -407,7 +530,7 @@ mpc_decoder_reset_y(d); } 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); } @@ -473,7 +596,7 @@ } } - mpc_decoder_update_buffer(d, RING); + mpc_decoder_update_buffer(d); if (valid_samples > 0) { return valid_samples; @@ -886,7 +1009,7 @@ #endif //MPC_SUPPORT_SV456 /****************************************** 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) /*static*/ mpc_int32_t idx30[] = { -1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1}; @@ -902,6 +1025,8 @@ mpc_int32_t *L ,*R; mpc_int32_t *ResL,*ResR; mpc_uint32_t tmp; + mpc_uint8_t *LUT; + mpc_uint8_t max_length; /***************************** Header *****************************/ ResL = d->Res_L; @@ -912,7 +1037,9 @@ *ResR = mpc_decoder_bitstream_read(d, 4); if (d->MS_used && !(*ResL==0 && *ResR==0)) { d->MS_Flag[0] = mpc_decoder_bitstream_read(d, 1); - } + } else { + d->MS_Flag[0] = 0; + } // consecutive subbands ++ResL; ++ResR; // increase pointers @@ -931,7 +1058,9 @@ // only perform following procedures up to the maximum non-zero subband if (*ResL!=0 || *ResR!=0) { Max_used_Band = n; - } + } else { + d->MS_Flag[n] = 0; + } } /****************************** SCFI ******************************/ L = d->SCFI_L; @@ -951,85 +1080,84 @@ for (n=0; n<=Max_used_Band; ++n, ++ResL, ++ResR, L+=3, R+=3) { if (*ResL) { - L[2] = d->DSCF_Reference_L[n]; + //L[2] = d->DSCF_Reference_L[n]; switch (d->SCFI_L[n]) { 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: return; 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: return; break; } - // update Reference for DSCF - d->DSCF_Reference_R[n] = R[2]; } } + + if (fastSeeking) + return; + /***************************** Samples ****************************/ ResL = d->Res_L; ResR = d->Res_R; @@ -1054,40 +1182,108 @@ L += 36;// increase pointer 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 ); *L++ = idx30[idx]; *L++ = idx31[idx]; *L++ = idx32[idx]; } 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 ); *L++ = idx50[idx]; *L++ = idx51[idx]; } 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) + *L++ = 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) - *L++ = mpc_decoder_huffman_decode_faster(d, Table); + *L++ = 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) - *L++ = mpc_decoder_huffman_decode_fast(d, Table); + *L++ = 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) + *L++ = 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) + *L++ = 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) - *L++ = 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) + *L++ = 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) + *L++ = 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]; @@ -1114,41 +1310,109 @@ R += 36;// increase pointer 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 ); *R++ = idx30[idx]; *R++ = idx31[idx]; *R++ = idx32[idx]; } 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 ); *R++ = idx50[idx]; *R++ = idx51[idx]; } 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) + *R++ = 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) - *R++ = mpc_decoder_huffman_decode_faster(d, Table); + *R++ = 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) - *R++ = mpc_decoder_huffman_decode_fast(d, Table); + *R++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); break; case 6: - case 7: - Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResR]; - for (k=0; k<36; ++k) - *R++ = mpc_decoder_huffman_decode(d, Table); - break; + 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) + *R++ = 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) + *R++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); + } + break; + case 7: + 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) + *R++ = 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) + *R++ = 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) @@ -1172,6 +1436,7 @@ d->FrameWasValid = 0; d->OverallFrames = 0; d->DecodedFrames = 0; + d->MaxDecodedFrames = 0; d->TrueGaplessPresent = 0; d->WordsRead = 0; d->Max_Band = 0; @@ -1182,10 +1447,34 @@ d->dword = 0; 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; mpc_decoder_initialisiere_quantisierungstabellen(d, 1.0f); +#if 0 + 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 ); /* Link struct entries to actual tables which are placed in IRAM */ d->V_L = V_L; @@ -1195,6 +1484,13 @@ #endif } +void mpc_decoder_destroy(mpc_decoder *d) { + + if (d->SeekTable != NULL) + free(d->SeekTable); + +} + void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si) { mpc_decoder_reset_synthesis(d); @@ -1209,26 +1505,38 @@ d->SampleRate = (mpc_int32_t)si->sample_freq; d->samples_to_skip = MPC_DECODER_SYNTH_DELAY; + + if (d->SeekTable != NULL) + free(d->SeekTable); + + if (d->Use_SeekTable) { + d->SeekTable = (mpc_uint16_t*) calloc( sizeof(mpc_uint16_t), si->frames+2); + memset(d->SeekTable, 0, sizeof d->SeekTable); + } + } mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si) { - mpc_decoder_set_streaminfo(d, si); + mpc_uint32_t bitPos; + mpc_uint32_t fpos; - // 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 - f_read_dword(d, d->Speicher, MEMSIZE ); - d->dword = d->Speicher[d->Zaehler = 0]; + mpc_decoder_set_streaminfo(d, si); + // 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->Ring = 0; + d->Zaehler = 0; + d->pos = bitPos & 31; + d->WordsRead = fpos; + d->dword = SWAP(d->Speicher[0]); + d->next = SWAP(d->Speicher[1]); + return TRUE; } @@ -1242,21 +1550,19 @@ { 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 helper2(mpc_decoder *d, mpc_uint32_t bitpos) { 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) { @@ -1267,10 +1573,28 @@ f_seek(d, bitpos * 4L + d->MPCHeaderPos); 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) { mpc_uint32_t fpos = 0; @@ -1290,18 +1614,17 @@ return mpc_decoder_seek_sample(d, (mpc_int64_t)(seconds * (double)d->SampleRate + 0.5)); } -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 ); - memset(d->SCF_Index_L , 0, sizeof d->SCF_Index_L ); + 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 ); memset(d->SCFI_L , 0, sizeof d->SCFI_L ); @@ -1313,32 +1636,103 @@ 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 = 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; - // reset number of decoded frames - d->DecodedFrames = 0; + // seek direction (note: avoids casting to int64) + delta = (d->DecodedFrames > seekFrame ? -(mpc_int32_t)(d->DecodedFrames - seekFrame) : (mpc_int32_t)(seekFrame - d->DecodedFrames)); - fpos = get_initial_fpos(d, d->StreamVersion); - if (fpos == 0) { - return FALSE; - } + // update max decoded frames + if (d->DecodedFrames > d->MaxDecodedFrames) + d->MaxDecodedFrames = d->DecodedFrames; + + if (seekFrame > 33) + lastFrame = seekFrame - 33; + + 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 + d->SeekTable[0] = (mpc_uint16_t)fpos; + for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) + d->SeekTable[d->DecodedFrames+1] = 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) { - helper2(d, fpos); + mpc_decoder_reset_state(d); + + // jumps backwards using the seek table + fpos = d->SeekTable[0]; + for (d->DecodedFrames = 0;d->DecodedFrames < lastFrame; d->DecodedFrames++) + fpos += d->SeekTable[d->DecodedFrames+1]; + 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 + fpos = mpc_decoder_bits_read(d); + for (; d->DecodedFrames < d->MaxDecodedFrames && d->DecodedFrames < lastFrame; d->DecodedFrames++) + fpos += d->SeekTable[d->DecodedFrames+1]; + mpc_decoder_seek_to(d, fpos); + } + for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) + d->SeekTable[d->DecodedFrames+1] = 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; - // read the last 32 frames before the desired position to scan the scalefactors (artifactless jumping) - for ( ; d->DecodedFrames < fwd; 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 { #ifdef MPC_SUPPORT_SV456 @@ -1347,28 +1741,105 @@ return FALSE; #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; - } - // update buffer - if ((RING ^ d->Zaehler) & MEMSIZE2) { - f_read_dword(d, d->Speicher + (RING & MEMSIZE2), MEMSIZE2); - } - } - // LastBitsRead = BitsRead (); - // LastFrame = d->DecodedFrames; + // REVIEW: Only if decodedFrames < maxDecodedFrames?? + if (d->Use_SeekTable) { + // 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; + } + + // update buffer + 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) + +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 ((RING ^ d->Zaehler) & MEMSIZE2 ) { + 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; + +} + + Index: libmusepack/musepack.h =================================================================== RCS file: /cvsroot/rockbox/apps/codecs/libmusepack/musepack.h,v retrieving revision 1.4 diff -u -r1.4 musepack.h --- libmusepack/musepack.h 30 Jan 2006 01:00:40 -0000 1.4 +++ libmusepack/musepack.h 30 Mar 2006 07:40:50 -0000 @@ -132,6 +132,9 @@ /// Seeks to specified position in seconds in the source stream. mpc_bool_t mpc_decoder_seek_seconds(mpc_decoder *d, double seconds); +/// Cleans up the decoder +void mpc_decoder_destroy(mpc_decoder *d); + #ifdef __cplusplus } #endif // __cplusplus Index: libmusepack/synth_filter.c =================================================================== RCS file: /cvsroot/rockbox/apps/codecs/libmusepack/synth_filter.c,v retrieving revision 1.13 diff -u -r1.13 synth_filter.c --- libmusepack/synth_filter.c 20 Feb 2006 20:40:29 -0000 1.13 +++ libmusepack/synth_filter.c 30 Mar 2006 11:28:08 -0000 @@ -334,6 +334,7 @@ for ( n = 0; n < 36; n++, Y += 32 ) { V -= 64; Calculate_New_V ( Y, V ); + if (OutData != NULL) { MPC_SAMPLE_FORMAT * Data = OutData; const MPC_SAMPLE_FORMAT * D = (const MPC_SAMPLE_FORMAT *) &Di_opt; @@ -452,7 +453,7 @@ memmove(d->V_R + MPC_V_MEM, d->V_R, 960 * sizeof(MPC_SAMPLE_FORMAT) ); Synthese_Filter_float_internal( - OutData + MPC_FRAME_LENGTH, + (OutData == NULL ? NULL : OutData + MPC_FRAME_LENGTH), (MPC_SAMPLE_FORMAT *)(d->V_R + MPC_V_MEM), (MPC_SAMPLE_FORMAT *)(d->Y_R [0])); }