From 20332bce1d49d7285109564d2e29ee18b0acd54e Mon Sep 17 00:00:00 2001 From: Thom Johansen Date: Thu, 31 Aug 2006 18:18:57 +0000 Subject: FS patch #5172 by Andrew Cupper. Musepack seeking support. Decoder should also be faster. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10827 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/libmusepack/config_types.h | 2 + apps/codecs/libmusepack/decoder.h | 46 +- apps/codecs/libmusepack/huffman.h | 4 +- apps/codecs/libmusepack/huffsv7.c | 20 +- apps/codecs/libmusepack/internal.h | 4 + apps/codecs/libmusepack/mpc_decoder.c | 969 ++++++++++++++++++++++++++------- apps/codecs/libmusepack/musepack.h | 6 + apps/codecs/libmusepack/synth_filter.c | 5 +- apps/codecs/mpc.c | 32 +- 9 files changed, 836 insertions(+), 252 deletions(-) (limited to 'apps') diff --git a/apps/codecs/libmusepack/config_types.h b/apps/codecs/libmusepack/config_types.h index 30a609b863..96e8b90430 100644 --- a/apps/codecs/libmusepack/config_types.h +++ b/apps/codecs/libmusepack/config_types.h @@ -40,6 +40,8 @@ typedef unsigned char mpc_bool_t; #define FALSE 0 /* these are filled in by configure */ +typedef signed 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; diff --git a/apps/codecs/libmusepack/decoder.h b/apps/codecs/libmusepack/decoder.h index 708533b09e..7ffa572db2 100644 --- a/apps/codecs/libmusepack/decoder.h +++ b/apps/codecs/libmusepack/decoder.h @@ -44,6 +44,7 @@ #include "streaminfo.h" #define MPC_SUPPORT_SV456 +#define SCF_HACK enum { MPC_V_MEM = 2304, @@ -51,8 +52,8 @@ enum { }; typedef struct { - mpc_int32_t L [36]; - mpc_int32_t R [36]; + mpc_int16_t L [36]; + mpc_int16_t R [36]; } QuantTyp; typedef struct mpc_decoder_t { @@ -61,10 +62,12 @@ typedef struct mpc_decoder_t { /// @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 *Speicher; /// read-buffer mpc_uint32_t Zaehler; /// actual index within read-buffer + mpc_uint32_t Ring; mpc_uint32_t samples_to_skip; mpc_uint32_t last_block_samples; @@ -74,6 +77,9 @@ typedef struct mpc_decoder_t { mpc_uint32_t DecodedFrames; mpc_uint32_t OverallFrames; + mpc_uint32_t MaxDecodedFrames; // Maximum frames decoded (indicates usable seek table entries) + mpc_uint16_t SeekTableIndex; + mpc_uint32_t SeekTableCounter; mpc_int32_t SampleRate; // Sample frequency mpc_uint32_t StreamVersion; // version of bitstream @@ -90,28 +96,34 @@ typedef struct mpc_decoder_t { mpc_uint32_t __r1; mpc_uint32_t __r2; - mpc_int32_t SCF_Index_L [32] [3]; - mpc_int32_t SCF_Index_R [32] [3]; // holds scalefactor-indices + mpc_int8_t SCF_Index_L [32] [3]; + mpc_int8_t SCF_Index_R [32] [3]; // holds scalefactor-indices QuantTyp Q [32]; // holds quantized samples - mpc_int32_t Res_L [32]; - mpc_int32_t Res_R [32]; // holds the chosen quantizer for each subband + mpc_int8_t Res_L [32]; + mpc_int8_t Res_R [32]; // holds the chosen quantizer for each subband +#ifdef MPC_SUPPORT_SV456 mpc_bool_t DSCF_Flag_L [32]; mpc_bool_t DSCF_Flag_R [32]; // differential SCF used? - mpc_int32_t SCFI_L [32]; - mpc_int32_t SCFI_R [32]; // describes order of transmitted SCF - mpc_int32_t DSCF_Reference_L [32]; - mpc_int32_t DSCF_Reference_R [32]; // holds last frames SCF +#endif + mpc_int8_t SCFI_L [32]; + mpc_int8_t SCFI_R [32]; // describes order of transmitted SCF + //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_uint32_t* SeekTable; + mpc_bool_t Use_SeekTable; + mpc_bool_t Use_FastSeek; + mpc_bool_t Use_StaticSeekTable; + mpc_uint8_t SeekTable_Step; + mpc_uint32_t Max_SeekTable_Size; + #ifdef MPC_FIXED_POINT unsigned char SCF_shift[256]; #endif - /* These two see very frequent use in synth_filter.c, so we'll put them - in IRAM for Rockbox use. Actual arrays are placed in mpc_decoder.c */ - /* MPC_SAMPLE_FORMAT V_L[MPC_V_MEM + 960]; */ - /* MPC_SAMPLE_FORMAT V_R[MPC_V_MEM + 960]; */ - MPC_SAMPLE_FORMAT *V_L; - MPC_SAMPLE_FORMAT *V_R; + MPC_SAMPLE_FORMAT V_L[MPC_V_MEM + 960]; + MPC_SAMPLE_FORMAT V_R[MPC_V_MEM + 960]; MPC_SAMPLE_FORMAT Y_L[36][32]; MPC_SAMPLE_FORMAT Y_R[36][32]; MPC_SAMPLE_FORMAT SCF[256]; ///< holds adapted scalefactors (for clipping prevention) diff --git a/apps/codecs/libmusepack/huffman.h b/apps/codecs/libmusepack/huffman.h index 3edbeb7b6e..87fd5c15a4 100644 --- a/apps/codecs/libmusepack/huffman.h +++ b/apps/codecs/libmusepack/huffman.h @@ -46,8 +46,8 @@ struct mpc_decoder_t; // forward declare to break circular dependencies /// 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_ diff --git a/apps/codecs/libmusepack/huffsv7.c b/apps/codecs/libmusepack/huffsv7.c index a59674191d..5611595281 100644 --- a/apps/codecs/libmusepack/huffsv7.c +++ b/apps/codecs/libmusepack/huffsv7.c @@ -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},}, }; diff --git a/apps/codecs/libmusepack/internal.h b/apps/codecs/libmusepack/internal.h index 44279e2fa5..45f2b41eea 100644 --- a/apps/codecs/libmusepack/internal.h +++ b/apps/codecs/libmusepack/internal.h @@ -54,6 +54,10 @@ mpc_uint32_t mpc_swap32(mpc_uint32_t val) { } #endif +#ifndef min +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif + /// Searches for a ID3v2-tag and reads the length (in bytes) of it. /// \param reader supplying raw stream data /// \return size of tag, in bytes diff --git a/apps/codecs/libmusepack/mpc_decoder.c b/apps/codecs/libmusepack/mpc_decoder.c index fc1755ff60..4bf36bddc6 100644 --- a/apps/codecs/libmusepack/mpc_decoder.c +++ b/apps/codecs/libmusepack/mpc_decoder.c @@ -58,6 +58,38 @@ extern const HuffmanTyp mpc_table_Region_C [ 4]; #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 //------------------------------------------------------------------------------ @@ -75,10 +107,20 @@ enum // 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 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]; //------------------------------------------------------------------------------ // utility functions @@ -96,19 +138,13 @@ static mpc_bool_t f_seek(mpc_decoder *d, mpc_int32_t offset) 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; } //------------------------------------------------------------------------------ // huffman & bitstream functions //------------------------------------------------------------------------------ -static const mpc_uint32_t mask [33] = { +static const mpc_uint32_t mask [33] ICONST_ATTR = { 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, @@ -127,6 +163,7 @@ static void mpc_decoder_reset_bitstream_decode(mpc_decoder *d) { d->dword = 0; + d->next = 0; d->pos = 0; d->Zaehler = 0; d->WordsRead = 0; @@ -139,8 +176,16 @@ mpc_decoder_bits_read(mpc_decoder *d) return 32 * d->WordsRead + d->pos; } +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) { mpc_uint32_t out = d->dword; @@ -151,28 +196,45 @@ mpc_decoder_bitstream_read(mpc_decoder *d, const mpc_uint32_t bits) out >>= (32 - d->pos); } 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; +} + // decode SCFI-bundle (sv4,5,6) static void mpc_decoder_scfi_bundle_read( mpc_decoder *d, - const HuffmanTyp* Table, mpc_int32_t* SCFI, mpc_bool_t* DSCF) + const HuffmanTyp* Table, mpc_int8_t* SCFI, mpc_bool_t* DSCF) { // 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,9 +242,7 @@ mpc_decoder_scfi_bundle_read( // 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); } *SCFI = Table->Value >> 1; @@ -196,8 +256,9 @@ mpc_decoder_huffman_decode(mpc_decoder *d, const HuffmanTyp *Table) { // 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,9 +266,7 @@ mpc_decoder_huffman_decode(mpc_decoder *d, const HuffmanTyp *Table) // 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; @@ -220,8 +279,9 @@ mpc_decoder_huffman_decode_fast(mpc_decoder *d, const HuffmanTyp* Table) { // 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) { Table++; @@ -229,9 +289,7 @@ mpc_decoder_huffman_decode_fast(mpc_decoder *d, const HuffmanTyp* Table) // 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; @@ -244,32 +302,73 @@ mpc_decoder_huffman_decode_faster(mpc_decoder *d, const HuffmanTyp* Table) { // 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) { + 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; +} + +/* 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->pos -= 32; - d->dword = d->Speicher[d->Zaehler = (d->Zaehler + 1) & MEMMASK]; - ++(d->WordsRead); + mpc_move_next(d); } return Table->Value; } -MPC_SAMPLE_FORMAT V_L[MPC_V_MEM + 960] IBSS_ATTR; -MPC_SAMPLE_FORMAT V_R[MPC_V_MEM + 960] IBSS_ATTR; +/* 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); + } + + return Table->Value; +} static void mpc_decoder_reset_v(mpc_decoder *d) { - /* since d->V_L and d->V_R are now pointers, sizeof (d->V_x) will no longer work */ - memset(d->V_L, 0, sizeof V_L); - memset(d->V_R, 0, sizeof V_R); + memset(d->V_L, 0, sizeof d->V_L); + memset(d->V_R, 0, sizeof d->V_R); } static void @@ -291,6 +390,8 @@ mpc_decoder_reset_globals(mpc_decoder *d) mpc_decoder_reset_bitstream_decode(d); d->DecodedFrames = 0; + d->SeekTableIndex = 0; + d->MaxDecodedFrames = 0; d->StreamVersion = 0; d->MS_used = 0; @@ -302,10 +403,12 @@ mpc_decoder_reset_globals(mpc_decoder *d) memset(d->Res_R , 0, sizeof d->Res_R ); memset(d->SCFI_L , 0, sizeof d->SCFI_L ); memset(d->SCFI_R , 0, sizeof d->SCFI_R ); +#ifdef MPC_SUPPORT_SV456 memset(d->DSCF_Flag_L , 0, sizeof d->DSCF_Flag_L ); memset(d->DSCF_Flag_R , 0, sizeof d->DSCF_Flag_R ); - memset(d->DSCF_Reference_L, 0, sizeof d->DSCF_Reference_L ); - memset(d->DSCF_Reference_R, 0, sizeof d->DSCF_Reference_R ); +#endif + //memset(d->DSCF_Reference_L, 0, sizeof d->DSCF_Reference_L ); + //memset(d->DSCF_Reference_R, 0, sizeof d->DSCF_Reference_R ); memset(d->Q , 0, sizeof d->Q ); memset(d->MS_Flag , 0, sizeof d->MS_Flag ); } @@ -314,16 +417,11 @@ mpc_uint32_t 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); + 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 - (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 +432,7 @@ mpc_decoder_decode_frame(mpc_decoder *d, mpc_uint32_t *in_buffer, #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); @@ -359,7 +457,7 @@ mpc_decoder_decode_internal(mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer) 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); } mpc_decoder_synthese_filter_float(d, buffer); @@ -370,6 +468,9 @@ mpc_decoder_decode_internal(mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer) 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); @@ -387,13 +488,28 @@ mpc_decoder_decode_internal(mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer) #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) { + 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); @@ -402,8 +518,6 @@ mpc_decoder_decode_internal(mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer) 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 @@ -483,7 +597,7 @@ mpc_uint32_t mpc_decoder_decode( } } - mpc_decoder_update_buffer(d, RING); + mpc_decoder_update_buffer(d); if (valid_samples > 0) { return valid_samples; @@ -502,8 +616,8 @@ mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band) MPC_SAMPLE_FORMAT tempr; MPC_SAMPLE_FORMAT* YL; MPC_SAMPLE_FORMAT* YR; - mpc_int32_t* L; - mpc_int32_t* R; + mpc_int16_t* L; + mpc_int16_t* R; #ifdef MPC_FIXED_POINT #if MPC_FIXED_POINT_FRACTPART == 14 @@ -694,10 +808,12 @@ mpc_decoder_read_bitstream_sv6(mpc_decoder *d) const HuffmanTyp *Table; const HuffmanTyp *x1; const HuffmanTyp *x2; - mpc_int32_t *L; - mpc_int32_t *R; - mpc_int32_t *ResL = d->Res_L; - mpc_int32_t *ResR = d->Res_R; + mpc_int8_t *L; + mpc_int8_t *R; + mpc_int16_t *QL; + mpc_int16_t *QR; + mpc_int8_t *ResL = d->Res_L; + mpc_int8_t *ResR = d->Res_R; /************************ HEADER **************************/ ResL = d->Res_L; @@ -738,7 +854,7 @@ mpc_decoder_read_bitstream_sv6(mpc_decoder *d) /*********** DSCF ************/ if (d->DSCF_Flag_L[n]==1) { - L[2] = d->DSCF_Reference_L[n]; + //L[2] = d->DSCF_Reference_L[n]; switch (d->SCFI_L[n]) { case 3: @@ -797,11 +913,11 @@ mpc_decoder_read_bitstream_sv6(mpc_decoder *d) } } // update Reference for DSCF - d->DSCF_Reference_L[n] = L[2]; + //d->DSCF_Reference_L[n] = L[2]; } if (*ResR) { - R[2] = d->DSCF_Reference_R[n]; + //R[2] = d->DSCF_Reference_R[n]; /*********** DSCF ************/ if (d->DSCF_Flag_R[n]==1) { @@ -863,7 +979,7 @@ mpc_decoder_read_bitstream_sv6(mpc_decoder *d) } } // update Reference for DSCF - d->DSCF_Reference_R[n] = R[2]; + //d->DSCF_Reference_R[n] = R[2]; } } @@ -875,28 +991,28 @@ mpc_decoder_read_bitstream_sv6(mpc_decoder *d) // setting pointers x1 = mpc_table_SampleHuff[*ResL]; x2 = mpc_table_SampleHuff[*ResR]; - L = d->Q[n].L; - R = d->Q[n].R; + QL = d->Q[n].L; + QR = d->Q[n].R; if (x1!=NULL || x2!=NULL) for (k=0; k<36; ++k) { - if (x1 != NULL) *L++ = mpc_decoder_huffman_decode_fast(d, x1); - if (x2 != NULL) *R++ = mpc_decoder_huffman_decode_fast(d, x2); + if (x1 != NULL) *QL++ = mpc_decoder_huffman_decode_fast(d, x1); + if (x2 != NULL) *QR++ = mpc_decoder_huffman_decode_fast(d, x2); } if (*ResL>7 || *ResR>7) for (k=0; k<36; ++k) { - if (*ResL>7) *L++ = (mpc_int32_t)mpc_decoder_bitstream_read(d, Res_bit[*ResL]) - Dc[*ResL]; - if (*ResR>7) *R++ = (mpc_int32_t)mpc_decoder_bitstream_read(d, Res_bit[*ResR]) - Dc[*ResR]; + if (*ResL>7) *QL++ = (mpc_int16_t)mpc_decoder_bitstream_read(d, Res_bit[*ResL]) - Dc[*ResL]; + if (*ResR>7) *QR++ = (mpc_int16_t)mpc_decoder_bitstream_read(d, Res_bit[*ResR]) - Dc[*ResR]; } } } #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}; @@ -909,9 +1025,12 @@ mpc_decoder_read_bitstream_sv7(mpc_decoder *d) mpc_int32_t Max_used_Band=0; const HuffmanTyp *Table; mpc_int32_t idx; - mpc_int32_t *L ,*R; - mpc_int32_t *ResL,*ResR; + 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 *****************************/ ResL = d->Res_L; @@ -922,6 +1041,8 @@ mpc_decoder_read_bitstream_sv7(mpc_decoder *d) *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 @@ -941,6 +1062,8 @@ mpc_decoder_read_bitstream_sv7(mpc_decoder *d) // 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 ******************************/ @@ -961,148 +1084,215 @@ mpc_decoder_read_bitstream_sv7(mpc_decoder *d) 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; - L = d->Q[0].L; - R = d->Q[0].R; - for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR, L+=36, R+=36) + LQ = d->Q[0].L; + RQ = d->Q[0].R; + for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR, LQ+=36, RQ+=36) { /************** links **************/ switch (*ResL) { case -2: case -3: case -4: case -5: case -6: case -7: case -8: case -9: case -10: case -11: case -12: case -13: case -14: case -15: case -16: case -17: - L += 36; + LQ += 36; break; case -1: for (k=0; k<36; k++ ) { tmp = mpc_random_int(d); - *L++ = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510; + *LQ++ = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510; } break; case 0: - L += 36;// increase pointer + LQ += 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); - *L++ = idx30[idx]; - *L++ = idx31[idx]; - *L++ = idx32[idx]; + idx = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); + *LQ++ = idx30[idx]; + *LQ++ = idx31[idx]; + *LQ++ = 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); - *L++ = idx50[idx]; - *L++ = idx51[idx]; + idx = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); + *LQ++ = idx50[idx]; + *LQ++ = 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) + *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) - *L++ = 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) - *L++ = mpc_decoder_huffman_decode_fast(d, Table); + *LQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); break; case 6: + if (mpc_decoder_bitstream_read(d, 1)) { + Table = mpc_table_HuffQ[1][6]; + LUT = LUT6_1; + max_length = 7; + for (k=0; k<36; ++k) + *LQ++ = HUFFMAN_DECODE_FASTERER ( d, Table, LUT, max_length ); + } else { + Table = mpc_table_HuffQ[0][6]; + LUT = LUT6_0; + max_length = 7; + for (k=0; k<36; ++k) + *LQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); + } + break; case 7: - Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResL]; - for (k=0; k<36; ++k) - *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) + *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) - *L++ = (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: return; @@ -1112,57 +1302,125 @@ mpc_decoder_read_bitstream_sv7(mpc_decoder *d) { case -2: case -3: case -4: case -5: case -6: case -7: case -8: case -9: case -10: case -11: case -12: case -13: case -14: case -15: case -16: case -17: - R += 36; + RQ += 36; break; case -1: for (k=0; k<36; k++ ) { tmp = mpc_random_int(d); - *R++ = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510; + *RQ++ = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510; } break; case 0: - R += 36;// increase pointer + RQ += 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); - *R++ = idx30[idx]; - *R++ = idx31[idx]; - *R++ = idx32[idx]; + idx = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); + *RQ++ = idx30[idx]; + *RQ++ = idx31[idx]; + *RQ++ = 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); - *R++ = idx50[idx]; - *R++ = idx51[idx]; + idx = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); + *RQ++ = idx50[idx]; + *RQ++ = 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) + *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) - *R++ = 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) - *R++ = mpc_decoder_huffman_decode_fast(d, Table); + *RQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); break; case 6: - 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][6]; + LUT = LUT6_1; + max_length = 7; for (k=0; k<36; ++k) - *R++ = mpc_decoder_huffman_decode(d, Table); - break; + *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: + if (mpc_decoder_bitstream_read(d, 1)) { + Table = mpc_table_HuffQ[1][7]; + LUT = LUT7_1; + max_length = 8; + for (k=0; k<36; ++k) + *RQ++ = HUFFMAN_DECODE_FASTERER ( d, Table, LUT, max_length ); + } else { + Table = mpc_table_HuffQ[0][7]; + LUT = LUT7_0; + max_length = 8; + for (k=0; k<36; ++k) + *RQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); + } + break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: tmp = Dc[*ResR]; for (k=0; k<36; ++k) - *R++ = (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: return; @@ -1182,6 +1440,7 @@ void mpc_decoder_setup(mpc_decoder *d, mpc_reader *r) d->FrameWasValid = 0; d->OverallFrames = 0; d->DecodedFrames = 0; + d->MaxDecodedFrames = 0; d->TrueGaplessPresent = 0; d->last_block_samples = 0; d->WordsRead = 0; @@ -1193,21 +1452,58 @@ void mpc_decoder_setup(mpc_decoder *d, mpc_reader *r) 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; + d->Use_StaticSeekTable = FALSE; + d->SeekTable_Step = 1; + d->SeekTableIndex = 0; + d->SeekTableCounter = 0; + d->Max_SeekTable_Size = 0; mpc_decoder_initialisiere_quantisierungstabellen(d, 1.0f); +#if 0 + mpc_decoder_init_huffman_sv6(d); + mpc_decoder_init_huffman_sv7(d); +#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; - /* Link struct entries to actual tables which are placed in IRAM */ - d->V_L = V_L; - d->V_R = V_R; #if defined(CPU_COLDFIRE)&& !defined(SIMULATOR) coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE); #endif } +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); @@ -1220,26 +1516,53 @@ void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si) d->SampleRate = (mpc_int32_t)si->sample_freq; 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_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; - } + mpc_decoder_set_streaminfo(d, si); - // AB: fill buffer and initialize decoder - f_read_dword(d, d->Speicher, MEMSIZE ); - d->dword = d->Speicher[d->Zaehler = 0]; + // 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]); + d->SeekTable_Step = 1; + return TRUE; } @@ -1253,21 +1576,19 @@ helper1(mpc_decoder *d, mpc_uint32_t bitpos) { 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) { @@ -1278,10 +1599,28 @@ helper3(mpc_decoder *d, mpc_uint32_t bitpos, mpc_uint32_t* buffoffs) 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; @@ -1301,55 +1640,170 @@ mpc_bool_t mpc_decoder_seek_seconds(mpc_decoder *d, double seconds) 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->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 ); memset(d->SCFI_R , 0, sizeof d->SCFI_R ); +#ifdef MPC_SUPPORT_SV456 memset(d->DSCF_Flag_L , 0, sizeof d->DSCF_Flag_L ); memset(d->DSCF_Flag_R , 0, sizeof d->DSCF_Flag_R ); - memset(d->DSCF_Reference_L, 0, sizeof d->DSCF_Reference_L ); - memset(d->DSCF_Reference_R, 0, sizeof d->DSCF_Reference_R ); +#endif + //memset(d->DSCF_Reference_L, 0, sizeof d->DSCF_Reference_L ); + //memset(d->DSCF_Reference_R, 0, sizeof d->DSCF_Reference_R ); 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 + 1 - d->SeekTable_Step; + + if ((!d->Use_SeekTable && delta < 0) || d->MaxDecodedFrames == 0) { - helper2(d, fpos); + mpc_decoder_reset_state(d); + + // starts from the beginning since no frames have been decoded yet, or not using seek table + fpos = get_initial_fpos(d, d->StreamVersion); + + // seek to the first frame + mpc_decoder_seek_to(d, fpos); + + // reset number of decoded frames + d->DecodedFrames = 0; + + if (d->Use_SeekTable) { + // jump to the last frame, updating seek table + if (d->SeekTable_Step == 1) { + d->SeekTable[0] = (mpc_uint32_t)fpos; + for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) + d->SeekTable[d->DecodedFrames+1] = mpc_decoder_jump_frame(d); + } else { + d->SeekTableIndex = 0; + d->SeekTableCounter = (mpc_uint32_t)fpos; + for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) { + if (d->DecodedFrames % d->SeekTable_Step == 0) { + d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter; + d->SeekTableIndex += 1; + d->SeekTableCounter = 0; + } + d->SeekTableCounter += mpc_decoder_jump_frame(d); + } + } + } else { + // just jump to the last frame + for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) + mpc_decoder_jump_frame(d); + } + + } else if (delta < 0) { + + mpc_decoder_reset_state(d); + + // jumps backwards using the seek table + fpos = d->SeekTable[0]; + if (d->SeekTable_Step == 1) { + for (d->DecodedFrames = 0;d->DecodedFrames < lastFrame; d->DecodedFrames++) + fpos += d->SeekTable[d->DecodedFrames+1]; + } else { + d->SeekTableIndex = 0; + //d->SeekTableCounter = 0; + for (d->DecodedFrames = 0;d->DecodedFrames < lastFrame; d->DecodedFrames+=d->SeekTable_Step, d->SeekTableIndex++) + fpos += d->SeekTable[d->SeekTableIndex+1]; + d->SeekTableCounter = d->SeekTable[d->SeekTableIndex]; + } + mpc_decoder_seek_to(d, fpos); + + } else if (delta > 33) { + + mpc_decoder_reset_state(d); + + // jumps forward from the current position + if (d->Use_SeekTable) { + + if (d->MaxDecodedFrames > lastFrame) { // REVIEW: Correct?? or (d->MaxDecodedFrames > d->DecodedFrames) + // jump to the last usable position in the seek table + if (d->SeekTable_Step == 1) { + fpos = mpc_decoder_bits_read(d); + for (; d->DecodedFrames < d->MaxDecodedFrames && d->DecodedFrames < lastFrame; d->DecodedFrames++) + fpos += d->SeekTable[d->DecodedFrames+1]; + } else { + // could test SeekTable offset and jump to next entry but this is easier for now... + //d->SeekTableIndex = 0; + //d->SeekTableCounter = 0; + fpos = d->SeekTable[0]; + d->SeekTableIndex = 0; + for (d->DecodedFrames = 0;d->DecodedFrames < d->MaxDecodedFrames && d->DecodedFrames < lastFrame; d->DecodedFrames+=d->SeekTable_Step, d->SeekTableIndex++) + fpos += d->SeekTable[d->SeekTableIndex+1]; + d->SeekTableCounter = d->SeekTable[d->SeekTableIndex]; + } + + mpc_decoder_seek_to(d, fpos); + } + if (d->SeekTable_Step == 1) { + for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) + d->SeekTable[d->DecodedFrames+1] = mpc_decoder_jump_frame(d); + } else { + for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) { + if (d->DecodedFrames % d->SeekTable_Step == 0) { + d->SeekTable[d->SeekTableIndex] = d->SeekTableCounter; + d->SeekTableIndex += 1; + d->SeekTableCounter = 0; + } + d->SeekTableCounter += mpc_decoder_jump_frame(d); + } + } + } else { + for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) + mpc_decoder_jump_frame(d); + } + + } + + // REVIEW: Needed? + mpc_decoder_update_buffer(d); + + for (;d->DecodedFrames < seekFrame; d->DecodedFrames++) { - // 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 @@ -1358,28 +1812,123 @@ mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample) 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; + + // 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); + 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); + } + } - // LastBitsRead = BitsRead (); - // LastFrame = d->DecodedFrames; - 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; + } +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; + +} diff --git a/apps/codecs/libmusepack/musepack.h b/apps/codecs/libmusepack/musepack.h index 9155f3f74d..549ea798a9 100644 --- a/apps/codecs/libmusepack/musepack.h +++ b/apps/codecs/libmusepack/musepack.h @@ -132,6 +132,12 @@ mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample); /// Seeks to specified position in seconds in the source stream. mpc_bool_t mpc_decoder_seek_seconds(mpc_decoder *d, double seconds); +/// Sets the static seek table pointer. +void mpc_decoder_set_seek_table(mpc_decoder *d, mpc_uint32_t *seek_table, mpc_uint32_t max_table_size); + +/// Cleans up the decoder +void mpc_decoder_destroy(mpc_decoder *d); + #ifdef __cplusplus } #endif // __cplusplus diff --git a/apps/codecs/libmusepack/synth_filter.c b/apps/codecs/libmusepack/synth_filter.c index c03355b01b..2b14c26c92 100644 --- a/apps/codecs/libmusepack/synth_filter.c +++ b/apps/codecs/libmusepack/synth_filter.c @@ -334,6 +334,7 @@ static void Synthese_Filter_float_internal(MPC_SAMPLE_FORMAT * OutData,MPC_SAMPL 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; @@ -429,7 +430,7 @@ static void Synthese_Filter_float_internal(MPC_SAMPLE_FORMAT * OutData,MPC_SAMPL , 1); Data += 1; - #endif + #endif } V -= 32;//bleh OutData+=32; @@ -452,7 +453,7 @@ mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT* OutData) 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])); } diff --git a/apps/codecs/mpc.c b/apps/codecs/mpc.c index 6629801a56..c1fa0d7a99 100644 --- a/apps/codecs/mpc.c +++ b/apps/codecs/mpc.c @@ -22,7 +22,7 @@ CODEC_HEADER -mpc_decoder decoder; +mpc_decoder decoder IBSS_ATTR; /* Our implementations of the mpc_reader callback functions. */ mpc_int32_t read_impl(void *data, void *ptr, mpc_int32_t size) @@ -63,7 +63,8 @@ mpc_bool_t canseek_impl(void *data) return true; } -MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH] IBSS_ATTR; +MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH]; +mpc_uint32_t seek_table[10000]; #ifdef USE_IRAM extern char iramcopy[]; @@ -92,6 +93,7 @@ enum codec_status codec_start(struct codec_api *api) ci->configure(DSP_DITHER, (bool *)false); ci->configure(DSP_SET_SAMPLE_DEPTH, (long *)(28)); ci->configure(CODEC_SET_FILEBUF_CHUNKSIZE, (long *)(1024*16)); + ci->configure(CODEC_SET_FILEBUF_PRESEEK, (long *)(0)); /* Create a decoder instance */ reader.read = read_impl; @@ -101,6 +103,11 @@ enum codec_status codec_start(struct codec_api *api) reader.canseek = canseek_impl; reader.data = ci; + /* Ensure that SeekTable is clear since decoder is reused */ + decoder.SeekTable = NULL; + + mpc_decoder_set_seek_table(&decoder, seek_table, sizeof(seek_table)); + next_track: if (codec_init(api)) { retval = CODEC_ERROR; @@ -113,7 +120,7 @@ next_track: retval = CODEC_ERROR; goto done; } - 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 */ @@ -139,21 +146,23 @@ next_track: /* 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) { if (ci->seek_time == 1 && mpc_decoder_seek_sample(&decoder, 0)) { samplesdone = 0; @@ -178,7 +187,7 @@ next_track: status*sizeof(MPC_SAMPLE_FORMAT))) ci->yield(); samplesdone += status; - ci->set_elapsed(samplesdone/(frequency/1000)); + ci->set_elapsed(samplesdone/frequency); } } while (status != 0); retval = CODEC_OK; @@ -188,6 +197,7 @@ done: goto next_track; exit: + mpc_decoder_destroy(&decoder); return retval; } -- cgit v1.2.3