summaryrefslogtreecommitdiffstats
path: root/apps/codecs
diff options
context:
space:
mode:
authorThom Johansen <thomj@rockbox.org>2006-08-31 18:18:57 +0000
committerThom Johansen <thomj@rockbox.org>2006-08-31 18:18:57 +0000
commit20332bce1d49d7285109564d2e29ee18b0acd54e (patch)
tree9e423a673c6f7e03816a0f0ca785ef3915405b44 /apps/codecs
parent6af8603d9a8894e644f0b9508f2142c2b56d09a3 (diff)
downloadrockbox-20332bce1d49d7285109564d2e29ee18b0acd54e.tar.gz
rockbox-20332bce1d49d7285109564d2e29ee18b0acd54e.zip
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
Diffstat (limited to 'apps/codecs')
-rw-r--r--apps/codecs/libmusepack/config_types.h2
-rw-r--r--apps/codecs/libmusepack/decoder.h46
-rw-r--r--apps/codecs/libmusepack/huffman.h4
-rw-r--r--apps/codecs/libmusepack/huffsv7.c20
-rw-r--r--apps/codecs/libmusepack/internal.h4
-rw-r--r--apps/codecs/libmusepack/mpc_decoder.c969
-rw-r--r--apps/codecs/libmusepack/musepack.h6
-rw-r--r--apps/codecs/libmusepack/synth_filter.c5
-rw-r--r--apps/codecs/mpc.c32
9 files changed, 836 insertions, 252 deletions
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 <huffman.h>
#include <requant.h>
-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;
}