diff --git a/apps/codecs/libmusepack/AUTHORS b/apps/codecs/libmusepack/AUTHORS index 3f61a8a0a0..1bcac63765 100644 --- a/apps/codecs/libmusepack/AUTHORS +++ b/apps/codecs/libmusepack/AUTHORS @@ -1,4 +1,4 @@ -libmusepack is the result of the work of many people: +libmpcdec is the result of the work of many people: * Andree Buschmann and Frank Klemm Original implementation and core development. diff --git a/apps/codecs/libmusepack/ChangeLog b/apps/codecs/libmusepack/ChangeLog index 6a9b7dfdf8..6c998480bd 100644 --- a/apps/codecs/libmusepack/ChangeLog +++ b/apps/codecs/libmusepack/ChangeLog @@ -1,3 +1,31 @@ +1.3.0 + * first sv8 release + * major changes in the API (decoder and demuxer are split) + +1.2.3 + * Reduced memory usage and code size. Patch by Peter Pawlowski + +1.2.2 + * Fixed compilation under OpenBSD + * Unix EOF again + +1.2.1 + * Warnings cleanup, patch by Tomas Salfischberger, Thom Johansen and + Daniel Stenberg (Rockbox) + * Mplayer interface, patch by Reimar Doffinger + * Unix EOF everywhere + +1.2 + * 1.1.1 broke the API (BOOL type changed to mpc_bool_t). Version bumped to 1.2 to reflect the major change. Sorry to those who were caught by this error + * Fixed relative/absolute includes (#include "stuff.h" in /include/mpcdec, #include in src/) + * Added msvc project files + * Changed mpc_reader_t structure, any specific data of the reader's + implementations should be hidden behind the (void*) data pointer. (example + in default implementation mpc_reader_file) + * Renamed to libmpcdec (to make room for libmpcenc) + +1.1.1 + * fix for fixed-point mode bug 1.1 * add compliance & cleanup patches from Michael Roitzsch of xine project diff --git a/apps/codecs/libmusepack/README b/apps/codecs/libmusepack/README deleted file mode 100644 index 5bc42b70db..0000000000 --- a/apps/codecs/libmusepack/README +++ /dev/null @@ -1,6 +0,0 @@ -Musepack Decoder Library 1.1: - -run "./configure; make" - -To create a sample app using the musepack decoder library in src/ -Check src/sample.cpp for more details. diff --git a/apps/codecs/libmusepack/README.rockbox b/apps/codecs/libmusepack/README.rockbox deleted file mode 100644 index 13c93a2518..0000000000 --- a/apps/codecs/libmusepack/README.rockbox +++ /dev/null @@ -1,27 +0,0 @@ -Library: libmusepack-1.1 (Released 2005-01-22 (I think)) -Imported: 2005-04-12 by Thom Johansen - - -This directory contains a local version of libmusepack for use by Rockbox -for software decoding and encoding of Musepack files. - - -LICENSING INFORMATION - -libmusepack is distributed under a modified BSD license - see the files AUTHORS -and COPYING in this directory for details. - - -IMPORT DETAILS - -The base version first imported into Rockbox was the libmusepack included -in the libmusepack-1.1.tar.bz2 distribution, downloaded on 2005-04-11 from -www.musepack.net. - -The contents of the libmusepack-1.1/, libmusepack-1.1/src/ and -libmusepack-1.1/include/ were all put in one directory for simplicity, and -the sample decoder and automake/autoconf stuff were removed. The default -FILE* based IO handlers in mpc_reader.c were also removed. Some small -modifications to make the library compilable and compatible with Rockbox -was made. - diff --git a/apps/codecs/libmusepack/SOURCES b/apps/codecs/libmusepack/SOURCES index 0de114336f..31848214e0 100644 --- a/apps/codecs/libmusepack/SOURCES +++ b/apps/codecs/libmusepack/SOURCES @@ -1,7 +1,8 @@ -huffsv46.c -huffsv7.c -idtag.c +crc32.c +huffman.c +mpc_bits_reader.c mpc_decoder.c +mpc_demux.c requant.c streaminfo.c synth_filter.c diff --git a/apps/codecs/libmusepack/config-mpc.h b/apps/codecs/libmusepack/config-mpc.h deleted file mode 100644 index 8d764c4031..0000000000 --- a/apps/codecs/libmusepack/config-mpc.h +++ /dev/null @@ -1,105 +0,0 @@ -/* include/config.h. Generated by configure. */ -/* include/config.h.in. Generated from configure.in by autoheader. */ - -/* Define to 1 if you have the header file. */ -#define HAVE_DLFCN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `memmove' function. */ -#define HAVE_MEMMOVE 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the `memset' function. */ -#define HAVE_MEMSET 1 - -/* Define to 1 if the system has the type `ptrdiff_t'. */ -#define HAVE_PTRDIFF_T 1 - -/* Define to 1 if you have the `sqrt' function. */ -/* #undef HAVE_SQRT */ - -/* Define to 1 if stdbool.h conforms to C99. */ -#define HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if the system has the type `_Bool'. */ -#define HAVE__BOOL 1 - -/* Name of package */ -#define PACKAGE "libmusepack" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "" - -/* The size of a `int', as computed by sizeof. */ -#define SIZEOF_INT 4 - -/* The size of a `long', as computed by sizeof. */ -#define SIZEOF_LONG 4 - -/* The size of a `long long', as computed by sizeof. */ -#define SIZEOF_LONG_LONG 8 - -/* The size of a `short', as computed by sizeof. */ -#define SIZEOF_SHORT 2 - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Version number of package */ -#define VERSION "1.1" - -/* Define to 1 if your processor stores words with the most significant byte - first (like Motorola and SPARC, unlike Intel and VAX). */ -/* #undef WORDS_BIGENDIAN */ - -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `long' if does not define. */ -/* #undef off_t */ - -/* Define to `unsigned' if does not define. */ -/* #undef size_t */ diff --git a/apps/codecs/libmusepack/config_types.h b/apps/codecs/libmusepack/config_types.h deleted file mode 100644 index 96e8b90430..0000000000 --- a/apps/codecs/libmusepack/config_types.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - Copyright (c) 2005, The Musepack Development Team - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of the The Musepack Development Team nor the - names of its contributors may be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef __MUSEPACK_CONFIG_TYPES_H__ -#define __MUSEPACK_CONFIG_TYPES_H__ - -typedef unsigned char mpc_bool_t; -#define TRUE 1 -#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; -typedef unsigned int mpc_uint32_t; -typedef long long mpc_int64_t; - -#endif // __MUSEPACK_CONFIG_TYPES_H__ diff --git a/apps/codecs/libmusepack/crc32.c b/apps/codecs/libmusepack/crc32.c new file mode 100755 index 0000000000..f9f3b8a73d --- /dev/null +++ b/apps/codecs/libmusepack/crc32.c @@ -0,0 +1,56 @@ +/* +* C Implementation: crc32 +* +* code from http://www.w3.org/TR/PNG/#D-CRCAppendix +* +*/ + +/* Table of CRCs of all 8-bit messages. */ +static unsigned long crc_table[256]; + +/* Flag: has the table been computed? Initially false. */ +static int crc_table_computed = 0; + +/* Make the table for a fast CRC. */ +static void make_crc_table(void) +{ + unsigned long c; + int n, k; + + for (n = 0; n < 256; n++) { + c = (unsigned long) n; + for (k = 0; k < 8; k++) { + if (c & 1) + c = 0xedb88320L ^ (c >> 1); + else + c = c >> 1; + } + crc_table[n] = c; + } + crc_table_computed = 1; +} + + +/* Update a running CRC with the bytes buf[0..len-1]--the CRC + should be initialized to all 1's, and the transmitted value + is the 1's complement of the final running CRC (see the + crc() routine below). */ + +static unsigned long update_crc(unsigned long crc, unsigned char *buf, int len) +{ + unsigned long c = crc; + int n; + + if (!crc_table_computed) + make_crc_table(); + for (n = 0; n < len; n++) { + c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + } + return c; +} + +/* Return the CRC of the bytes buf[0..len-1]. */ +unsigned long mpc_crc32(unsigned char *buf, int len) +{ + return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL; +} diff --git a/apps/codecs/libmusepack/decoder.h b/apps/codecs/libmusepack/decoder.h index 9031bf29e7..b3d24cf4ea 100644 --- a/apps/codecs/libmusepack/decoder.h +++ b/apps/codecs/libmusepack/decoder.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, The Musepack Development Team + Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,107 +31,71 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /// \file decoder.h +#ifndef _MPCDEC_DECODER_H_ +#define _MPCDEC_DECODER_H_ +#ifdef WIN32 +#pragma once +#endif -#ifndef _mpcdec_decoder_h_ -#define _mpcdec_decoder_h_ - -#include "huffman.h" -#include "math.h" -#include "musepack.h" #include "reader.h" -#include "streaminfo.h" -// define this to enable/disable support for streamversion SV4-6 -//#define MPC_SUPPORT_SV456 +#ifdef __cplusplus +extern "C" { +#endif -// SCF_HACK is used to avoid possible distortion after seeking with mpc files -// background: scf's are coded differential in time domain. if you seek to the -// desired postion it might happen that the baseline is missed and the resulting -// scf is much too high (hissing noise). this hack uses the lowest scaling until -// a non-differential scf could be decoded after seek. through this hack subbands -// are faded out until there was at least a single non-differential scf found. -#define SCF_HACK +#define SEEKING_TABLE_SIZE 256u +// set it to SLOW_SEEKING_WINDOW to not use fast seeking +#define FAST_SEEKING_WINDOW 32 +// set it to FAST_SEEKING_WINDOW to only use fast seeking +#define SLOW_SEEKING_WINDOW 0x80000000 enum { - MPC_V_MEM = 2304, - MPC_DECODER_MEMSIZE = 16384, // overall buffer size (words) - MPC_SEEK_BUFFER_SIZE = 8192, // seek buffer size (words) + MPC_V_MEM = 2304, + MPC_DECODER_MEMSIZE = 16384, // overall buffer size }; -typedef struct { - mpc_int16_t L [36]; - mpc_int16_t R [36]; -} QuantTyp; - -typedef struct mpc_decoder_t { - mpc_reader *r; - +struct mpc_decoder_t { /// @name internal state variables //@{ + mpc_uint32_t stream_version; ///< Streamversion of stream + mpc_int32_t max_band; ///< Maximum band-index used in stream (0...31) + mpc_uint32_t ms; ///< Mid/side stereo (0: off, 1: on) + mpc_uint32_t channels; ///< Number of channels in stream - mpc_uint32_t next; - mpc_uint32_t dword; /// currently decoded 32bit-word - mpc_uint32_t pos; /// bit-position within dword - mpc_uint32_t *Speicher; /// read-buffer - mpc_uint32_t Zaehler; /// actual index within read-buffer - mpc_uint32_t Ring; + mpc_uint64_t samples; ///< Number of samples in stream - mpc_uint32_t samples_to_skip; - mpc_uint32_t last_block_samples; - mpc_uint32_t FwdJumpInfo; - mpc_uint32_t ActDecodePos; - - - mpc_uint32_t DecodedFrames; - mpc_uint32_t OverallFrames; - mpc_int32_t SampleRate; // Sample frequency - - mpc_uint32_t StreamVersion; // version of bitstream - mpc_int32_t Max_Band; - mpc_uint32_t MPCHeaderPos; // AB: needed to support ID3v2 - - mpc_uint32_t FrameWasValid; - mpc_uint32_t MS_used; // MS-coding used ? - mpc_uint32_t TrueGaplessPresent; - - mpc_uint32_t WordsRead; // counts amount of decoded dwords + mpc_uint64_t decoded_samples; ///< Number of samples decoded from file begining + mpc_uint32_t samples_to_skip; ///< Number samples to skip (used for seeking) + mpc_int32_t last_max_band; ///< number of bands used in the last frame // randomizer state variables - mpc_uint32_t __r1; - mpc_uint32_t __r2; + mpc_uint32_t __r1; + mpc_uint32_t __r2; - 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_int8_t Res_L [32]; - mpc_int8_t Res_R [32]; // holds the chosen quantizer for each subband -#ifdef MPC_SUPPORT_SV456 + mpc_int32_t SCF_Index_L [32] [3]; + mpc_int32_t SCF_Index_R [32] [3]; // holds scalefactor-indices + mpc_quantizer 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_bool_t DSCF_Flag_L [32]; mpc_bool_t DSCF_Flag_R [32]; // differential SCF used? -#endif - mpc_int8_t SCFI_L [32]; - mpc_int8_t SCFI_R [32]; // describes order of transmitted SCF + mpc_int32_t SCFI_L [32]; + mpc_int32_t SCFI_R [32]; // describes order of transmitted SCF mpc_bool_t MS_Flag[32]; // MS used? - - mpc_uint32_t SeekTableCounter; // used to sum up skip info, if SeekTable_Step != 1 - mpc_uint32_t MaxDecodedFrames; // Maximum frames decoded (indicates usable seek table entries) - mpc_uint32_t* SeekTable; // seek table itself - mpc_uint8_t SeekTable_Step; // 1<= 0 ; i--) { + if ((table[idx].Code >> shift) < i) { + lut[i].Length = table[idx].Length; + lut[i].Value = table[idx].Value; + } else { + if (table[idx].Length <= bits) { + lut[i].Length = table[idx].Length; + lut[i].Value = table[idx].Value; + } else { + lut[i].Length = 0; + lut[i].Value = idx; + } + if (i != 0) + do { + idx++; + } while ((table[idx].Code >> shift) == i); + } + } +} + +static void can_fill_lut(mpc_can_data * data, const int bits) +{ + int i, idx = 0; + const int shift = 16 - bits; + const mpc_huffman * table = data->table; + const mpc_int8_t * sym = data->sym; + mpc_huff_lut * lut = data->lut; + for (i = (1 << bits) - 1; i >= 0 ; i--) { + if ((table[idx].Code >> shift) < i) { + if (table[idx].Length <= bits) { + lut[i].Length = table[idx].Length; + lut[i].Value = sym[(table[idx].Value - (i >> (bits - table[idx].Length))) & 0xFF]; + } else { + lut[i].Length = 0; + lut[i].Value = idx; + } + } else { + if (table[idx].Length <= bits) { + lut[i].Length = table[idx].Length; + lut[i].Value = sym[(table[idx].Value - (i >> (bits - table[idx].Length))) & 0xFF]; + } else { + lut[i].Length = 0; + lut[i].Value = idx; + } + if (i != 0) + do { + idx++; + } while ((table[idx].Code >> shift) == i); + } + } +} + +void huff_init_lut(const int bits) +{ + /* sv7: create vlc lookup tables */ + mpc_HuffDSCF.table = mpc_table_HuffDSCF ; huff_fill_lut(mpc_HuffDSCF.table , mpc_HuffDSCF.lut , bits); + mpc_HuffHdr.table = mpc_table_HuffHdr ; huff_fill_lut(mpc_HuffHdr.table , mpc_HuffHdr.lut , bits); + mpc_HuffQ[0][0].table = mpc_table_HuffQ1[0]; huff_fill_lut(mpc_HuffQ[0][0].table, mpc_HuffQ[0][0].lut, bits); + mpc_HuffQ[0][1].table = mpc_table_HuffQ1[1]; huff_fill_lut(mpc_HuffQ[0][1].table, mpc_HuffQ[0][1].lut, bits); + mpc_HuffQ[1][0].table = mpc_table_HuffQ2[0]; huff_fill_lut(mpc_HuffQ[1][0].table, mpc_HuffQ[1][0].lut, bits); + mpc_HuffQ[1][1].table = mpc_table_HuffQ2[1]; huff_fill_lut(mpc_HuffQ[1][1].table, mpc_HuffQ[1][1].lut, bits); + mpc_HuffQ[2][0].table = mpc_table_HuffQ3[0]; huff_fill_lut(mpc_HuffQ[2][0].table, mpc_HuffQ[2][0].lut, bits); + mpc_HuffQ[2][1].table = mpc_table_HuffQ3[1]; huff_fill_lut(mpc_HuffQ[2][1].table, mpc_HuffQ[2][1].lut, bits); + mpc_HuffQ[3][0].table = mpc_table_HuffQ4[0]; huff_fill_lut(mpc_HuffQ[3][0].table, mpc_HuffQ[3][0].lut, bits); + mpc_HuffQ[3][1].table = mpc_table_HuffQ4[1]; huff_fill_lut(mpc_HuffQ[3][1].table, mpc_HuffQ[3][1].lut, bits); + mpc_HuffQ[4][0].table = mpc_table_HuffQ5[0]; huff_fill_lut(mpc_HuffQ[4][0].table, mpc_HuffQ[4][0].lut, bits); + mpc_HuffQ[4][1].table = mpc_table_HuffQ5[1]; huff_fill_lut(mpc_HuffQ[4][1].table, mpc_HuffQ[4][1].lut, bits); + mpc_HuffQ[5][0].table = mpc_table_HuffQ6[0]; huff_fill_lut(mpc_HuffQ[5][0].table, mpc_HuffQ[5][0].lut, bits); + mpc_HuffQ[5][1].table = mpc_table_HuffQ6[1]; huff_fill_lut(mpc_HuffQ[5][1].table, mpc_HuffQ[5][1].lut, bits); + mpc_HuffQ[6][0].table = mpc_table_HuffQ7[0]; huff_fill_lut(mpc_HuffQ[6][0].table, mpc_HuffQ[6][0].lut, bits); + mpc_HuffQ[6][1].table = mpc_table_HuffQ7[1]; huff_fill_lut(mpc_HuffQ[6][1].table, mpc_HuffQ[6][1].lut, bits); + + /* sv8: create vlc lookup tables */ + mpc_can_Bands.table = mpc_huff_Bands ; mpc_can_Bands.sym = mpc_sym_Bands; + mpc_can_SCFI[0].table = mpc_huff_SCFI_1; mpc_can_SCFI[0].sym = mpc_sym_SCFI_1; can_fill_lut(&mpc_can_SCFI[0], bits); + mpc_can_SCFI[1].table = mpc_huff_SCFI_2; mpc_can_SCFI[1].sym = mpc_sym_SCFI_2; can_fill_lut(&mpc_can_SCFI[1], bits); + mpc_can_DSCF[0].table = mpc_huff_DSCF_1; mpc_can_DSCF[0].sym = mpc_sym_DSCF_1; can_fill_lut(&mpc_can_DSCF[0], bits); + mpc_can_DSCF[1].table = mpc_huff_DSCF_2; mpc_can_DSCF[1].sym = mpc_sym_DSCF_2; can_fill_lut(&mpc_can_DSCF[1], bits); + mpc_can_Res[0].table = mpc_huff_Res_1 ; mpc_can_Res[0].sym = mpc_sym_Res_1 ; can_fill_lut(&mpc_can_Res[0] , bits); + mpc_can_Res[1].table = mpc_huff_Res_2 ; mpc_can_Res[1].sym = mpc_sym_Res_2 ; can_fill_lut(&mpc_can_Res[1] , bits); + mpc_can_Q1.table = mpc_huff_Q1 ; mpc_can_Q1.sym = mpc_sym_Q1 ; can_fill_lut(&mpc_can_Q1 , bits); + mpc_can_Q9up.table = mpc_huff_Q9up ; mpc_can_Q9up.sym = mpc_sym_Q9up ; can_fill_lut(&mpc_can_Q9up , bits); + mpc_can_Q[0][0].table = mpc_huff_Q2_1 ; mpc_can_Q[0][0].sym = mpc_sym_Q2_1 ; can_fill_lut(&mpc_can_Q[0][0], bits); + mpc_can_Q[0][1].table = mpc_huff_Q2_2 ; mpc_can_Q[0][1].sym = mpc_sym_Q2_2 ; can_fill_lut(&mpc_can_Q[0][1], bits); + mpc_can_Q[1][0].table = mpc_huff_Q3 ; mpc_can_Q[1][0].sym = mpc_sym_Q3 ; can_fill_lut(&mpc_can_Q[1][0], bits); + mpc_can_Q[1][1].table = mpc_huff_Q4 ; mpc_can_Q[1][1].sym = mpc_sym_Q4 ; can_fill_lut(&mpc_can_Q[1][1], bits); + mpc_can_Q[2][0].table = mpc_huff_Q5_1 ; mpc_can_Q[2][0].sym = mpc_sym_Q5_1 ; can_fill_lut(&mpc_can_Q[2][0], bits); + mpc_can_Q[2][1].table = mpc_huff_Q5_2 ; mpc_can_Q[2][1].sym = mpc_sym_Q5_2 ; can_fill_lut(&mpc_can_Q[2][1], bits); + mpc_can_Q[3][0].table = mpc_huff_Q6_1 ; mpc_can_Q[3][0].sym = mpc_sym_Q6_1 ; can_fill_lut(&mpc_can_Q[3][0], bits); + mpc_can_Q[3][1].table = mpc_huff_Q6_2 ; mpc_can_Q[3][1].sym = mpc_sym_Q6_2 ; can_fill_lut(&mpc_can_Q[3][1], bits); + mpc_can_Q[4][0].table = mpc_huff_Q7_1 ; mpc_can_Q[4][0].sym = mpc_sym_Q7_1 ; can_fill_lut(&mpc_can_Q[4][0], bits); + mpc_can_Q[4][1].table = mpc_huff_Q7_2 ; mpc_can_Q[4][1].sym = mpc_sym_Q7_2 ; can_fill_lut(&mpc_can_Q[4][1], bits); + mpc_can_Q[5][0].table = mpc_huff_Q8_1 ; mpc_can_Q[5][0].sym = mpc_sym_Q8_1 ; can_fill_lut(&mpc_can_Q[5][0], bits); + mpc_can_Q[5][1].table = mpc_huff_Q8_2 ; mpc_can_Q[5][1].sym = mpc_sym_Q8_2 ; can_fill_lut(&mpc_can_Q[5][1], bits); +} diff --git a/apps/codecs/libmusepack/huffman.h b/apps/codecs/libmusepack/huffman.h index 87fd5c15a4..1244149184 100644 --- a/apps/codecs/libmusepack/huffman.h +++ b/apps/codecs/libmusepack/huffman.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, The Musepack Development Team + Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,23 +31,53 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /// \file huffman.h /// Data structures and functions for huffman coding. -#ifndef _mpcdec_huffman_h_ -#define _mpcdec_huffman_h_ +#ifndef _MPCDEC_HUFFMAN_H_ +#define _MPCDEC_HUFFMAN_H_ +#ifdef WIN32 +#pragma once +#endif -#include "config_types.h" -#include "decoder.h" +#include "mpc_types.h" -struct mpc_decoder_t; // forward declare to break circular dependencies +#ifdef __cplusplus +extern "C" { +#endif + +// LUT size parameter, LUT size is 1 << LUT_DEPTH +#define LUT_DEPTH 6 /// Huffman table entry. -typedef struct huffman_type_t { - mpc_uint32_t Code; - mpc_uint8_t Length; - mpc_int8_t Value; -} HuffmanTyp; +typedef struct mpc_huffman_t { + mpc_uint16_t Code; + mpc_uint8_t Length; + mpc_int8_t Value; +} mpc_huffman; -#endif // _mpcdec_huffman_h_ +/// Huffman LUT entry. +typedef struct mpc_huff_lut_t { + mpc_uint8_t Length; + mpc_int8_t Value; +} mpc_huff_lut; + +/// Type used for huffman LUT decoding +typedef struct mpc_lut_data_t { + mpc_huffman const *table; + mpc_huff_lut lut[1 << LUT_DEPTH]; +} mpc_lut_data; + +/// Type used for canonical huffman decoding +typedef struct mpc_can_data_t { + mpc_huffman const *table; + mpc_int8_t const *sym; + mpc_huff_lut lut[1 << LUT_DEPTH]; +} mpc_can_data; + +void huff_init_lut(const int bits); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/apps/codecs/libmusepack/huffsv46.c b/apps/codecs/libmusepack/huffsv46.c deleted file mode 100644 index 20d754c7bb..0000000000 --- a/apps/codecs/libmusepack/huffsv46.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - Copyright (c) 2005, The Musepack Development Team - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of the The Musepack Development Team nor the - names of its contributors may be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/// \file huffsv46.c -/// Implementations of huffman decoding for streamversions < 7. - -#include "musepack.h" -#include "requant.h" -#include "huffman.h" - -#ifdef MPC_SUPPORT_SV456 - - -const HuffmanTyp mpc_table_SCFI_Bundle [ 8] = -{{2147483648u,1,7},{1073741824u,2,3},{939524096u,5,1},{805306368u,5,2},{738197504u,6,0},{671088640u,6,6},{536870912u,5,4},{0u,3,5},}; -const HuffmanTyp mpc_table_DSCF_Entropie [13] = -{{3758096384u,3,1},{3489660928u,4,3},{3355443200u,5,5},{3221225472u,5,-3},{2952790016u,4,-2},{2684354560u,4,4},{2147483648u,3,-1},{1610612736u,3,2},{1476395008u,5,-5},{1409286144u,6,6},{1342177280u,6,-6},{1073741824u,4,-4},{0u,2,0},}; -const HuffmanTyp mpc_table_Region_A [16] = -{{2147483648u,1,1},{2013265920u,5,3},{1946157056u,6,4},{1912602624u,7,7},{1895825408u,8,8},{1887436800u,9,9},{1883242496u,10,10},{1881145344u,11,11},{1880096768u,12,12},{1879572480u,13,13},{1879310336u,14,14},{1879048192u,14,15},{1744830464u,5,5},{1610612736u,5,6},{1073741824u,3,0},{0u,2,2},}; -const HuffmanTyp mpc_table_Region_B [ 8] = -{{2147483648u,1,1},{1073741824u,2,0},{536870912u,3,2},{268435456u,4,3},{134217728u,5,4},{67108864u,6,5},{33554432u,7,6},{0u,7,7},}; -const HuffmanTyp mpc_table_Region_C [ 4] = -{{2147483648u,1,0},{1073741824u,2,1},{536870912u,3,2},{0u,3,3},}; - -static const HuffmanTyp mpc_table_Entropie_1 [ 3] = -{{2147483648u,1,0},{1073741824u,2,-1},{0u,2,1},}; -static const HuffmanTyp mpc_table_Entropie_2 [ 5] = -{{3221225472u,2,0},{2684354560u,3,2},{2147483648u,3,-2},{1073741824u,2,1},{0u,2,-1},}; -static const HuffmanTyp mpc_table_Entropie_3 [ 7] = -{{3221225472u,2,0},{2684354560u,3,-2},{2415919104u,4,2},{2281701376u,5,-3},{2147483648u,5,3},{1073741824u,2,-1},{0u,2,1},}; -static const HuffmanTyp mpc_table_Entropie_4 [ 9] = -{{4026531840u,4,3},{3758096384u,4,-3},{3221225472u,3,1},{2684354560u,3,-1},{2147483648u,3,2},{1610612736u,3,-2},{1342177280u,4,-4},{1073741824u,4,4},{0u,2,0},}; -static const HuffmanTyp mpc_table_Entropie_5 [15] = -{{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},{2147483648u,3,0},{1610612736u,3,1},{1073741824u,3,-1},{805306368u,4,-4},{536870912u,4,5},{0u,3,2},}; -static const HuffmanTyp mpc_table_Entropie_6 [31] = -{{4160749568u,5,-4},{4026531840u,5,5},{3892314112u,5,-5},{3825205248u,6,10},{3758096384u,6,-10},{3623878656u,5,-6},{3489660928u,5,6},{3355443200u,5,7},{3221225472u,5,-7},{3087007744u,5,-8},{3019898880u,6,-11},{2986344448u,7,14},{2952790016u,7,-14},{2818572288u,5,8},{2751463424u,6,11},{2684354560u,6,-13},{2415919104u,4,0},{2147483648u,4,1},{1879048192u,4,-1},{1610612736u,4,3},{1342177280u,4,2},{1207959552u,5,-9},{1140850688u,6,12},{1073741824u,6,13},{805306368u,4,-3},{536870912u,4,-2},{402653184u,5,9},{335544320u,6,-12},{301989888u,7,15},{268435456u,7,-15},{0u,4,4},}; -static const HuffmanTyp mpc_table_Entropie_7 [63] = -{{4278190080u,8,28},{4261412864u,8,26},{4227858432u,7,-20},{4160749568u,6,8},{4093640704u,6,-8},{4026531840u,6,-9},{3959422976u,6,9},{3925868544u,7,20},{3892314112u,7,21},{3825205248u,6,-10},{3758096384u,6,-11},{3690987520u,6,10},{3623878656u,6,11},{3590324224u,7,-21},{3573547008u,8,29},{3556769792u,8,-29},{3489660928u,6,13},{3422552064u,6,-13},{3355443200u,6,-12},{3288334336u,6,12},{3254779904u,7,-22},{3221225472u,7,22},{3154116608u,6,14},{3087007744u,6,15},{3019898880u,6,-14},{2986344448u,7,-23},{2952790016u,7,23},{2885681152u,6,-15},{2818572288u,6,-16},{2751463424u,6,16},{2717908992u,7,27},{2684354560u,7,-27},{2617245696u,6,17},{2550136832u,6,-17},{2533359616u,8,-30},{2516582400u,8,30},{2483027968u,7,24},{2415919104u,6,-18},{2281701376u,5,-1},{2147483648u,5,1},{2113929216u,7,-24},{2080374784u,7,25},{2013265920u,6,18},{1879048192u,5,-3},{1744830464u,5,3},{1610612736u,5,5},{1476395008u,5,0},{1342177280u,5,-2},{1275068416u,6,19},{1207959552u,6,-19},{1073741824u,5,-5},{939524096u,5,-4},{805306368u,5,-7},{671088640u,5,2},{536870912u,5,4},{402653184u,5,7},{369098752u,7,-25},{335544320u,7,-26},{301989888u,7,-28},{285212672u,8,-31},{268435456u,8,31},{134217728u,5,6},{0u,5,-6},}; - -const HuffmanTyp* mpc_table_SampleHuff [18] = { - NULL,mpc_table_Entropie_1,mpc_table_Entropie_2,mpc_table_Entropie_3,mpc_table_Entropie_4,mpc_table_Entropie_5,mpc_table_Entropie_6,mpc_table_Entropie_7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL -}; - -#endif //#ifdef MPC_SUPPORT_SV456 diff --git a/apps/codecs/libmusepack/huffsv7.c b/apps/codecs/libmusepack/huffsv7.c deleted file mode 100644 index 9ca77ceaa5..0000000000 --- a/apps/codecs/libmusepack/huffsv7.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - Copyright (c) 2005, The Musepack Development Team - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of the The Musepack Development Team nor the - names of its contributors may be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/// \file huffsv7.c -/// Implementations of sv7 huffman decoding functions. - -#include "musepack.h" -#include "huffman.h" -#include "requant.h" - -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] ICONST_ATTR = -{{2147483648u,1,1},{1610612736u,3,2},{1073741824u,3,0},{0u,2,3},}; -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] 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] 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] 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] 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] 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] 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] 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},}, -}; - -const HuffmanTyp* mpc_table_HuffQ [2] [8] = { - {0,mpc_table_HuffQ1[0],mpc_table_HuffQ2[0],mpc_table_HuffQ3[0],mpc_table_HuffQ4[0],mpc_table_HuffQ5[0],mpc_table_HuffQ6[0],mpc_table_HuffQ7[0]}, - {0,mpc_table_HuffQ1[1],mpc_table_HuffQ2[1],mpc_table_HuffQ3[1],mpc_table_HuffQ4[1],mpc_table_HuffQ5[1],mpc_table_HuffQ6[1],mpc_table_HuffQ7[1]}, -}; diff --git a/apps/codecs/libmusepack/idtag.c b/apps/codecs/libmusepack/idtag.c deleted file mode 100644 index 8af5ce4d3b..0000000000 --- a/apps/codecs/libmusepack/idtag.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - Copyright (c) 2005, The Musepack Development Team - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of the The Musepack Development Team nor the - names of its contributors may be used to endorse or promote - products derived from this software without specific prior - written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/// \file idtag.c -/// Rudimentary id3tag handling routines, just enough to skip id3v2 tags, -/// if present. - -#include "musepack.h" -#include "internal.h" - -mpc_int32_t -JumpID3v2 (mpc_reader* r) { - unsigned char tmp [10]; - mpc_uint32_t Unsynchronisation; // ID3v2.4-flag - mpc_uint32_t ExtHeaderPresent; // ID3v2.4-flag - mpc_uint32_t ExperimentalFlag; // ID3v2.4-flag - mpc_uint32_t FooterPresent; // ID3v2.4-flag - mpc_int32_t ret; - - // seek to first byte of mpc data - if (!r->seek (r->data, 0)) { - return 0; - } - - r->read(r->data, tmp, sizeof(tmp)); - - // check id3-tag - if ( 0 != memcmp ( tmp, "ID3", 3) ) - return 0; - - // read flags - Unsynchronisation = tmp[5] & 0x80; - ExtHeaderPresent = tmp[5] & 0x40; - ExperimentalFlag = tmp[5] & 0x20; - FooterPresent = tmp[5] & 0x10; - - if ( tmp[5] & 0x0F ) - return -1; // not (yet???) allowed - if ( (tmp[6] | tmp[7] | tmp[8] | tmp[9]) & 0x80 ) - return -1; // not allowed - - // read HeaderSize (syncsave: 4 * $0xxxxxxx = 28 significant bits) - ret = tmp[6] << 21; - ret += tmp[7] << 14; - ret += tmp[8] << 7; - ret += tmp[9] ; - ret += 10; - if ( FooterPresent ) - ret += 10; - - return ret; -} diff --git a/apps/codecs/libmusepack/internal.h b/apps/codecs/libmusepack/internal.h index 45f2b41eea..d12c39c96b 100644 --- a/apps/codecs/libmusepack/internal.h +++ b/apps/codecs/libmusepack/internal.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, The Musepack Development Team + Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,43 +31,77 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /// \file internal.h /// Definitions and structures used only internally by the libmpcdec. +#ifndef _MPCDEC_INTERNAL_H_ +#define _MPCDEC_INTERNAL_H_ +#ifdef WIN32 +#pragma once +#endif +#ifdef __cplusplus +extern "C" { +#endif -#ifndef _mpcdec_internal_h -#define _mpcdec_internal_h +#include "mpcdec.h" +/* rockbox: not used, rockbox's swap32 is used now. +/// Big/little endian 32 bit byte swapping routine. +static mpc_inline +mpc_uint32_t mpc_swap32(mpc_uint32_t val) { + return (((val & 0xFF000000) >> 24) | ((val & 0x00FF0000) >> 8) + | ((val & 0x0000FF00) << 8) | ((val & 0x000000FF) << 24)); +} +*/ +typedef struct mpc_block_t { + char key[2]; // block key + mpc_uint64_t size; // block size minus the block header size +} mpc_block; + +#define MAX_FRAME_SIZE 4352 +#define DEMUX_BUFFER_SIZE (65536 - MAX_FRAME_SIZE) // need some space as sand box + +struct mpc_demux_t { + mpc_reader * r; + mpc_decoder * d; + mpc_streaminfo si; + + // buffer + mpc_uint8_t *buffer; + mpc_size_t bytes_total; + mpc_bits_reader bits_reader; + mpc_int32_t block_bits; /// bits remaining in current audio block + mpc_uint_t block_frames; /// frames remaining in current audio block + + // seeking + mpc_seek_t * seek_table; + mpc_uint_t seek_pwr; /// distance between 2 frames in seek_table = 2^seek_pwr + mpc_uint32_t seek_table_size; /// used size in seek_table + + // chapters + mpc_seek_t chap_pos; /// supposed position of the first chapter block + mpc_int_t chap_nb; /// number of chapters (-1 if unknown, 0 if no chapter) + mpc_chap_info * chap; /// chapters position and tag -enum { - MPC_DECODER_SYNTH_DELAY = 481 }; -/// Big/little endian 32 bit byte swapping routine. -/* Use our Rockbox (maybe) optimised swap routine instead */ -#define mpc_swap32(x) swap32(x) -#if 0 -static __inline -mpc_uint32_t mpc_swap32(mpc_uint32_t val) { - return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | - ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); +/** + * checks if a block key is valid + * @param key the two caracters key to check + * @return MPC_STATUS_INVALIDSV if the key is invalid, MPC_STATUS_OK else + */ +static mpc_inline mpc_status mpc_check_key(char * key) +{ + if (key[0] < 65 || key[0] > 90 || key[1] < 65 || key[1] > 90) + return MPC_STATUS_INVALIDSV; + return MPC_STATUS_OK; } -#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 -/// \return -1 on errors of any kind -mpc_int32_t JumpID3v2(mpc_reader* fp); /// helper functions used by multiple files mpc_uint32_t mpc_random_int(mpc_decoder *d); // in synth_filter.c -void mpc_decoder_initialisiere_quantisierungstabellen(mpc_decoder *d, double scale_factor); -void mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT* OutData); - -#endif // _mpcdec_internal_h +void mpc_decoder_init_quant(mpc_decoder *d, double scale_factor); +void mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT* OutData, mpc_int_t channels); +#ifdef __cplusplus +} +#endif +#endif diff --git a/apps/codecs/libmusepack/mainpage.h b/apps/codecs/libmusepack/mainpage.h deleted file mode 100644 index a51174aa3a..0000000000 --- a/apps/codecs/libmusepack/mainpage.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - \mainpage libmusepack documentation - - \section whats what is libmusepack - libmusepack is a library that decodes musepack compressed audio data. Musepack - is a free, high performance, high quality lossy audio compression codec. For - more information on musepack visit http://www.musepack.net. - - \section using using libmusepack - - Using libmusepack is very straightforward. There are typically four things you must - do to use libmusepack in your application. - - \subsection step1 step 1: implement an mpc_reader to provide raw data to the decoder library - The role of the mpc_reader is to provide raw mpc stream data to the mpc decoding library. - This data can come from a file, a network socket, or any other source you wish. - - See the documentation of - \link mpc_reader_t mpc_reader \endlink - for more information. - - \subsection step2 step2: read the streaminfo properties structure from the stream - This is a simple matter of calling the streaminfo_init() and streaminfo_read() functions, - supplying your mpc_reader as a source of raw data. This reads the stream properties header from the - mpc stream. This information will be used to prime the decoder for decoding in - the next step. - - \subsection step3 step 3: initialize an mpc_decoder with your mpc_reader source - This is just a matter of calling the mpc_decoder_setup() and mpc_decoder_initialize() - functions with your mpc_decoder, mpc_reader data source and streaminfo information. - - \subsection step4 step 4: iteratively read raw sample data from the mpc decoder - Once you've initialized the decoding library you just iteratively call the - mpc_decoder_decode routine until it indicates that the entire stream has been read. - - For a simple example of all of these steps see the sample application distributed with - libmusepack in src/sample.cpp. -*/ diff --git a/apps/codecs/libmusepack/minimax.h b/apps/codecs/libmusepack/minimax.h new file mode 100755 index 0000000000..1192626567 --- /dev/null +++ b/apps/codecs/libmusepack/minimax.h @@ -0,0 +1,57 @@ +/* + * Musepack audio compression + * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#pragma once + +# define clip(x,min,max) ( (x) < (min) ? (min) : (x) > (max) ? (max) : (x) ) + +#ifdef __cplusplus + +# define maxi(A,B) ( (A) >? (B) ) +# define mini(A,B) ( (A) ? (B) ) +# define mind(A,B) ( (A) ? (B) ) +# define minf(A,B) ( (A) (B) ? (A) : (B) ) +# define mini(A,B) ( (A) < (B) ? (A) : (B) ) +# define maxd(A,B) ( (A) > (B) ? (A) : (B) ) +# define mind(A,B) ( (A) < (B) ? (A) : (B) ) +# define maxf(A,B) ( (A) > (B) ? (A) : (B) ) +# define minf(A,B) ( (A) < (B) ? (A) : (B) ) + +#endif + +#ifdef __GNUC__ + +# define absi(A) abs (A) +# define absf(A) fabsf (A) +# define absd(A) fabs (A) + +#else + +# define absi(A) ( (A) >= 0 ? (A) : -(A) ) +# define absf(A) ( (A) >= 0.f ? (A) : -(A) ) +# define absd(A) ( (A) >= 0. ? (A) : -(A) ) + +#endif + diff --git a/apps/codecs/libmusepack/mpc_bits_reader.c b/apps/codecs/libmusepack/mpc_bits_reader.c new file mode 100755 index 0000000000..bc86cd1a72 --- /dev/null +++ b/apps/codecs/libmusepack/mpc_bits_reader.c @@ -0,0 +1,179 @@ +/* + Copyright (c) 2007-2009, The Musepack Development Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the The Musepack Development Team nor the + names of its contributors may be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "mpcdec.h" +#include "internal.h" +#include "huffman.h" +#include "mpc_bits_reader.h" + +const mpc_uint32_t Cnk[MAX_ENUM / 2][MAX_ENUM] ICONST_ATTR_MPC_LARGE_IRAM = +{ + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, + {0, 0, 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210, 231, 253, 276, 300, 325, 351, 378, 406, 435, 465}, + {0, 0, 0, 1, 4, 10, 20, 35, 56, 84, 120, 165, 220, 286, 364, 455, 560, 680, 816, 969, 1140, 1330, 1540, 1771, 2024, 2300, 2600, 2925, 3276, 3654, 4060, 4495}, + {0, 0, 0, 0, 1, 5, 15, 35, 70, 126, 210, 330, 495, 715, 1001, 1365, 1820, 2380, 3060, 3876, 4845, 5985, 7315, 8855, 10626, 12650, 14950, 17550, 20475, 23751, 27405, 31465}, + {0, 0, 0, 0, 0, 1, 6, 21, 56, 126, 252, 462, 792, 1287, 2002, 3003, 4368, 6188, 8568, 11628, 15504, 20349, 26334, 33649, 42504, 53130, 65780, 80730, 98280, 118755, 142506, 169911}, + {0, 0, 0, 0, 0, 0, 1, 7, 28, 84, 210, 462, 924, 1716, 3003, 5005, 8008, 12376, 18564, 27132, 38760, 54264, 74613, 100947, 134596, 177100, 230230, 296010, 376740, 475020, 593775, 736281}, + {0, 0, 0, 0, 0, 0, 0, 1, 8, 36, 120, 330, 792, 1716, 3432, 6435, 11440, 19448, 31824, 50388, 77520, 116280, 170544, 245157, 346104, 480700, 657800, 888030, 1184040, 1560780, 2035800, 2629575}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 45, 165, 495, 1287, 3003, 6435, 12870, 24310, 43758, 75582, 125970, 203490, 319770, 490314, 735471, 1081575, 1562275, 2220075, 3108105, 4292145, 5852925, 7888725}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 55, 220, 715, 2002, 5005, 11440, 24310, 48620, 92378, 167960, 293930, 497420, 817190, 1307504, 2042975, 3124550, 4686825, 6906900, 10015005, 14307150, 20160075}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 11, 66, 286, 1001, 3003, 8008, 19448, 43758, 92378, 184756, 352716, 646646, 1144066, 1961256, 3268760, 5311735, 8436285, 13123110, 20030010, 30045015, 44352165}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 12, 78, 364, 1365, 4368, 12376, 31824, 75582, 167960, 352716, 705432, 1352078, 2496144, 4457400, 7726160, 13037895, 21474180, 34597290, 54627300, 84672315}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 13, 91, 455, 1820, 6188, 18564, 50388, 125970, 293930, 646646, 1352078, 2704156, 5200300, 9657700, 17383860, 30421755, 51895935, 86493225, 141120525}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 14, 105, 560, 2380, 8568, 27132, 77520, 203490, 497420, 1144066, 2496144, 5200300, 10400600, 20058300, 37442160, 67863915, 119759850, 206253075}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 15, 120, 680, 3060, 11628, 38760, 116280, 319770, 817190, 1961256, 4457400, 9657700, 20058300, 40116600, 77558760, 145422675, 265182525}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 16, 136, 816, 3876, 15504, 54264, 170544, 490314, 1307504, 3268760, 7726160, 17383860, 37442160, 77558760, 155117520, 300540195}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 17, 153, 969, 4845, 20349, 74613, 245157, 735471, 2042975, 5311735, 13037895, 30421755, 67863915, 145422675, 300540195} +}; + +const mpc_uint8_t Cnk_len[MAX_ENUM / 2][MAX_ENUM] ICONST_ATTR_MPC_LARGE_IRAM = +{ + {0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}, + {0, 0, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9}, + {0, 0, 0, 2, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13}, + {0, 0, 0, 0, 3, 4, 6, 7, 7, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 15, 16}, + {0, 0, 0, 0, 0, 3, 5, 6, 7, 8, 9, 10, 11, 11, 12, 13, 13, 14, 14, 14, 15, 15, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18}, + {0, 0, 0, 0, 0, 0, 3, 5, 7, 8, 9, 10, 11, 12, 13, 13, 14, 15, 15, 16, 16, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20}, + {0, 0, 0, 0, 0, 0, 0, 3, 6, 7, 9, 10, 11, 12, 13, 14, 15, 15, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 21, 22, 22}, + {0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 8, 9, 11, 12, 13, 14, 15, 16, 17, 17, 18, 19, 19, 20, 21, 21, 22, 22, 23, 23, 23, 24}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 6, 8, 10, 11, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 21, 22, 23, 23, 24, 24, 25, 25}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 10, 12, 13, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 24, 25, 25, 26, 26}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 11, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 26, 27, 27}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 9, 11, 13, 15, 16, 17, 19, 20, 21, 22, 23, 24, 25, 25, 26, 27, 28, 28}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 10, 12, 14, 15, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 27, 28, 29}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 7, 10, 12, 14, 16, 17, 19, 20, 21, 23, 24, 25, 26, 27, 28, 28, 29}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8, 10, 12, 14, 16, 18, 19, 21, 22, 23, 25, 26, 27, 28, 29, 30}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 8, 10, 13, 15, 17, 18, 20, 21, 23, 24, 25, 27, 28, 29, 30} + +}; + +const mpc_uint32_t Cnk_lost[MAX_ENUM / 2][MAX_ENUM] ICONST_ATTR_MPC_LARGE_IRAM = +{ + {0, 0, 1, 0, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, + {0, 0, 1, 2, 6, 1, 11, 4, 28, 19, 9, 62, 50, 37, 23, 8, 120, 103, 85, 66, 46, 25, 3, 236, 212, 187, 161, 134, 106, 77, 47, 16}, + {0, 0, 0, 0, 6, 12, 29, 8, 44, 8, 91, 36, 226, 148, 57, 464, 344, 208, 55, 908, 718, 508, 277, 24, 1796, 1496, 1171, 820, 442, 36, 3697, 3232}, + {0, 0, 0, 0, 3, 1, 29, 58, 2, 46, 182, 17, 309, 23, 683, 228, 1716, 1036, 220, 3347, 2207, 877, 7529, 5758, 3734, 1434, 15218, 12293, 9017, 5363, 1303, 29576}, + {0, 0, 0, 0, 0, 2, 11, 8, 2, 4, 50, 232, 761, 46, 1093, 3824, 2004, 7816, 4756, 880, 12419, 6434, 31887, 23032, 12406, 65292, 50342, 32792, 12317, 119638, 92233, 60768}, + {0, 0, 0, 0, 0, 0, 1, 4, 44, 46, 50, 100, 332, 1093, 3187, 184, 4008, 14204, 5636, 26776, 11272, 56459, 30125, 127548, 85044, 31914, 228278, 147548, 49268, 454801, 312295, 142384}, + {0, 0, 0, 0, 0, 0, 0, 0, 28, 8, 182, 232, 332, 664, 1757, 4944, 13320, 944, 15148, 53552, 14792, 91600, 16987, 178184, 43588, 390776, 160546, 913112, 536372, 61352, 1564729, 828448}, + {0, 0, 0, 0, 0, 0, 0, 0, 7, 19, 91, 17, 761, 1093, 1757, 3514, 8458, 21778, 55490, 5102, 58654, 204518, 33974, 313105, 1015577, 534877, 1974229, 1086199, 4096463, 2535683, 499883, 6258916}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 9, 36, 309, 46, 3187, 4944, 8458, 16916, 38694, 94184, 230358, 26868, 231386, 789648, 54177, 1069754, 3701783, 1481708, 6762211, 2470066, 13394357, 5505632}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 62, 226, 23, 1093, 184, 13320, 21778, 38694, 77388, 171572, 401930, 953086, 135896, 925544, 3076873, 8340931, 3654106, 13524422, 3509417, 22756699, 2596624}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 50, 148, 683, 3824, 4008, 944, 55490, 94184, 171572, 343144, 745074, 1698160, 3931208, 662448, 3739321, 12080252, 32511574, 12481564, 49545413, 5193248}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 37, 57, 228, 2004, 14204, 15148, 5102, 230358, 401930, 745074, 1490148, 3188308, 7119516, 16170572, 3132677, 15212929, 47724503, 127314931, 42642616}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 23, 464, 1716, 7816, 5636, 53552, 58654, 26868, 953086, 1698160, 3188308, 6376616, 13496132, 29666704, 66353813, 14457878, 62182381, 189497312}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 344, 1036, 4756, 26776, 14792, 204518, 231386, 135896, 3931208, 7119516, 13496132, 26992264, 56658968, 123012781, 3252931, 65435312}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 208, 220, 880, 11272, 91600, 33974, 789648, 925544, 662448, 16170572, 29666704, 56658968, 113317936, 236330717, 508019104}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 103, 55, 3347, 12419, 56459, 16987, 313105, 54177, 3076873, 3739321, 3132677, 66353813, 123012781, 236330717} +}; + +static const mpc_uint8_t log2[32] ICONST_ATTR_MPC_LARGE_IRAM = +{ 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6}; + +static const mpc_uint8_t log2_lost[32] ICONST_ATTR_MPC_LARGE_IRAM = +{ 0, 1, 0, 3, 2, 1, 0, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 31}; + +mpc_int32_t mpc_bits_golomb_dec(mpc_bits_reader * r, const mpc_uint_t k) +{ + unsigned int l = 0; + unsigned int code = r->buff[0] & ((1 << r->count) - 1); + + while( code == 0 ) { + l += r->count; + r->buff++; + code = r->buff[0]; + r->count = 8; + } + + while( ((1 << (r->count - 1)) & code) == 0 ) { + l++; + r->count--; + } + r->count--; + + while( r->count < k ) { + r->buff++; + r->count += 8; + code = (code << 8) | r->buff[0]; + } + + r->count -= k; + + return (l << k) | ((code >> r->count) & ((1 << k) - 1)); +} + +mpc_uint32_t mpc_bits_log_dec(mpc_bits_reader * r, mpc_uint_t max) +{ + mpc_uint32_t value = 0; + if (log2[max - 1] > 1) + value = mpc_bits_read(r, log2[max - 1] - 1); + if (value >= log2_lost[max - 1]) + value = ((value << 1) | mpc_bits_read(r, 1)) - log2_lost[max - 1]; + return value; +} + +unsigned int mpc_bits_get_size(mpc_bits_reader * r, mpc_uint64_t * p_size) +{ + unsigned char tmp; + mpc_uint64_t size = 0; + unsigned int ret = 0; + + do { + tmp = mpc_bits_read(r, 8); + size = (size << 7) | (tmp & 0x7F); + ret++; + } while((tmp & 0x80)); + + *p_size = size; + return ret; +} + +int mpc_bits_get_block(mpc_bits_reader * r, mpc_block * p_block) +{ + int size = 2; + + p_block->size = 0; + p_block->key[0] = mpc_bits_read(r, 8); + p_block->key[1] = mpc_bits_read(r, 8); + + size += mpc_bits_get_size(r, &(p_block->size)); + + if (p_block->size >= (mpc_uint64_t)size) // check if the block size doesn't conflict with the header size + p_block->size -= (mpc_uint64_t)size; + + return size; +} + + + diff --git a/apps/codecs/libmusepack/mpc_bits_reader.h b/apps/codecs/libmusepack/mpc_bits_reader.h new file mode 100755 index 0000000000..1233720c74 --- /dev/null +++ b/apps/codecs/libmusepack/mpc_bits_reader.h @@ -0,0 +1,175 @@ +/* + Copyright (c) 2007-2009, The Musepack Development Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the The Musepack Development Team nor the + names of its contributors may be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define MAX_ENUM 32 + +MPC_API int mpc_bits_get_block(mpc_bits_reader * r, mpc_block * p_block); +mpc_int32_t mpc_bits_golomb_dec(mpc_bits_reader * r, const mpc_uint_t k); +MPC_API unsigned int mpc_bits_get_size(mpc_bits_reader * r, mpc_uint64_t * p_size); +mpc_uint32_t mpc_bits_log_dec(mpc_bits_reader * r, mpc_uint_t max); + +extern const mpc_uint32_t Cnk [MAX_ENUM / 2][MAX_ENUM]; +extern const mpc_uint8_t Cnk_len [MAX_ENUM / 2][MAX_ENUM]; +extern const mpc_uint32_t Cnk_lost[MAX_ENUM / 2][MAX_ENUM]; + +// can read up to 31 bits +static mpc_inline mpc_uint32_t mpc_bits_read(mpc_bits_reader * r, const unsigned int nb_bits) +{ + mpc_uint32_t ret; + + r->buff -= (int)(r->count - nb_bits) >> 3; + r->count = (r->count - nb_bits) & 0x07; + + ret = (r->buff[0] | (r->buff[-1] << 8)) >> r->count; + if (nb_bits > (16 - r->count)) { + ret |= (mpc_uint32_t)((r->buff[-2] << 16) | (r->buff[-3] << 24)) >> r->count; + if (nb_bits > 24 && r->count != 0) + ret |= r->buff[-4] << (32 - r->count); + } + + return ret & ((1 << nb_bits) - 1); +} + +#if defined(CPU_COLDFIRE) +/* rockbox: This is specific code to optimize demux performance on Coldfire + * CPUs. Coldfire CPUs are very sensible to RAM accesses. As the bitstream + * buffer does not fit into IRAM the read accesses to the uint8 buffer are very + * expensive in terms of CPU cycles. + * The following code uses two variables in IRAM. The variable last_code keeps + * the 4-byte value of buf[0]<<16 | buf[1]<<8 | buf[2]. As long as buf[0] will + * read from the same address the following code will avoid re-reading of the + * buffers. If buf[0] did advance to the next uint8-entry since the last call + * the following will only need to load 1 uint8-entry instead of 3. + */ +static mpc_inline mpc_uint16_t get_code_from_buffer(mpc_bits_reader *r) +{ + /* Buffer advanced by 1 entry since last call */ + if (r->buff == r->buffered_addr + 1) { + r->buffered_code = (r->buffered_code<<8) | r->buff[2]; + r->buffered_addr = r->buff; + } + /* Buffer must be fully re-read */ + else if (r->buff != r->buffered_addr) { + r->buffered_code = (r->buff[0] << 16) | (r->buff[1] << 8) | r->buff[2]; + r->buffered_addr = r->buff; + } + + return (mpc_uint16_t)((r->buffered_code >> r->count) & 0xFFFF); +} +#else +/* Use the decoder's default implementation. This is faster on non-Coldfire targets */ +#define get_code_from_buffer(r) (mpc_uint16_t)((((r->buff[0] << 16) | (r->buff[1] << 8) | r->buff[2]) >> r->count) & 0xFFFF); +#endif + +// basic huffman decoding routine +// works with maximum lengths up to 16 +static mpc_inline mpc_int32_t mpc_bits_huff_dec(mpc_bits_reader * r, const mpc_huffman *Table) +{ + const mpc_uint16_t code = get_code_from_buffer(r); + + while (code < Table->Code) Table++; + + r->buff -= (int)(r->count - Table->Length) >> 3; + r->count = (r->count - Table->Length) & 0x07; + + return Table->Value; +} + +static mpc_inline mpc_int32_t mpc_bits_can_dec(mpc_bits_reader * r, const mpc_can_data *can) +{ + const mpc_uint16_t code = get_code_from_buffer(r); + const mpc_huff_lut tmp = can->lut[code >> (16 - LUT_DEPTH)]; + const mpc_huffman * Table; + + if (tmp.Length != 0) { + r->buff -= (int)(r->count - tmp.Length) >> 3; + r->count = (r->count - tmp.Length) & 0x07; + return tmp.Value; + } + + Table = can->table + (unsigned char)tmp.Value; + while (code < Table->Code) Table++; + + r->buff -= (int)(r->count - Table->Length) >> 3; + r->count = (r->count - Table->Length) & 0x07; + + return can->sym[(Table->Value - (code >> (16 - Table->Length))) & 0xFF] ; +} + +// LUT-based huffman decoding routine +// works with maximum lengths up to 16 +static mpc_inline mpc_int32_t mpc_bits_huff_lut(mpc_bits_reader * r, const mpc_lut_data *lut) +{ + const mpc_uint16_t code = get_code_from_buffer(r); + const mpc_huff_lut tmp = lut->lut[code >> (16 - LUT_DEPTH)]; + const mpc_huffman * Table; + + if (tmp.Length != 0) { + r->buff -= (int)(r->count - tmp.Length) >> 3; + r->count = (r->count - tmp.Length) & 0x07; + return tmp.Value; + } + + Table = lut->table + (unsigned char)tmp.Value; + while (code < Table->Code) Table++; + + r->buff -= (int)(r->count - Table->Length) >> 3; + r->count = (r->count - Table->Length) & 0x07; + + return Table->Value; +} + +static mpc_inline mpc_uint32_t mpc_bits_enum_dec(mpc_bits_reader * r, mpc_uint_t k, mpc_uint_t n) +{ + mpc_uint32_t bits = 0; + mpc_uint32_t code; + const mpc_uint32_t * C = Cnk[k-1]; + + code = mpc_bits_read(r, Cnk_len[k-1][n-1] - 1); + + if (code >= Cnk_lost[k-1][n-1]) + code = ((code << 1) | mpc_bits_read(r, 1)) - Cnk_lost[k-1][n-1]; + + do { + n--; + if (code >= C[n]) { + bits |= 1 << n; + code -= C[n]; + C -= MAX_ENUM; + k--; + } + } while(k > 0); + + return bits; +} diff --git a/apps/codecs/libmusepack/mpc_config.h b/apps/codecs/libmusepack/mpc_config.h deleted file mode 100644 index 7bc922c4a7..0000000000 --- a/apps/codecs/libmusepack/mpc_config.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Copyright (C) 2008 by Andree Buschmann - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef _mpc_config_h_ -#define _mpc_config_h_ - -#include "config.h" - -/* choose fixed point or floating point */ -#define MPC_FIXED_POINT - -#ifndef MPC_FIXED_POINT -#error FIXME, mpc will not with floating point now -#endif - -/* choose speed vs. accuracy for MPC_FIXED_POINT - * speed-setting will increase decoding speed on ARM only (+20%), loss of accuracy - * equals about 5 dB SNR (15bit output precision) to not use the speed-optimization - * -> comment OPTIMIZE_FOR_SPEED here for desired target */ -#if defined(MPC_FIXED_POINT) - #if defined(CPU_COLDFIRE) - // do nothing - #elif defined(CPU_ARM) - //#define OPTIMIZE_FOR_SPEED - #else - #define OPTIMIZE_FOR_SPEED - #endif -#else - // do nothing -#endif - -#endif diff --git a/apps/codecs/libmusepack/mpc_decoder.c b/apps/codecs/libmusepack/mpc_decoder.c index d211980782..5a78c943a6 100644 --- a/apps/codecs/libmusepack/mpc_decoder.c +++ b/apps/codecs/libmusepack/mpc_decoder.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, The Musepack Development Team + Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,577 +31,217 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /// \file mpc_decoder.c /// Core decoding routines and logic. -#include "musepack.h" -#include "internal.h" -#include "requant.h" +#include +#include "mpcdec.h" +#include "minimax.h" +#include "decoder.h" #include "huffman.h" +#include "internal.h" +#include "mpcdec_math.h" +#include "requant.h" +#include "mpc_bits_reader.h" //SV7 tables -extern const HuffmanTyp* mpc_table_HuffQ [2] [8]; -extern const HuffmanTyp mpc_table_HuffHdr [10]; -extern const HuffmanTyp mpc_table_HuffSCFI [ 4]; -extern const HuffmanTyp mpc_table_HuffDSCF [16]; +extern const mpc_lut_data mpc_HuffQ [7] [2]; +extern const mpc_lut_data mpc_HuffHdr; +extern const mpc_huffman mpc_table_HuffSCFI [ 4]; +extern const mpc_lut_data mpc_HuffDSCF; +//SV8 tables +extern const mpc_can_data mpc_can_Bands; +extern const mpc_can_data mpc_can_SCFI[2]; +extern const mpc_can_data mpc_can_DSCF[2]; +extern const mpc_can_data mpc_can_Res [2]; +extern const mpc_can_data mpc_can_Q [8][2]; +extern const mpc_can_data mpc_can_Q1; +extern const mpc_can_data mpc_can_Q9up; -#ifdef MPC_SUPPORT_SV456 -//SV4/5/6 tables -extern const HuffmanTyp* mpc_table_SampleHuff [18]; -extern const HuffmanTyp mpc_table_SCFI_Bundle [ 8]; -extern const HuffmanTyp mpc_table_DSCF_Entropie [13]; -extern const HuffmanTyp mpc_table_Region_A [16]; -extern const HuffmanTyp mpc_table_Region_B [ 8]; -extern const HuffmanTyp mpc_table_Region_C [ 4]; +//Decoder globals (g_Y_L and g_Y_R do not fit into iram for all targets) +static mpc_decoder g_mpc_decoder IBSS_ATTR; +static MPC_SAMPLE_FORMAT g_Y_L[MPC_FRAME_LENGTH] IBSS_ATTR_MPC_LARGE_IRAM; +static MPC_SAMPLE_FORMAT g_Y_R[MPC_FRAME_LENGTH] IBSS_ATTR_MPC_LARGE_IRAM; -#endif +//SV7 globals (decoding results for bundled quantizers (3- and 5-step)) +static const mpc_int32_t g_sv7_idx30[] ICONST_ATTR = +{-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}; +static const mpc_int32_t g_sv7_idx31[] ICONST_ATTR = +{-1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1}; +static const mpc_int32_t g_sv7_idx32[] ICONST_ATTR = +{-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}; +static const mpc_int32_t g_sv7_idx50[] ICONST_ATTR = +{-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2}; +static const mpc_int32_t g_sv7_idx51[] ICONST_ATTR = +{-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2}; -#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 == 127 ? 127 : SCF + D) -#else -#define SCF_DIFF(SCF, D) SCF + D -#endif - -#define LOOKUP(x, e, q) mpc_decoder_make_huffman_lookup ( (q), sizeof(q), (x), (e) ) -#define Decode_DSCF() HUFFMAN_DECODE_FASTEST ( d, mpc_table_HuffDSCF, LUTDSCF, 6 ) -#define HUFFMAN_DECODE_FASTEST(d,a,b,c) mpc_decoder_huffman_decode_fastest ( (d), (a), (b), 32-(c) ) -#define HUFFMAN_DECODE_FASTERER(d,a,b,c) mpc_decoder_huffman_decode_fasterer ( (d), (a), (b), 32-(c) ) - -mpc_uint8_t LUT1_0 [1<< 6] IBSS_ATTR_MPC_LARGE_IRAM; -mpc_uint8_t LUT1_1 [1<< 9] IBSS_ATTR_MPC_LARGE_IRAM; // 576 Bytes -mpc_uint8_t LUT2_0 [1<< 7] IBSS_ATTR_MPC_LARGE_IRAM; -mpc_uint8_t LUT2_1 [1<<10] IBSS_ATTR_MPC_LARGE_IRAM; // 1152 Bytes -mpc_uint8_t LUT3_0 [1<< 4] IBSS_ATTR_MPC_LARGE_IRAM; -mpc_uint8_t LUT3_1 [1<< 5] IBSS_ATTR_MPC_LARGE_IRAM; // 48 Bytes -mpc_uint8_t LUT4_0 [1<< 4] IBSS_ATTR_MPC_LARGE_IRAM; -mpc_uint8_t LUT4_1 [1<< 5] IBSS_ATTR_MPC_LARGE_IRAM; // 48 Bytes -mpc_uint8_t LUT5_0 [1<< 6] IBSS_ATTR_MPC_LARGE_IRAM; -mpc_uint8_t LUT5_1 [1<< 8] IBSS_ATTR_MPC_LARGE_IRAM; // 320 Bytes -mpc_uint8_t LUT6_0 [1<< 7] IBSS_ATTR_MPC_LARGE_IRAM; -mpc_uint8_t LUT6_1 [1<< 7] IBSS_ATTR_MPC_LARGE_IRAM; // 256 Bytes -mpc_uint8_t LUT7_0 [1<< 8] IBSS_ATTR_MPC_LARGE_IRAM; -mpc_uint8_t LUT7_1 [1<< 8] IBSS_ATTR_MPC_LARGE_IRAM; // 512 Bytes -mpc_uint8_t LUTDSCF [1<< 6] IBSS_ATTR_MPC_LARGE_IRAM; // 64 Bytes = 2976 Bytes +//SV8 globals (decoding results for bundled quantizers (3- and 5-step)) +static const mpc_int8_t g_sv8_idx50[125] ICONST_ATTR = +{-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, + -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, + -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, + -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, + -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2}; +static const mpc_int8_t g_sv8_idx51[125] ICONST_ATTR = +{-2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2}; +static const mpc_int8_t g_sv8_idx52[125] ICONST_ATTR = +{-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2,-2, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}; +static const mpc_int8_t g_sv8_HuffQ2_var[125] ICONST_ATTR = +{ 6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 6, + 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, + 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, + 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 3, 2, 1, 2, 3, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, + 6, 5, 4, 5, 6, 5, 4, 3, 4, 5, 4, 3, 2, 3, 4, 5, 4, 3, 4, 5, 6, 5, 4, 5, 6}; //------------------------------------------------------------------------------ // types //------------------------------------------------------------------------------ enum - { - SEEK_PRE_DECODE = 33, // number of frames to be pre-decoded - MEMSIZE = MPC_DECODER_MEMSIZE, // overall buffer size - MEMSIZE2 = (MEMSIZE/2), // size of one buffer - MEMMASK = (MEMSIZE-1) - }; +{ + MEMSIZE = MPC_DECODER_MEMSIZE, // overall buffer size + MEMSIZE2 = (MEMSIZE/2), // size of one buffer + MEMMASK = (MEMSIZE-1) +}; //------------------------------------------------------------------------------ // forward declarations //------------------------------------------------------------------------------ -void mpc_decoder_read_bitstream_sv6(mpc_decoder *d); -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); +void mpc_decoder_read_bitstream_sv7(mpc_decoder * d, mpc_bits_reader * r); +void mpc_decoder_read_bitstream_sv8(mpc_decoder * d, mpc_bits_reader * r, + mpc_bool_t is_key_frame); +static void mpc_decoder_requantisierung(mpc_decoder *d); -mpc_uint32_t Seekbuffer[MPC_SEEK_BUFFER_SIZE]; -mpc_uint32_t Speicher[MPC_DECODER_MEMSIZE]; -MPC_SAMPLE_FORMAT Y_L[36][32] IBSS_ATTR_MPC_LARGE_IRAM; -MPC_SAMPLE_FORMAT Y_R[36][32] IBSS_ATTR_MPC_LARGE_IRAM; - -//------------------------------------------------------------------------------ -// utility functions -//------------------------------------------------------------------------------ -static mpc_int32_t f_read(mpc_decoder *d, void *ptr, size_t size) -{ - return d->r->read(d->r->data, ptr, size); -}; - -static mpc_bool_t f_seek(mpc_decoder *d, mpc_int32_t offset) -{ - return d->r->seek(d->r->data, offset); -}; - -static mpc_int32_t f_read_dword(mpc_decoder *d, mpc_uint32_t * ptr, mpc_uint32_t count) +/** + * set the scf indexes for seeking use + * needed only for sv7 seeking + * @param d + */ +void mpc_decoder_reset_scf(mpc_decoder * d, int value) { - count = f_read(d, ptr, count << 2) >> 2; - return count; + memset(d->SCF_Index_L, value, sizeof d->SCF_Index_L ); + memset(d->SCF_Index_R, value, sizeof d->SCF_Index_R ); } -//------------------------------------------------------------------------------ -// huffman & bitstream functions -//------------------------------------------------------------------------------ -static const mpc_uint32_t mask [33] ICONST_ATTR = { - 0x00000000, 0x00000001, 0x00000003, 0x00000007, - 0x0000000F, 0x0000001F, 0x0000003F, 0x0000007F, - 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF, - 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, - 0x0000FFFF, 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, - 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, - 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, - 0x0FFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, - 0xFFFFFFFF -}; - -/* F U N C T I O N S */ - -// resets bitstream decoding -static void -mpc_decoder_reset_bitstream_decode(mpc_decoder *d) +void mpc_decoder_setup(mpc_decoder *d) { - d->dword = 0; - d->next = 0; - d->pos = 0; - d->Zaehler = 0; - d->WordsRead = 0; + memset(d, 0, sizeof *d); + + d->__r1 = 1; + d->__r2 = 1; + d->Y_L = g_Y_L; + d->Y_R = g_Y_R; + + memset(d->Y_L, 0, sizeof(g_Y_L)); + memset(d->Y_R, 0, sizeof(g_Y_R)); + + mpc_decoder_init_quant(d, 1.0f); } -// reports the number of read bits -static mpc_uint32_t -mpc_decoder_bits_read(mpc_decoder *d) +void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si) { - return 32 * d->WordsRead + d->pos; + d->stream_version = si->stream_version; + d->ms = si->ms; + d->max_band = si->max_band; + d->channels = si->channels; + d->samples_to_skip = MPC_DECODER_SYNTH_DELAY + si->beg_silence; + + if (si->stream_version == 7 && si->is_true_gapless) + d->samples = ((si->samples + MPC_FRAME_LENGTH - 1) / MPC_FRAME_LENGTH) * MPC_FRAME_LENGTH; + else + d->samples = si->samples; } -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 inline mpc_uint32_t -mpc_decoder_bitstream_read(mpc_decoder *d, const mpc_uint32_t bits) +mpc_decoder * mpc_decoder_init(mpc_streaminfo *si) { - mpc_uint32_t out = d->dword; + mpc_decoder* p_tmp = &g_mpc_decoder; - d->pos += bits; - - if (d->pos < 32) { - out >>= (32 - d->pos); + if (p_tmp != 0) { + mpc_decoder_setup(p_tmp); + mpc_decoder_set_streaminfo(p_tmp, si); + huff_init_lut(LUT_DEPTH); } - else { - mpc_move_next(d); - if (d->pos) { - out <<= d->pos; - out |= d->dword >> (32 - d->pos); + + return p_tmp; +} + +void mpc_decoder_exit(mpc_decoder *d) +{ + (void)d; +} + +void mpc_decoder_decode_frame(mpc_decoder * d, + mpc_bits_reader * r, + mpc_frame_info * i) +{ + mpc_bits_reader r_sav = *r; + mpc_int64_t samples_left; + + samples_left = d->samples - d->decoded_samples + MPC_DECODER_SYNTH_DELAY; + + if (samples_left <= 0 && d->samples != 0) { + i->samples = 0; + i->bits = -1; + return; + } + + if (d->stream_version == 8) { + mpc_decoder_read_bitstream_sv8(d, r, i->is_key_frame); + } else { + mpc_decoder_read_bitstream_sv7(d, r); + } + + if (d->samples_to_skip < MPC_FRAME_LENGTH + MPC_DECODER_SYNTH_DELAY) { + mpc_decoder_requantisierung(d); + mpc_decoder_synthese_filter_float(d, i->buffer, d->channels); + } + + d->decoded_samples += MPC_FRAME_LENGTH; + + // reconstruct exact filelength + if (d->decoded_samples - d->samples < MPC_FRAME_LENGTH && d->stream_version == 7) { + int last_frame_samples = mpc_bits_read(r, 11); + if (d->decoded_samples == d->samples) { + if (last_frame_samples == 0) last_frame_samples = MPC_FRAME_LENGTH; + d->samples += last_frame_samples - MPC_FRAME_LENGTH; + samples_left += last_frame_samples - MPC_FRAME_LENGTH; } } - 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; -} - -#ifdef MPC_SUPPORT_SV456 -// decode SCFI-bundle (sv4,5,6) -static void -mpc_decoder_scfi_bundle_read( - mpc_decoder *d, - 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->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); - } - - *SCFI = Table->Value >> 1; - *DSCF = Table->Value & 1; -} - -// basic huffman decoding routine -// works with maximum lengths up to 14 -static mpc_int32_t -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->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; -} -#endif - -// faster huffman through previewing less bits -// works with maximum lengths up to 10 -static mpc_int32_t -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->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; -} - -// even faster huffman through previewing even less bits -// works with maximum lengths up to 5 -static mpc_int32_t -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->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) { - mpc_move_next(d); - } - - return Table->Value; -} - -/* full decode using lookup table */ -static inline mpc_int32_t -mpc_decoder_huffman_decode_fastest(mpc_decoder *d, const HuffmanTyp* Table, const mpc_uint8_t* tab, mpc_uint16_t unused_bits) -{ - // load preview and decode - mpc_uint32_t code = d->dword << d->pos; - - if (d->pos > unused_bits) { - code |= d->next >> (32 - d->pos); - } - - Table+=tab [(size_t)(code >> unused_bits) ]; - - // set the new position within bitstream without performing a dummy-read - if ((d->pos += Table->Length) >= 32) { - mpc_move_next(d); - } - - return Table->Value; -} - -static void -mpc_decoder_reset_v(mpc_decoder *d) -{ - memset(d->V_L, 0, sizeof d->V_L); - memset(d->V_R, 0, sizeof d->V_R); -} - -static void -mpc_decoder_reset_synthesis(mpc_decoder *d) -{ - mpc_decoder_reset_v(d); -} - -static void -mpc_decoder_reset_y(mpc_decoder *d) -{ - memset(d->Y_L, 0, sizeof Y_L); - memset(d->Y_R, 0, sizeof Y_R); -} - -static void -mpc_decoder_reset_globals(mpc_decoder *d) -{ - mpc_decoder_reset_bitstream_decode(d); - - d->DecodedFrames = 0; - d->MaxDecodedFrames = 0; - d->StreamVersion = 0; - d->MS_used = 0; - - memset(d->Y_L , 0, sizeof Y_L ); - memset(d->Y_R , 0, sizeof Y_R ); - memset(d->SCF_Index_L , 0, sizeof d->SCF_Index_L); - memset(d->SCF_Index_R , 0, sizeof d->SCF_Index_R); - 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); -#endif - memset(d->Q , 0, sizeof d->Q ); - memset(d->MS_Flag , 0, sizeof d->MS_Flag ); -} - -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) -{ - mpc_decoder_reset_bitstream_decode(d); - if (in_len > sizeof(Speicher)) in_len = sizeof(Speicher); - memcpy(d->Speicher, in_buffer, in_len); - d->dword = SWAP(d->Speicher[0]); - d->next = SWAP(d->Speicher[1]); - switch (d->StreamVersion) { -#ifdef MPC_SUPPORT_SV456 - case 0x04: - case 0x05: - case 0x06: - mpc_decoder_read_bitstream_sv6(d); - break; -#endif - case 0x07: - case 0x17: - mpc_decoder_read_bitstream_sv7(d, FALSE); - break; - default: - return (mpc_uint32_t)(-1); - } - mpc_decoder_requantisierung(d, d->Max_Band); - mpc_decoder_synthese_filter_float(d, out_buffer); - return mpc_decoder_bits_read(d); -} - -static mpc_uint32_t -mpc_decoder_decode_internal(mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer) -{ - mpc_uint32_t output_frame_length = MPC_FRAME_LENGTH; - - mpc_uint32_t FrameBitCnt = 0; - - // output the last part of the last frame here, if needed - if (d->last_block_samples > 0) { - output_frame_length = d->last_block_samples; - d->last_block_samples = 0; // it's going to be handled now, so reset it - if (!d->TrueGaplessPresent) { - mpc_decoder_reset_y(d); - } else { - mpc_decoder_bitstream_read(d, 20); - mpc_decoder_read_bitstream_sv7(d, FALSE); - mpc_decoder_requantisierung(d, d->Max_Band); - } - mpc_decoder_synthese_filter_float(d, buffer); - return output_frame_length; - } - - if (d->DecodedFrames >= d->OverallFrames) { - return (mpc_uint32_t)(-1); // end of file -> abort decoding - } - - if (d->DecodedFrames == 0) - { - d->SeekTable[0] = mpc_decoder_bits_read(d); - d->SeekTableCounter = 0; - } - - // read jump-info for validity check of frame - d->FwdJumpInfo = mpc_decoder_bitstream_read(d, 20); - - d->ActDecodePos = (d->Zaehler << 5) + d->pos; - - // decode data and check for validity of frame - FrameBitCnt = mpc_decoder_bits_read(d); - switch (d->StreamVersion) { -#ifdef MPC_SUPPORT_SV456 - case 0x04: - case 0x05: - case 0x06: - mpc_decoder_read_bitstream_sv6(d); - break; -#endif - case 0x07: - case 0x17: - 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++; - - /* update seek table */ - d->SeekTableCounter += d->FwdJumpInfo + 20; - if (0 == ((d->DecodedFrames) & (d->SeekTable_Mask))) - { - d->SeekTable[d->DecodedFrames>>d->SeekTable_Step] = d->SeekTableCounter; - d->MaxDecodedFrames = d->DecodedFrames; - d->SeekTableCounter = 0; - } - - // synthesize signal - mpc_decoder_requantisierung(d, d->Max_Band); - - mpc_decoder_synthese_filter_float(d, buffer); - - // cut off first MPC_DECODER_SYNTH_DELAY zero-samples - if (d->DecodedFrames == d->OverallFrames && d->StreamVersion >= 6) { - // reconstruct exact filelength - mpc_int32_t mod_block = mpc_decoder_bitstream_read(d, 11); - mpc_int32_t FilterDecay; - - if (mod_block == 0) { - // Encoder bugfix - mod_block = 1152; - } - FilterDecay = (mod_block + MPC_DECODER_SYNTH_DELAY) % MPC_FRAME_LENGTH; - - // additional FilterDecay samples are needed for decay of synthesis filter - if (MPC_DECODER_SYNTH_DELAY + mod_block >= MPC_FRAME_LENGTH) { - // this variable will be checked for at the top of the function - d->last_block_samples = FilterDecay; - } - else { // there are only FilterDecay samples needed for this frame - output_frame_length = FilterDecay; - } - } + i->samples = samples_left > MPC_FRAME_LENGTH ? MPC_FRAME_LENGTH : samples_left < 0 ? 0 : (mpc_uint32_t) samples_left; + i->bits = (mpc_uint32_t) (((r->buff - r_sav.buff) << 3) + r_sav.count - r->count); if (d->samples_to_skip) { - if (output_frame_length < d->samples_to_skip) { - d->samples_to_skip -= output_frame_length; - output_frame_length = 0; - } - else { - output_frame_length -= d->samples_to_skip; - memmove( - buffer, - buffer + d->samples_to_skip, - output_frame_length * sizeof (MPC_SAMPLE_FORMAT)); - memmove( - buffer + MPC_FRAME_LENGTH, - buffer + MPC_FRAME_LENGTH + d->samples_to_skip, - output_frame_length * sizeof (MPC_SAMPLE_FORMAT)); + if (i->samples <= d->samples_to_skip) { + d->samples_to_skip -= i->samples; + i->samples = 0; + } else { + i->samples -= d->samples_to_skip; + + /* move valid samples to beginning for channel 0. noninterleaved! */ + memmove(i->buffer, + i->buffer + d->samples_to_skip, + i->samples * sizeof(MPC_SAMPLE_FORMAT)); + /* move valid samples to beginning for channel 1. noninterleaved! */ + memmove(i->buffer + MPC_FRAME_LENGTH, + i->buffer + MPC_FRAME_LENGTH + d->samples_to_skip, + i->samples * sizeof(MPC_SAMPLE_FORMAT)); + d->samples_to_skip = 0; } } - - return output_frame_length; -} - -mpc_uint32_t mpc_decoder_decode( - mpc_decoder *d, - MPC_SAMPLE_FORMAT *buffer, - mpc_uint32_t *vbr_update_acc, - mpc_uint32_t *vbr_update_bits) -{ - for(;;) - { - mpc_uint32_t RING = d->Zaehler; - mpc_int32_t vbr_ring = (RING << 5) + d->pos; - - mpc_uint32_t valid_samples = mpc_decoder_decode_internal(d, buffer); - - if (valid_samples == (mpc_uint32_t)(-1) ) { - return 0; - } - - /**************** ERROR CONCEALMENT *****************/ - if (d->FrameWasValid == 0 ) { - // error occurred in bitstream - return (mpc_uint32_t)(-1); - } - else { - if (vbr_update_acc && vbr_update_bits) { - (*vbr_update_acc) ++; - vbr_ring = (d->Zaehler << 5) + d->pos - vbr_ring; - if (vbr_ring < 0) { - vbr_ring += 524288; - } - (*vbr_update_bits) += vbr_ring; - } - - } - mpc_decoder_update_buffer(d); - - if (valid_samples > 0) { - return valid_samples; - } - } } void -mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band) +mpc_decoder_requantisierung(mpc_decoder *d) { mpc_int32_t Band; mpc_int32_t n; @@ -613,6 +253,7 @@ mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band) MPC_SAMPLE_FORMAT* YR; mpc_int16_t* L; mpc_int16_t* R; + const mpc_int32_t Last_Band = d->max_band; #ifdef MPC_FIXED_POINT #if MPC_FIXED_POINT_FRACTPART == 14 @@ -629,42 +270,42 @@ mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band) #endif // requantization and scaling of subband-samples for ( Band = 0; Band <= Last_Band; Band++ ) { // setting pointers - YL = d->Y_L[0] + Band; - YR = d->Y_R[0] + Band; + YL = d->Y_L + Band; + YR = d->Y_R + Band; L = d->Q[Band].L; R = d->Q[Band].R; /************************** MS-coded **************************/ if ( d->MS_Flag [Band] ) { if ( d->Res_L [Band] ) { if ( d->Res_R [Band] ) { // M!=0, S!=0 - facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]); - facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]); + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][0] & 0xFF); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][0] & 0xFF); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); *YR = templ - tempr; } - facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]); - facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]); + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][1] & 0xFF); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][1] & 0xFF); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); *YR = templ - tempr; } - facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]); - facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]); + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][2] & 0xFF); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][2] & 0xFF); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); *YR = templ - tempr; } } else { // M!=0, S==0 - facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]); + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][0] & 0xFF); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); } - facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]); + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][1] & 0xFF); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); } - facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]); + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][2] & 0xFF); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); } @@ -672,15 +313,15 @@ mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band) } else { if (d->Res_R[Band]) // M==0, S!=0 { - facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][0] & 0xFF); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); } - facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][1] & 0xFF); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); } - facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][2] & 0xFF); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); } @@ -695,36 +336,36 @@ mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band) else { if ( d->Res_L [Band] ) { if ( d->Res_R [Band] ) { // L!=0, R!=0 - facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]); - facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]); + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][0] & 0xFF); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][0] & 0xFF); for (n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } - facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]); - facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]); + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][1] & 0xFF); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][1] & 0xFF); for (; n < 24; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } - facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]); - facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]); + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][2] & 0xFF); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][2] & 0xFF); for (; n < 36; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } } else { // L!=0, R==0 - facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]); + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][0] & 0xFF); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = 0; } - facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]); + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][1] & 0xFF); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = 0; } - facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]); + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][2] & 0xFF); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = 0; @@ -733,17 +374,17 @@ mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band) } else { if ( d->Res_R [Band] ) { // L==0, R!=0 - facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][0] & 0xFF); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YL = 0; *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } - facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][1] & 0xFF); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YL = 0; *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } - facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][2] & 0xFF); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YL = 0; *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); @@ -758,1040 +399,324 @@ mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band) } } -#ifdef MPC_SUPPORT_SV456 -static const unsigned char Q_res[32][16] ICONST_ATTR = { -{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, -{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, -{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, -{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, -{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, -{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, -{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, -{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, -{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, -{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, -{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, -{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, -{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, -{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, -{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, -{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, -{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, -{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, -{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, -{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, -{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, -{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, -{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, -{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, -{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, -{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, -{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, -{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, -{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, -{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, -{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, -{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, -}; - -/****************************************** SV 6 ******************************************/ -void -mpc_decoder_read_bitstream_sv6(mpc_decoder *d) +void mpc_decoder_read_bitstream_sv7(mpc_decoder * d, mpc_bits_reader * r) { - mpc_int32_t n,k; - mpc_int32_t Max_used_Band=0; - const HuffmanTyp *Table; - const HuffmanTyp *x1; - const HuffmanTyp *x2; - 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; - ResR = d->Res_R; - for (n=0; n <= d->Max_Band; ++n, ++ResL, ++ResR) - { - if (n<11) Table = mpc_table_Region_A; - else if (n>=11 && n<=22) Table = mpc_table_Region_B; - else /*if (n>=23)*/ Table = mpc_table_Region_C; - - *ResL = Q_res[n][mpc_decoder_huffman_decode(d, Table)]; - if (d->MS_used) { - d->MS_Flag[n] = mpc_decoder_bitstream_read(d, 1); - } - *ResR = Q_res[n][mpc_decoder_huffman_decode(d, Table)]; - - // only perform the following procedure up to the maximum non-zero subband - if (*ResL || *ResR) Max_used_Band = n; - } - - /************************* SCFI-Bundle *****************************/ - ResL = d->Res_L; - ResR = d->Res_R; - for (n=0; n<=Max_used_Band; ++n, ++ResL, ++ResR) { - if (*ResL) mpc_decoder_scfi_bundle_read(d, mpc_table_SCFI_Bundle, &(d->SCFI_L[n]), &(d->DSCF_Flag_L[n])); - if (*ResR) mpc_decoder_scfi_bundle_read(d, mpc_table_SCFI_Bundle, &(d->SCFI_R[n]), &(d->DSCF_Flag_R[n])); - } - - /***************************** SCFI ********************************/ - ResL = d->Res_L; - ResR = d->Res_R; - L = d->SCF_Index_L[0]; - R = d->SCF_Index_R[0]; - for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR, L+=3, R+=3) - { - if (*ResL) - { - /*********** DSCF ************/ - if (d->DSCF_Flag_L[n]==1) - { - switch (d->SCFI_L[n]) - { - case 3: - L[0] = L[2] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - L[1] = L[0]; - L[2] = L[1]; - break; - case 1: - L[0] = L[2] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - L[1] = L[0] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - L[2] = L[1]; - break; - case 2: - L[0] = L[2] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - L[1] = L[0]; - L[2] = L[1] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - break; - case 0: - L[0] = L[2] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - L[1] = L[0] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - L[2] = L[1] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - break; - default: - return; - break; - } - } - /************ SCF ************/ - else - { - switch (d->SCFI_L[n]) - { - case 3: - L[0] = mpc_decoder_bitstream_read(d, 6); - L[1] = L[0]; - L[2] = L[1]; - break; - case 1: - L[0] = mpc_decoder_bitstream_read(d, 6); - L[1] = mpc_decoder_bitstream_read(d, 6); - L[2] = L[1]; - break; - case 2: - L[0] = mpc_decoder_bitstream_read(d, 6); - L[1] = L[0]; - L[2] = mpc_decoder_bitstream_read(d, 6); - break; - case 0: - L[0] = mpc_decoder_bitstream_read(d, 6); - L[1] = mpc_decoder_bitstream_read(d, 6); - L[2] = mpc_decoder_bitstream_read(d, 6); - break; - default: - return; - break; - } - } - } - if (*ResR) - { - /*********** DSCF ************/ - if (d->DSCF_Flag_R[n]==1) - { - switch (d->SCFI_R[n]) - { - case 3: - R[0] = R[2] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - R[1] = R[0]; - R[2] = R[1]; - break; - case 1: - R[0] = R[2] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - R[1] = R[0] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - R[2] = R[1]; - break; - case 2: - R[0] = R[2] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - R[1] = R[0]; - R[2] = R[1] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - break; - case 0: - R[0] = R[2] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - R[1] = R[0] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - R[2] = R[1] + mpc_decoder_huffman_decode_fast(d, mpc_table_DSCF_Entropie); - break; - default: - return; - break; - } - } - /************ SCF ************/ - else - { - switch (d->SCFI_R[n]) - { - case 3: - R[0] = mpc_decoder_bitstream_read(d, 6); - R[1] = R[0]; - R[2] = R[1]; - break; - case 1: - R[0] = mpc_decoder_bitstream_read(d, 6); - R[1] = mpc_decoder_bitstream_read(d, 6); - R[2] = R[1]; - break; - case 2: - R[0] = mpc_decoder_bitstream_read(d, 6); - R[1] = R[0]; - R[2] = mpc_decoder_bitstream_read(d, 6); - break; - case 0: - R[0] = mpc_decoder_bitstream_read(d, 6); - R[1] = mpc_decoder_bitstream_read(d, 6); - R[2] = mpc_decoder_bitstream_read(d, 6); - break; - default: - return; - break; - } - } - } - } - - /**************************** Samples ****************************/ - ResL = d->Res_L; - ResR = d->Res_R; - for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR) - { - // setting pointers - x1 = mpc_table_SampleHuff[*ResL]; - x2 = mpc_table_SampleHuff[*ResR]; - QL = d->Q[n].L; - QR = d->Q[n].R; - - if (x1!=NULL || x2!=NULL) - for (k=0; k<36; ++k) - { - 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) *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_bool_t fastSeeking) -{ - mpc_int32_t n,k; - mpc_int32_t Max_used_Band=0; - const HuffmanTyp *Table; - mpc_int32_t idx; - mpc_int8_t *L ,*R; - mpc_int16_t *LQ ,*RQ; - mpc_int8_t *ResL,*ResR; - mpc_uint32_t tmp; - mpc_uint8_t *LUT; - mpc_uint8_t max_length; + mpc_int32_t n, idx, Max_used_Band = 0; /***************************** Header *****************************/ - ResL = d->Res_L; - ResR = d->Res_R; // first subband - *ResL = mpc_decoder_bitstream_read(d, 4); - *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; + d->Res_L[0] = mpc_bits_read(r, 4); + d->Res_R[0] = mpc_bits_read(r, 4); + if (!(d->Res_L[0] == 0 && d->Res_R[0] == 0)) { + if (d->ms) + d->MS_Flag[0] = mpc_bits_read(r, 1); + Max_used_Band = 1; } // consecutive subbands - ++ResL; ++ResR; // increase pointers - for (n=1; n <= d->Max_Band; ++n, ++ResL, ++ResR) - { - idx = mpc_decoder_huffman_decode_fast(d, mpc_table_HuffHdr); - *ResL = (idx!=4) ? *(ResL-1) + idx : (int) mpc_decoder_bitstream_read(d, 4); + for ( n = 1; n <= d->max_band; n++ ) { + idx = mpc_bits_huff_lut(r, & mpc_HuffHdr); + d->Res_L[n] = (idx!=4) ? d->Res_L[n - 1] + idx : (int) mpc_bits_read(r, 4); - idx = mpc_decoder_huffman_decode_fast(d, mpc_table_HuffHdr); - *ResR = (idx!=4) ? *(ResR-1) + idx : (int) mpc_decoder_bitstream_read(d, 4); + idx = mpc_bits_huff_lut(r, & mpc_HuffHdr); + d->Res_R[n] = (idx!=4) ? d->Res_R[n - 1] + idx : (int) mpc_bits_read(r, 4); - if (d->MS_used && !(*ResL==0 && *ResR==0)) { - d->MS_Flag[n] = mpc_decoder_bitstream_read(d, 1); - } - - // 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; + if (!(d->Res_L[n] == 0 && d->Res_R[n] == 0)) { + if (d->ms) + d->MS_Flag[n] = mpc_bits_read(r, 1); + Max_used_Band = n + 1; } } + /****************************** SCFI ******************************/ - L = d->SCFI_L; - R = d->SCFI_R; - ResL = d->Res_L; - ResR = d->Res_R; - for (n=0; n <= Max_used_Band; ++n, ++L, ++R, ++ResL, ++ResR) { - if (*ResL) *L = mpc_decoder_huffman_decode_faster(d, mpc_table_HuffSCFI); - if (*ResR) *R = mpc_decoder_huffman_decode_faster(d, mpc_table_HuffSCFI); + for ( n = 0; n < Max_used_Band; n++ ) { + if (d->Res_L[n]) + d->SCFI_L[n] = mpc_bits_huff_dec(r, mpc_table_HuffSCFI); + if (d->Res_R[n]) + d->SCFI_R[n] = mpc_bits_huff_dec(r, mpc_table_HuffSCFI); } /**************************** SCF/DSCF ****************************/ - ResL = d->Res_L; - ResR = d->Res_R; - L = d->SCF_Index_L[0]; - R = d->SCF_Index_R[0]; - for (n=0; n<=Max_used_Band; ++n, ++ResL, ++ResR, L+=3, R+=3) { - if (*ResL) - { - switch (d->SCFI_L[n]) - { - case 1: - 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 = 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 = Decode_DSCF (); - L[0] = (idx!=8) ? SCF_DIFF(L[2], idx) : (int) mpc_decoder_bitstream_read(d, 6); - L[1] = L[0]; - idx = Decode_DSCF (); - L[2] = (idx!=8) ? SCF_DIFF(L[1], idx) : (int) mpc_decoder_bitstream_read(d, 6); - break; - case 0: - 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; + for ( n = 0; n < Max_used_Band; n++ ) { + mpc_int32_t * SCF = d->SCF_Index_L[n]; + mpc_uint32_t Res = d->Res_L[n], SCFI = d->SCFI_L[n]; + do { + if (Res) { + switch (SCFI) { + case 1: + idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); + SCF[0] = (idx!=8) ? SCF[2] + idx : (int) mpc_bits_read(r, 6); + idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); + SCF[1] = (idx!=8) ? SCF[0] + idx : (int) mpc_bits_read(r, 6); + SCF[2] = SCF[1]; + break; + case 3: + idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); + SCF[0] = (idx!=8) ? SCF[2] + idx : (int) mpc_bits_read(r, 6); + SCF[1] = SCF[0]; + SCF[2] = SCF[1]; + break; + case 2: + idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); + SCF[0] = (idx!=8) ? SCF[2] + idx : (int) mpc_bits_read(r, 6); + SCF[1] = SCF[0]; + idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); + SCF[2] = (idx!=8) ? SCF[1] + idx : (int) mpc_bits_read(r, 6); + break; + case 0: + idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); + SCF[0] = (idx!=8) ? SCF[2] + idx : (int) mpc_bits_read(r, 6); + idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); + SCF[1] = (idx!=8) ? SCF[0] + idx : (int) mpc_bits_read(r, 6); + idx = mpc_bits_huff_lut(r, & mpc_HuffDSCF); + SCF[2] = (idx!=8) ? SCF[1] + idx : (int) mpc_bits_read(r, 6); + break; + default: + return; + } + if (SCF[0] > 1024) + SCF[0] = 0x8080; + if (SCF[1] > 1024) + SCF[1] = 0x8080; + if (SCF[2] > 1024) + SCF[2] = 0x8080; } - } - if (*ResR) - { - switch (d->SCFI_R[n]) - { - case 1: - 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 = 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 = Decode_DSCF (); - R[0] = (idx!=8) ? SCF_DIFF(R[2], idx) : (int) mpc_decoder_bitstream_read(d, 6); - R[1] = R[0]; - idx = Decode_DSCF (); - R[2] = (idx!=8) ? SCF_DIFF(R[1], idx) : (int) mpc_decoder_bitstream_read(d, 6); - break; - case 0: - 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; - } - } + Res = d->Res_R[n]; + SCFI = d->SCFI_R[n]; + } while ( SCF == d->SCF_Index_L[n] && (SCF = d->SCF_Index_R[n])); } - if (fastSeeking) - return; +// if (d->seeking == TRUE) +// return; /***************************** Samples ****************************/ - ResL = d->Res_L; - ResR = d->Res_R; - LQ = d->Q[0].L; - RQ = d->Q[0].R; - for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR, LQ+=36, RQ+=36) - { - /************** 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: - LQ += 36; - break; - case -1: - for (k=0; k<36; k++ ) { - tmp = mpc_random_int(d); - *LQ++ = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510; + for ( n = 0; n < Max_used_Band; n++ ) { + mpc_int16_t *q = d->Q[n].L, Res = d->Res_L[n]; + do { + mpc_int32_t k; + const mpc_lut_data *Table; + switch (Res) { + 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: case 0: + break; + case -1: + for (k=0; k<36; k++ ) { + mpc_uint32_t tmp = mpc_random_int(d); + q[k] = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510; + } + break; + case 1: + Table = & mpc_HuffQ[0][mpc_bits_read(r, 1)]; + for ( k = 0; k < 36; k += 3) { + idx = mpc_bits_huff_lut(r, Table); + q[k] = g_sv7_idx30[idx]; + q[k + 1] = g_sv7_idx31[idx]; + q[k + 2] = g_sv7_idx32[idx]; + } + break; + case 2: + Table = & mpc_HuffQ[1][mpc_bits_read(r, 1)]; + for ( k = 0; k < 36; k += 2) { + idx = mpc_bits_huff_lut(r, Table); + q[k] = g_sv7_idx50[idx]; + q[k + 1] = g_sv7_idx51[idx]; + } + break; + case 3: + case 4: + case 5: + case 6: + case 7: + Table = & mpc_HuffQ[Res - 1][mpc_bits_read(r, 1)]; + for ( k = 0; k < 36; k++ ) + q[k] = mpc_bits_huff_lut(r, Table); + break; + case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: + for ( k = 0; k < 36; k++ ) + q[k] = (mpc_int32_t)mpc_bits_read(r, Res_bit[Res]) - Dc[Res]; + break; + default: + return; } - break; - case 0: - LQ += 36;// increase pointer - break; - case 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 = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); - *LQ++ = idx30[idx]; - *LQ++ = idx31[idx]; - *LQ++ = idx32[idx]; - } - break; - case 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 = 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: - if (mpc_decoder_bitstream_read(d, 1)) { - Table = mpc_table_HuffQ[1][4]; - LUT = LUT4_1; - max_length = 5; - } else { - Table = mpc_table_HuffQ[0][4]; - LUT = LUT4_0; - max_length = 4; - } - for (k=0; k<36; ++k) - *LQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); - break; - case 5: - if (mpc_decoder_bitstream_read(d, 1)) { - Table = mpc_table_HuffQ[1][5]; - LUT = LUT5_1; - max_length = 8; - } else { - Table = mpc_table_HuffQ[0][5]; - LUT = LUT5_0; - max_length = 6; - } - for (k=0; k<36; ++k) - *LQ++ = 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: - if (mpc_decoder_bitstream_read(d, 1)) { - Table = mpc_table_HuffQ[1][7]; - LUT = LUT7_1; - max_length = 8; - for (k=0; k<36; ++k) - *LQ++ = HUFFMAN_DECODE_FASTERER ( d, Table, LUT, max_length ); - } else { - Table = mpc_table_HuffQ[0][7]; - LUT = LUT7_0; - max_length = 8; - for (k=0; k<36; ++k) - *LQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); - } - break; - case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: - tmp = Dc[*ResL]; - for (k=0; k<36; ++k) - *LQ++ = (mpc_int16_t)mpc_decoder_bitstream_read(d, Res_bit[*ResL]) - tmp; - break; - default: - return; - } - /************** rechts **************/ - switch (*ResR) - { - 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: - RQ += 36; - break; - case -1: - for (k=0; k<36; k++ ) { - tmp = mpc_random_int(d); - *RQ++ = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510; - } - break; - case 0: - RQ += 36;// increase pointer - break; - case 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 = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); - *RQ++ = idx30[idx]; - *RQ++ = idx31[idx]; - *RQ++ = idx32[idx]; - } - break; - case 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 = 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: - if (mpc_decoder_bitstream_read(d, 1)) { - Table = mpc_table_HuffQ[1][4]; - LUT = LUT4_1; - max_length = 5; - } else { - Table = mpc_table_HuffQ[0][4]; - LUT = LUT4_0; - max_length = 4; - } - for (k=0; k<36; ++k) - *RQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); - break; - case 5: - if (mpc_decoder_bitstream_read(d, 1)) { - Table = mpc_table_HuffQ[1][5]; - LUT = LUT5_1; - max_length = 8; - } else { - Table = mpc_table_HuffQ[0][5]; - LUT = LUT5_0; - max_length = 6; - } - for (k=0; k<36; ++k) - *RQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); - break; - case 6: - if (mpc_decoder_bitstream_read(d, 1)) { - Table = mpc_table_HuffQ[1][6]; - LUT = LUT6_1; - max_length = 7; - for (k=0; k<36; ++k) - *RQ++ = HUFFMAN_DECODE_FASTERER ( d, Table, LUT, max_length ); - } else { - Table = mpc_table_HuffQ[0][6]; - LUT = LUT6_0; - max_length = 7; - for (k=0; k<36; ++k) - *RQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); - } - break; - case 7: - if (mpc_decoder_bitstream_read(d, 1)) { - Table = mpc_table_HuffQ[1][7]; - LUT = LUT7_1; - max_length = 8; - for (k=0; k<36; ++k) - *RQ++ = HUFFMAN_DECODE_FASTERER ( d, Table, LUT, max_length ); - } else { - Table = mpc_table_HuffQ[0][7]; - LUT = LUT7_0; - max_length = 8; - for (k=0; k<36; ++k) - *RQ++ = HUFFMAN_DECODE_FASTEST ( d, Table, LUT, max_length ); - } - break; - case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: - tmp = Dc[*ResR]; - for (k=0; k<36; ++k) - *RQ++ = (mpc_int16_t)mpc_decoder_bitstream_read(d, Res_bit[*ResR]) - tmp; - break; - default: - return; - } + + Res = d->Res_R[n]; + } while (q == d->Q[n].L && (q = d->Q[n].R)); } } -void mpc_decoder_setup(mpc_decoder *d, mpc_reader *r) +void mpc_decoder_read_bitstream_sv8(mpc_decoder * d, mpc_bits_reader * r, mpc_bool_t is_key_frame) { - d->r = r; + mpc_int32_t n, Max_used_Band; + const mpc_can_data * Table, * Tables[2]; - d->MPCHeaderPos = 0; - d->StreamVersion = 0; - d->MS_used = 0; - d->FwdJumpInfo = 0; - d->ActDecodePos = 0; - d->FrameWasValid = 0; - d->OverallFrames = 0; - d->DecodedFrames = 0; - d->MaxDecodedFrames = 0; - d->TrueGaplessPresent = 0; - d->last_block_samples = 0; - d->WordsRead = 0; - d->Max_Band = 0; - d->SampleRate = 0; - d->__r1 = 1; - d->__r2 = 1; - - d->dword = 0; - d->pos = 0; - d->Zaehler = 0; - d->Ring = 0; - d->WordsRead = 0; - d->Max_Band = 0; - d->SeekTable_Step = 0; - d->SeekTable_Mask = 0; - d->SeekTableCounter = 0; - - mpc_decoder_initialisiere_quantisierungstabellen(d, 1.0f); - - 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->SeekTable = Seekbuffer; - d->Speicher = Speicher; - d->Y_L = Y_L; - d->Y_R = Y_R; - - #if defined(CPU_COLDFIRE) - coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE); - #endif -} - -static void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si) -{ - mpc_uint32_t seekTableSize; - - mpc_decoder_reset_synthesis(d); - mpc_decoder_reset_globals(d); - - d->StreamVersion = si->stream_version; - d->MS_used = si->ms; - d->Max_Band = si->max_band; - d->OverallFrames = si->frames; - d->MPCHeaderPos = si->header_position; - d->TrueGaplessPresent = si->is_true_gapless; - d->SampleRate = (mpc_int32_t)si->sample_freq; - - d->samples_to_skip = MPC_DECODER_SYNTH_DELAY; - - memset(d->SeekTable, 0, sizeof(Seekbuffer)); - - // limit used table size to MPC_SEEK_BUFFER_SIZE - seekTableSize = min(si->frames, MPC_SEEK_BUFFER_SIZE); - // frames per buffer to not exceed buffer and to be able to seek full file - while ( seekTableSize < si->frames / (1<SeekTable_Step) ) - { - d->SeekTable_Step++; - } - d->SeekTable_Mask = (1 << d->SeekTable_Step) - 1; -} - -mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si) -{ - mpc_uint32_t bitPos; - mpc_uint32_t fpos; - - mpc_decoder_set_streaminfo(d, si); - - // setting position to the beginning of the data-bitstream - bitPos = get_initial_fpos(d, d->StreamVersion); - fpos = bitPos >> 5; - - // fill buffer and initialize decoder - f_seek(d, fpos*4 + d->MPCHeaderPos); - f_read_dword(d, d->Speicher, MEMSIZE); - d->Ring = 0; - d->Zaehler = 0; - d->pos = bitPos & 31; - d->WordsRead = fpos; - d->dword = SWAP(d->Speicher[0]); - d->next = SWAP(d->Speicher[1]); - - return TRUE; -} - -// 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; - (void) StreamVersion; - - // setting position to the beginning of the data-bitstream - switch ( d->StreamVersion ) { - case 0x04: fpos = 48; break; - case 0x05: - case 0x06: fpos = 64; break; - case 0x07: - case 0x17: fpos = 200; break; - } - return fpos; -} - -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)); -} - -void mpc_decoder_reset_state(mpc_decoder *d) { - - memset(d->Y_L , 0, sizeof Y_L ); - memset(d->Y_R , 0, sizeof Y_R ); -#ifdef SCF_HACK - memset(d->SCF_Index_L , 127, sizeof d->SCF_Index_L ); - memset(d->SCF_Index_R , 127, 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 ); -#endif - memset(d->Q , 0, sizeof d->Q ); - memset(d->MS_Flag , 0, sizeof d->MS_Flag ); - -} - -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 - seekFrame = seekFrame < d->OverallFrames ? seekFrame : d->OverallFrames; - - // seek direction (note: avoids casting to int64) - delta = (d->DecodedFrames > seekFrame ? -(mpc_int32_t)(d->DecodedFrames - seekFrame) : (mpc_int32_t)(seekFrame - d->DecodedFrames)); - - if (seekFrame > SEEK_PRE_DECODE) - lastFrame = seekFrame - SEEK_PRE_DECODE + 1 - (1<SeekTable_Step); - - if (d->MaxDecodedFrames == 0) // nothing decoded yet, parse stream - { - 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); - - // jump to the last frame via parsing, updating seek table - d->SeekTable[0] = (mpc_uint32_t)fpos; - d->SeekTableCounter = 0; - for (d->DecodedFrames = 0; d->DecodedFrames < lastFrame; d->DecodedFrames++) - { - d->SeekTableCounter += mpc_decoder_jump_frame(d); - if (0 == ((d->DecodedFrames+1) & (d->SeekTable_Mask))) - { - d->SeekTable[(d->DecodedFrames+1)>>d->SeekTable_Step] = d->SeekTableCounter; - d->MaxDecodedFrames = d->DecodedFrames; - d->SeekTableCounter = 0; - } - } - } - else if (delta < 0) // jump backwards, seek table is already available - { - mpc_decoder_reset_state(d); - - // jumps backwards using the seek table - fpos = d->SeekTable[0]; - for (d->DecodedFrames = 0; d->DecodedFrames < lastFrame; d->DecodedFrames++) - { - if (0 == ((d->DecodedFrames+1) & (d->SeekTable_Mask))) - { - fpos += d->SeekTable[(d->DecodedFrames+1)>>d->SeekTable_Step]; - d->SeekTableCounter = 0; - } - } - mpc_decoder_seek_to(d, fpos); - } - else if (delta > SEEK_PRE_DECODE) // jump forward, seek table is available - { - mpc_decoder_reset_state(d); - - // 1st loop: jump to the last usable position in the seek table - fpos = mpc_decoder_bits_read(d); - for (; d->DecodedFrames < d->MaxDecodedFrames && d->DecodedFrames < lastFrame; d->DecodedFrames++) - { - if (0 == ((d->DecodedFrames+1) & (d->SeekTable_Mask))) - { - fpos += d->SeekTable[(d->DecodedFrames+1)>>d->SeekTable_Step]; - d->SeekTableCounter = 0; - } - } - mpc_decoder_seek_to(d, fpos); - - // 2nd loop: jump the residual frames via parsing, update seek table - for (;d->DecodedFrames < lastFrame; d->DecodedFrames++) - { - d->SeekTableCounter += mpc_decoder_jump_frame(d); - if (0 == ((d->DecodedFrames+1) & (d->SeekTable_Mask))) - { - d->SeekTable[(d->DecodedFrames+1)>>d->SeekTable_Step] = d->SeekTableCounter; - d->MaxDecodedFrames = d->DecodedFrames; - d->SeekTableCounter = 0; - } - } - } - // until here we jumped to desired position -SEEK_PRE_DECODE frames - - // now we decode the last SEEK_PRE_DECODE frames until we reach the seek - // position. this is neccessary as mpc uses entropy coding in time domain - for (;d->DecodedFrames < seekFrame; d->DecodedFrames++) - { - mpc_uint32_t FrameBitCnt; - - 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) - if (d->StreamVersion >= 7) - { - mpc_decoder_read_bitstream_sv7(d, (d->DecodedFrames < seekFrame - 1)); - } - else - { -#ifdef MPC_SUPPORT_SV456 - mpc_decoder_read_bitstream_sv6(d); -#else - return FALSE; -#endif - } - - FrameBitCnt = mpc_decoder_bits_read(d) - FrameBitCnt; - - if (d->FwdJumpInfo > FrameBitCnt) - mpc_decoder_seek_forward(d, d->FwdJumpInfo - FrameBitCnt); - else if (FrameBitCnt != d->FwdJumpInfo ) - // Bug in perform_jump; - return FALSE; - - // update seek table, if there new entries to fill - d->SeekTableCounter += d->FwdJumpInfo + 20; - if (0 == ((d->DecodedFrames+1) & (d->SeekTable_Mask))) - { - d->SeekTable[(d->DecodedFrames+1)>>d->SeekTable_Step] = d->SeekTableCounter; - d->MaxDecodedFrames = d->DecodedFrames; - d->SeekTableCounter = 0; - } - - // update buffer - mpc_decoder_update_buffer(d); - - if (d->DecodedFrames == seekFrame - 1) - { - // initialize the synth correctly for perfect decoding - mpc_decoder_requantisierung(d, d->Max_Band); - mpc_decoder_synthese_filter_float(d, NULL); - } - } - - return TRUE; -} - - -void mpc_decoder_fill_buffer(mpc_decoder *d) { - - f_read_dword(d, d->Speicher, MEMSIZE); - d->dword = SWAP(d->Speicher[d->Zaehler = 0]); - d->next = SWAP(d->Speicher[1]); - d->Ring = 0; - -} - - -void mpc_decoder_update_buffer(mpc_decoder *d) -{ - if ((d->Ring ^ d->Zaehler) & MEMSIZE2) { - // update buffer - f_read_dword(d, d->Speicher + (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); - + /***************************** Header *****************************/ + if (is_key_frame == MPC_TRUE) { + Max_used_Band = mpc_bits_log_dec(r, d->max_band + 1); } 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); - + Max_used_Band = d->last_max_band + mpc_bits_can_dec(r, & mpc_can_Bands); + if (Max_used_Band > 32) Max_used_Band -= 33; + } + d->last_max_band = Max_used_Band; + + if (Max_used_Band) { + d->Res_L[Max_used_Band-1] = mpc_bits_can_dec(r, & mpc_can_Res[0]); + d->Res_R[Max_used_Band-1] = mpc_bits_can_dec(r, & mpc_can_Res[0]); + if (d->Res_L[Max_used_Band-1] > 15) d->Res_L[Max_used_Band-1] -= 17; + if (d->Res_R[Max_used_Band-1] > 15) d->Res_R[Max_used_Band-1] -= 17; + for ( n = Max_used_Band - 2; n >= 0; n--) { + d->Res_L[n] = mpc_bits_can_dec(r, & mpc_can_Res[d->Res_L[n + 1] > 2]) + d->Res_L[n + 1]; + if (d->Res_L[n] > 15) d->Res_L[n] -= 17; + d->Res_R[n] = mpc_bits_can_dec(r, & mpc_can_Res[d->Res_R[n + 1] > 2]) + d->Res_R[n + 1]; + if (d->Res_R[n] > 15) d->Res_R[n] -= 17; + } + + if (d->ms) { + int cnt = 0, tot = 0; + mpc_uint32_t tmp = 0; + for( n = 0; n < Max_used_Band; n++) + if ( d->Res_L[n] != 0 || d->Res_R[n] != 0 ) + tot++; + cnt = mpc_bits_log_dec(r, tot); + if (cnt != 0 && cnt != tot) + tmp = mpc_bits_enum_dec(r, mini(cnt, tot-cnt), tot); + if (cnt * 2 > tot) tmp = ~tmp; + for( n = Max_used_Band - 1; n >= 0; n--) + if ( d->Res_L[n] != 0 || d->Res_R[n] != 0 ) { + d->MS_Flag[n] = tmp & 1; + tmp >>= 1; + } + } + } + + for( n = Max_used_Band; n <= d->max_band; n++) + d->Res_L[n] = d->Res_R[n] = 0; + + /****************************** SCFI ******************************/ + if (is_key_frame == MPC_TRUE){ + for( n = 0; n < 32; n++) + d->DSCF_Flag_L[n] = d->DSCF_Flag_R[n] = 1; // new block -> force key frame + } + + Tables[0] = & mpc_can_SCFI[0]; + Tables[1] = & mpc_can_SCFI[1]; + for ( n = 0; n < Max_used_Band; n++ ) { + int tmp = 0, cnt = -1; + if (d->Res_L[n]) cnt++; + if (d->Res_R[n]) cnt++; + if (cnt >= 0) { + tmp = mpc_bits_can_dec(r, Tables[cnt]); + if (d->Res_L[n]) d->SCFI_L[n] = tmp >> (2 * cnt); + if (d->Res_R[n]) d->SCFI_R[n] = tmp & 3; + } + } + + /**************************** SCF/DSCF ****************************/ + + for ( n = 0; n < Max_used_Band; n++ ) { + mpc_int32_t * SCF = d->SCF_Index_L[n]; + mpc_uint32_t Res = d->Res_L[n], SCFI = d->SCFI_L[n]; + mpc_bool_t * DSCF_Flag = &d->DSCF_Flag_L[n]; + + do { + if ( Res ) { + int m; + if (*DSCF_Flag == 1) { + SCF[0] = (mpc_int32_t)mpc_bits_read(r, 7) - 6; + *DSCF_Flag = 0; + } else { + mpc_uint_t tmp = mpc_bits_can_dec(r, & mpc_can_DSCF[1]); + if (tmp == 64) + tmp += mpc_bits_read(r, 6); + SCF[0] = ((SCF[2] - 25 + tmp) & 127) - 6; + } + for( m = 0; m < 2; m++){ + if (((SCFI << m) & 2) == 0) { + mpc_uint_t tmp = mpc_bits_can_dec(r, & mpc_can_DSCF[0]); + if (tmp == 31) + tmp = 64 + mpc_bits_read(r, 6); + SCF[m + 1] = ((SCF[m] - 25 + tmp) & 127) - 6; + } else + SCF[m + 1] = SCF[m]; + } + } + Res = d->Res_R[n]; + SCFI = d->SCFI_R[n]; + DSCF_Flag = &d->DSCF_Flag_R[n]; + } while ( SCF == d->SCF_Index_L[n] && (SCF = d->SCF_Index_R[n])); + } + + /***************************** Samples ****************************/ + for ( n = 0; n < Max_used_Band; n++ ) { + mpc_int16_t *q = d->Q[n].L, Res = d->Res_L[n]; + static const int thres[] = {0, 0, 3, 0, 0, 1, 3, 4, 8}; + do { + mpc_int32_t k = 0, idx = 1; + if (Res != 0) { + if (Res == 2) { + Tables[0] = & mpc_can_Q [0][0]; + Tables[1] = & mpc_can_Q [0][1]; + idx = 2 * thres[Res]; + for ( ; k < 36; k += 3) { + int tmp = mpc_bits_can_dec(r, Tables[idx > thres[Res]]); + q[k] = g_sv8_idx50[tmp]; + q[k + 1] = g_sv8_idx51[tmp]; + q[k + 2] = g_sv8_idx52[tmp]; + idx = (idx >> 1) + g_sv8_HuffQ2_var[tmp]; + } + } else if (Res == 1) { + Table = & mpc_can_Q1; + for( ; k < 36; ){ + int kmax = k + 18; + mpc_uint_t cnt = mpc_bits_can_dec(r, Table); + idx = 0; + if (cnt > 0 && cnt < 18) + idx = mpc_bits_enum_dec(r, cnt <= 9 ? cnt : 18 - cnt, 18); + if (cnt > 9) idx = ~idx; + for ( ; k < kmax; k++) { + q[k] = 0; + if ( idx & (1 << 17) ) + q[k] = (mpc_bits_read(r, 1) << 1) - 1; + idx <<= 1; + } + } + } else if (Res == -1) { + for ( ; k<36; k++ ) { + mpc_uint32_t tmp = mpc_random_int(d); + q[k] = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510; + } + } else if (Res <= 4) { + Table = & mpc_can_Q[1][Res - 3]; + for ( ; k < 36; k += 2 ) { + union { + mpc_int8_t sym; + struct { mpc_int8_t s1:4, s2:4; }; + } tmp; + tmp.sym = mpc_bits_can_dec(r, Table); + q[k] = tmp.s1; + q[k + 1] = tmp.s2; + } + } else if (Res <= 8) { + Tables[0] = & mpc_can_Q [Res - 3][0]; + Tables[1] = & mpc_can_Q [Res - 3][1]; + idx = 2 * thres[Res]; + for ( ; k < 36; k++ ) { + q[k] = mpc_bits_can_dec(r, Tables[idx > thres[Res]]); + idx = (idx >> 1) + absi(q[k]); + } + } else { + for ( ; k < 36; k++ ) { + q[k] = (unsigned char) mpc_bits_can_dec(r, & mpc_can_Q9up); + if (Res != 9) + q[k] = (q[k] << (Res - 9)) | mpc_bits_read(r, Res - 9); + q[k] -= Dc[Res]; + } + } + } + + Res = d->Res_R[n]; + } while (q == d->Q[n].L && (q = d->Q[n].R)); } - -} - -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; - } diff --git a/apps/codecs/libmusepack/mpc_demux.c b/apps/codecs/libmusepack/mpc_demux.c new file mode 100755 index 0000000000..75d02bae54 --- /dev/null +++ b/apps/codecs/libmusepack/mpc_demux.c @@ -0,0 +1,666 @@ +/* + Copyright (c) 2005-2009, The Musepack Development Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the The Musepack Development Team nor the + names of its contributors may be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include "streaminfo.h" +#include "mpcdec.h" +#include "internal.h" +#include "decoder.h" +#include "huffman.h" +#include "mpc_bits_reader.h" + +#include + +/// maximum number of seek points in the table. The distance between points will +/// be adapted so this value is never exceeded. +#define MAX_SEEK_TABLE_SIZE 8192 + +// globals +static mpc_uint8_t g_buffer[DEMUX_BUFFER_SIZE + MAX_FRAME_SIZE]; +static mpc_seek_t g_seek_table[MAX_SEEK_TABLE_SIZE]; +static mpc_demux g_mpc_demux IBSS_ATTR; + +// streaminfo.c +mpc_status streaminfo_read_header_sv8(mpc_streaminfo* si, + const mpc_bits_reader * r_in, + mpc_size_t block_size); +mpc_status streaminfo_read_header_sv7(mpc_streaminfo* si, mpc_bits_reader * r_in); +void streaminfo_encoder_info(mpc_streaminfo* si, const mpc_bits_reader * r_in); +void streaminfo_gain(mpc_streaminfo* si, const mpc_bits_reader * r_in); + +// mpc_decoder.c +void mpc_decoder_reset_scf(mpc_decoder * d, int value); + +enum { + MPC_BUFFER_SWAP = 1, + MPC_BUFFER_FULL = 2, +}; + +static void mpc_demux_clear_buff(mpc_demux * d) +{ + d->bytes_total = 0; + d->bits_reader.buff = d->buffer; + d->bits_reader.count = 8; + d->bits_reader.buffered_addr = 0; + d->bits_reader.buffered_code = 0; + d->block_bits = 0; + d->block_frames = 0; + memset(d->buffer, 0, sizeof(g_buffer)); +} + +static mpc_uint32_t +mpc_demux_fill(mpc_demux * d, mpc_uint32_t min_bytes, int flags) +{ + mpc_uint32_t unread_bytes = d->bytes_total + d->buffer - d->bits_reader.buff + - ((8 - d->bits_reader.count) >> 3); + int offset = 0; + + if (min_bytes == 0 || min_bytes > DEMUX_BUFFER_SIZE || + (unread_bytes < min_bytes && flags & MPC_BUFFER_FULL)) + min_bytes = DEMUX_BUFFER_SIZE; + + if (unread_bytes < min_bytes) { + mpc_uint32_t bytes2read = min_bytes - unread_bytes; + mpc_uint32_t bytes_free = DEMUX_BUFFER_SIZE - d->bytes_total; + + if (flags & MPC_BUFFER_SWAP) { + bytes2read &= -1 << 2; + offset = (unread_bytes + 3) & ( -1 << 2); + offset -= unread_bytes; + } + + if (bytes2read > bytes_free) { + if (d->bits_reader.count == 0) { + d->bits_reader.count = 8; + d->bits_reader.buff++; + } + memmove(d->buffer + offset, d->bits_reader.buff, unread_bytes); + d->bits_reader.buff = d->buffer + offset; + d->bytes_total = unread_bytes + offset; + } + bytes2read = d->r->read(d->r, d->buffer + d->bytes_total, bytes2read); + if (flags & MPC_BUFFER_SWAP){ + unsigned int i, * tmp = (unsigned int *) (d->buffer + d->bytes_total); + for(i = 0 ;i < (bytes2read >> 2); i++) + tmp[i] = swap32(tmp[i]); + } + d->bytes_total += bytes2read; + return bytes2read; + } + + return (mpc_uint32_t) -1; +} + +/** + * seek to a bit position in the stream + * @param d demuxer context + * @param fpos position in the stream in bits from the beginning of mpc datas + * @param min_bytes number of bytes to load after seeking + */ +static void +mpc_demux_seek(mpc_demux * d, mpc_seek_t fpos, mpc_uint32_t min_bytes) { + mpc_seek_t next_pos; + mpc_int_t bit_offset; + + // FIXME : do not flush the buffer if fpos is in the current buffer + + next_pos = fpos >> 3; + if (d->si.stream_version == 7) + next_pos = ((next_pos - d->si.header_position) & (-1 << 2)) + d->si.header_position; + bit_offset = (int) (fpos - (next_pos << 3)); + + d->r->seek(d->r, (mpc_int32_t) next_pos); + mpc_demux_clear_buff(d); + if (d->si.stream_version == 7) + mpc_demux_fill(d, (min_bytes + ((bit_offset + 7) >> 3) + 3) & (~3), MPC_BUFFER_SWAP); + else + mpc_demux_fill(d, min_bytes + ((bit_offset + 7) >> 3), 0); + d->bits_reader.buff += bit_offset >> 3; + d->bits_reader.count = 8 - (bit_offset & 7); +} + +/** + * return the current position in the stream (in bits) from the beginning + * of the file + * @param d demuxer context + * @return current stream position in bits + */ +mpc_seek_t mpc_demux_pos(mpc_demux * d) +{ + return (((mpc_seek_t)(d->r->tell(d->r)) - d->bytes_total + + d->bits_reader.buff - d->buffer) << 3) + 8 - d->bits_reader.count; +} + +/** + * Searches for a ID3v2-tag and reads the length (in bytes) of it. + * + * @param d demuxer context + * @return size of tag, in bytes + * @return MPC_STATUS_FILE on errors of any kind + */ +static mpc_int32_t mpc_demux_skip_id3v2(mpc_demux * d) +{ + mpc_uint8_t tmp [4]; + mpc_bool_t footerPresent; // ID3v2.4-flag + mpc_int32_t size; + + // we must be at the beginning of the stream + mpc_demux_fill(d, 3, 0); + + // check id3-tag + if ( 0 != memcmp( d->bits_reader.buff, "ID3", 3 ) ) + return 0; + + mpc_demux_fill(d, 10, 0); + + mpc_bits_read(&d->bits_reader, 24); // read ID3 + mpc_bits_read(&d->bits_reader, 16); // read tag version + + tmp[0] = mpc_bits_read(&d->bits_reader, 8); // read flags + footerPresent = tmp[0] & 0x10; + if ( tmp[0] & 0x0F ) + return MPC_STATUS_FILE; // not (yet???) allowed + + tmp[0] = mpc_bits_read(&d->bits_reader, 8); // read size + tmp[1] = mpc_bits_read(&d->bits_reader, 8); // read size + tmp[2] = mpc_bits_read(&d->bits_reader, 8); // read size + tmp[3] = mpc_bits_read(&d->bits_reader, 8); // read size + + if ( (tmp[0] | tmp[1] | tmp[2] | tmp[3]) & 0x80 ) + return MPC_STATUS_FILE; // not allowed + + // read headerSize (syncsave: 4 * $0xxxxxxx = 28 significant bits) + size = tmp[0] << 21; + size |= tmp[1] << 14; + size |= tmp[2] << 7; + size |= tmp[3]; + + size += 10; //header + + if ( footerPresent ) size += 10; + + // This is called before file headers get read, streamversion etc isn't yet known, demuxing isn't properly initialized and we can't call mpc_demux_seek() from here. + mpc_demux_clear_buff(d); + if (!d->r->seek(d->r, size)) return MPC_STATUS_FILE; + + return size; +} + +static mpc_status mpc_demux_seek_init(mpc_demux * d) +{ + size_t seek_table_size; + if (d->seek_table != 0) + return MPC_STATUS_OK; + + d->seek_pwr = 6; + if (d->si.block_pwr > d->seek_pwr) + d->seek_pwr = d->si.block_pwr; + seek_table_size = (2 + d->si.samples / (MPC_FRAME_LENGTH << d->seek_pwr)); + while (seek_table_size > MAX_SEEK_TABLE_SIZE) { + d->seek_pwr++; + seek_table_size = (2 + d->si.samples / (MPC_FRAME_LENGTH << d->seek_pwr)); + } + d->seek_table = g_seek_table; + if (d->seek_table == 0) + return MPC_STATUS_FILE; + d->seek_table[0] = (mpc_seek_t)mpc_demux_pos(d); + d->seek_table_size = 1; + + return MPC_STATUS_OK; +} + +static void mpc_demux_ST(mpc_demux * d) +{ + mpc_uint64_t tmp; + mpc_seek_t * table, last[2]; + mpc_bits_reader r = d->bits_reader; + mpc_uint_t i, diff_pwr = 0, mask; + mpc_uint32_t file_table_size; + + if (d->seek_table != 0) + return; + + mpc_bits_get_size(&r, &tmp); + file_table_size = (mpc_seek_t) tmp; + d->seek_pwr = d->si.block_pwr + mpc_bits_read(&r, 4); + + tmp = 2 + d->si.samples / (MPC_FRAME_LENGTH << d->seek_pwr); + while (tmp > MAX_SEEK_TABLE_SIZE) { + d->seek_pwr++; + diff_pwr++; + tmp = 2 + d->si.samples / (MPC_FRAME_LENGTH << d->seek_pwr); + } + if ((file_table_size >> diff_pwr) > tmp) + file_table_size = tmp << diff_pwr; + d->seek_table = g_seek_table; + d->seek_table_size = (file_table_size + ((1 << diff_pwr) - 1)) >> diff_pwr; + + table = d->seek_table; + mpc_bits_get_size(&r, &tmp); + table[0] = last[0] = (mpc_seek_t) (tmp + d->si.header_position) * 8; + + if (d->seek_table_size == 1) + return; + + mpc_bits_get_size(&r, &tmp); + last[1] = (mpc_seek_t) (tmp + d->si.header_position) * 8; + if (diff_pwr == 0) table[1] = last[1]; + + mask = (1 << diff_pwr) - 1; + for (i = 2; i < file_table_size; i++) { + int code = mpc_bits_golomb_dec(&r, 12); + if (code & 1) + code = -(code & (-1 << 1)); + code <<= 2; + last[i & 1] = code + 2 * last[(i-1) & 1] - last[i & 1]; + if ((i & mask) == 0) + table[i >> diff_pwr] = last[i & 1]; + } +} + +static void mpc_demux_SP(mpc_demux * d, int size, int block_size) +{ + mpc_seek_t cur; + mpc_uint64_t ptr; + mpc_block b; + int st_head_size; + + cur = mpc_demux_pos(d); + mpc_bits_get_size(&d->bits_reader, &ptr); + mpc_demux_seek(d, (ptr - size) * 8 + cur, 11); + st_head_size = mpc_bits_get_block(&d->bits_reader, &b); + if (memcmp(b.key, "ST", 2) == 0) { + d->chap_pos = (ptr - size + b.size + st_head_size) * 8 + cur; + d->chap_nb = -1; + mpc_demux_fill(d, (mpc_uint32_t) b.size, 0); + mpc_demux_ST(d); + } + mpc_demux_seek(d, cur, 11 + block_size); +} +/* rockbox: not used +static void mpc_demux_chap_find(mpc_demux * d) +{ + mpc_block b; + int tag_size = 0, chap_size = 0, size, i = 0; + + d->chap_nb = 0; + + if (d->si.stream_version < 8) + return; + + if (d->chap_pos == 0) { + mpc_uint64_t cur_pos = (d->si.header_position + 4) * 8; + mpc_demux_seek(d, cur_pos, 11); // seek to the beginning of the stream + size = mpc_bits_get_block(&d->bits_reader, &b); + while (memcmp(b.key, "SE", 2) != 0) { + if (mpc_check_key(b.key) != MPC_STATUS_OK) + return; + if (memcmp(b.key, "CT", 2) == 0) { + if (d->chap_pos == 0) d->chap_pos = cur_pos; + } else + d->chap_pos = 0; + cur_pos += (size + b.size) * 8; + mpc_demux_seek(d, cur_pos, 11); + size = mpc_bits_get_block(&d->bits_reader, &b); + } + if (d->chap_pos == 0) + d->chap_pos = cur_pos; + } + + mpc_demux_seek(d, d->chap_pos, 20); + size = mpc_bits_get_block(&d->bits_reader, &b); + while (memcmp(b.key, "CT", 2) == 0) { + mpc_uint64_t chap_sample; + d->chap_nb++; + chap_size += size; + size = mpc_bits_get_size(&d->bits_reader, &chap_sample) + 4; + chap_size += size; + tag_size += b.size - size; + mpc_demux_seek(d, d->chap_pos + (chap_size + tag_size) * 8, 20); + size = mpc_bits_get_block(&d->bits_reader, &b); + } + + if (d->chap_nb > 0) { + char * ptag; + d->chap = malloc(sizeof(mpc_chap_info) * d->chap_nb + tag_size); + ptag = (char*)(d->chap + d->chap_nb); + + mpc_demux_seek(d, d->chap_pos, 11); + size = mpc_bits_get_block(&d->bits_reader, &b); + while (memcmp(b.key, "CT", 2) == 0) { + mpc_demux_fill(d, 11 + (mpc_uint32_t) b.size, 0); + size = mpc_bits_get_size(&d->bits_reader, &d->chap[i].sample) + 4; + d->chap[i].gain = (mpc_uint16_t) mpc_bits_read(&d->bits_reader, 16); + d->chap[i].peak = (mpc_uint16_t) mpc_bits_read(&d->bits_reader, 16); + memcpy(ptag, d->bits_reader.buff + ((8 - d->bits_reader.count) >> 3), b.size - size); + d->bits_reader.buff += b.size - size; + d->chap[i].tag_size = b.size - size; + d->chap[i].tag = ptag; + ptag += b.size - size; + i++; + size = mpc_bits_get_block(&d->bits_reader, &b); + } + } + + d->bits_reader.buff -= size; +} +*/ + +/** + * Gets the number of chapters in the stream + * @param d pointer to a musepack demuxer + * @return the number of chapters found in the stream + */ +/* rockbox: not used +mpc_int_t mpc_demux_chap_nb(mpc_demux * d) +{ + if (d->chap_nb == -1) + mpc_demux_chap_find(d); + return d->chap_nb; +} +*/ +/** + * Gets datas associated to a given chapter + * The chapter tag is an APEv2 tag without the preamble + * @param d pointer to a musepack demuxer + * @param chap_nb chapter number you want datas (from 0 to mpc_demux_chap_nb(d) - 1) + * @return the chapter information structure + */ +/* rockbox: not used +mpc_chap_info const * mpc_demux_chap(mpc_demux * d, int chap_nb) +{ + if (d->chap_nb == -1) + mpc_demux_chap_find(d); + if (chap_nb >= d->chap_nb || chap_nb < 0) + return 0; + return &d->chap[chap_nb]; +} +*/ + +static mpc_status mpc_demux_header(mpc_demux * d) +{ + char magic[4]; + + d->si.pns = 0xFF; +/* rockbox: not used + d->si.profile_name = "n.a."; +*/ + // get header position + d->si.header_position = mpc_demux_skip_id3v2(d); + if(d->si.header_position < 0) return MPC_STATUS_FILE; + + d->si.tag_offset = d->si.total_file_length = d->r->get_size(d->r); + + mpc_demux_fill(d, 4, 0); + magic[0] = mpc_bits_read(&d->bits_reader, 8); + magic[1] = mpc_bits_read(&d->bits_reader, 8); + magic[2] = mpc_bits_read(&d->bits_reader, 8); + magic[3] = mpc_bits_read(&d->bits_reader, 8); + + if (memcmp(magic, "MP+", 3) == 0) { + d->si.stream_version = magic[3] & 15; + d->si.pns = magic[3] >> 4; + if (d->si.stream_version == 7) { + mpc_status ret; + mpc_demux_fill(d, 6 * 4, MPC_BUFFER_SWAP); // header block size + endian convertion + ret = streaminfo_read_header_sv7(&d->si, &d->bits_reader); + if (ret != MPC_STATUS_OK) return ret; + } else { + return MPC_STATUS_INVALIDSV; + } + } else if (memcmp(magic, "MPCK", 4) == 0) { + mpc_block b; + int size; + mpc_demux_fill(d, 11, 0); // max header block size + size = mpc_bits_get_block(&d->bits_reader, &b); + while( memcmp(b.key, "AP", 2) != 0 ){ // scan all blocks until audio + if (mpc_check_key(b.key) != MPC_STATUS_OK) + return MPC_STATUS_INVALIDSV; + if (b.size > (mpc_uint64_t) DEMUX_BUFFER_SIZE - 11) + return MPC_STATUS_INVALIDSV; + mpc_demux_fill(d, 11 + (mpc_uint32_t) b.size, 0); + if (memcmp(b.key, "SH", 2) == 0){ + int ret = streaminfo_read_header_sv8(&d->si, &d->bits_reader, (mpc_uint32_t) b.size); + if (ret != MPC_STATUS_OK) return ret; + } else if (memcmp(b.key, "RG", 2) == 0) + streaminfo_gain(&d->si, &d->bits_reader); + else if (memcmp(b.key, "EI", 2) == 0) + streaminfo_encoder_info(&d->si, &d->bits_reader); + else if (memcmp(b.key, "SO", 2) == 0) + mpc_demux_SP(d, size, (mpc_uint32_t) b.size); + else if (memcmp(b.key, "ST", 2) == 0) + mpc_demux_ST(d); + d->bits_reader.buff += b.size; + size = mpc_bits_get_block(&d->bits_reader, &b); + } + d->bits_reader.buff -= size; + if (d->si.stream_version == 0) // si not initialized !!! + return MPC_STATUS_INVALIDSV; + } else + return MPC_STATUS_INVALIDSV; + + return MPC_STATUS_OK; +} + +mpc_demux * mpc_demux_init(mpc_reader * p_reader) +{ + mpc_demux* p_tmp = &g_mpc_demux; + + if (p_tmp != 0) { + memset(p_tmp, 0, sizeof(mpc_demux)); + p_tmp->buffer = g_buffer; + p_tmp->r = p_reader; + p_tmp->chap_nb = -1; + mpc_demux_clear_buff(p_tmp); + if (mpc_demux_header(p_tmp) == MPC_STATUS_OK && + mpc_demux_seek_init(p_tmp) == MPC_STATUS_OK) { + p_tmp->d = mpc_decoder_init(&p_tmp->si); + } else { + if (p_tmp->seek_table) + memset(p_tmp->seek_table, 0, sizeof(g_seek_table)); + p_tmp = 0; + } + } + + return p_tmp; +} + +void mpc_demux_exit(mpc_demux * d) +{ + mpc_decoder_exit(d->d); + memset(d->seek_table, 0, sizeof(g_seek_table)); +} + +void mpc_demux_get_info(mpc_demux * d, mpc_streaminfo * i) +{ + memcpy(i, &d->si, sizeof d->si); +} + +mpc_status mpc_demux_decode(mpc_demux * d, mpc_frame_info * i) +{ + mpc_bits_reader r; + if (d->si.stream_version >= 8) { + i->is_key_frame = MPC_FALSE; + + if (d->block_frames == 0) { + mpc_block b = {{0,0},0}; + d->bits_reader.count &= -8; + if (d->d->decoded_samples == (d->seek_table_size << d->seek_pwr) * MPC_FRAME_LENGTH) { + d->seek_table[d->seek_table_size] = (mpc_seek_t) mpc_demux_pos(d); + d->seek_table_size ++; + } + mpc_demux_fill(d, 11, 0); // max header block size + mpc_bits_get_block(&d->bits_reader, &b); + while( memcmp(b.key, "AP", 2) != 0 ) { // scan all blocks until audio + if (mpc_check_key(b.key) != MPC_STATUS_OK) + goto error; + if (memcmp(b.key, "SE", 2) == 0) { // end block + i->bits = -1; + return MPC_STATUS_OK; + } + if (mpc_demux_fill(d, 11 + (mpc_uint32_t) b.size, 0) == 0) + goto error; + d->bits_reader.buff += b.size; + mpc_bits_get_block(&d->bits_reader, &b); + } + d->block_bits = (mpc_uint32_t) b.size * 8; + d->block_frames = 1 << d->si.block_pwr; + i->is_key_frame = MPC_TRUE; + } + if (d->buffer + d->bytes_total - d->bits_reader.buff <= MAX_FRAME_SIZE) + mpc_demux_fill(d, (d->block_bits >> 3) + 1, 0); + r = d->bits_reader; + mpc_decoder_decode_frame(d->d, &d->bits_reader, i); + d->block_bits -= ((d->bits_reader.buff - r.buff) << 3) + r.count - d->bits_reader.count; + d->block_frames--; + if (d->block_bits < 0 || (d->block_frames == 0 && d->block_bits > 7)) + goto error; + } else { + if (d->d->decoded_samples == (d->seek_table_size << d->seek_pwr) * MPC_FRAME_LENGTH) { + d->seek_table[d->seek_table_size] = (mpc_seek_t) mpc_demux_pos(d); + d->seek_table_size ++; + } + mpc_demux_fill(d, MAX_FRAME_SIZE, MPC_BUFFER_FULL | MPC_BUFFER_SWAP); + d->block_bits = (mpc_int_t) mpc_bits_read(&d->bits_reader, 20); // read frame size + if (MPC_FRAME_LENGTH > d->d->samples - d->d->decoded_samples - 1) d->block_bits += 11; // we will read last frame size + r = d->bits_reader; + mpc_decoder_decode_frame(d->d, &d->bits_reader, i); + if (i->bits != -1 && d->block_bits != (mpc_int32_t)(((d->bits_reader.buff - r.buff) << 3) + r.count - d->bits_reader.count)) + goto error; + } + if (i->bits != -1 && d->buffer + d->bytes_total < d->bits_reader.buff + ((8 - d->bits_reader.count) >> 3)) + goto error; + + return MPC_STATUS_OK; +error: + i->bits = -1; // we pretend it's end of file + return MPC_STATUS_INVALIDSV; +} + +mpc_status mpc_demux_seek_second(mpc_demux * d, double seconds) +{ + return mpc_demux_seek_sample(d, (mpc_int64_t)(seconds * (double)d->si.sample_freq + 0.5)); +} + +mpc_status mpc_demux_seek_sample(mpc_demux * d, mpc_uint64_t destsample) +{ + mpc_uint32_t fwd, samples_to_skip, i; + mpc_uint32_t block_samples = MPC_FRAME_LENGTH << d->si.block_pwr; + mpc_seek_t fpos; + + destsample += d->si.beg_silence; + if (destsample > d->si.samples) destsample = d->si.samples; + fwd = (mpc_uint32_t) (destsample / block_samples); + samples_to_skip = MPC_DECODER_SYNTH_DELAY + + (mpc_uint32_t) (destsample % block_samples); + if (d->si.stream_version == 7) { + if (fwd > 32) { + fwd -= 32; + samples_to_skip += MPC_FRAME_LENGTH * 32; + } else { + samples_to_skip += MPC_FRAME_LENGTH * fwd; + fwd = 0; + } + } + + i = fwd >> (d->seek_pwr - d->si.block_pwr); + if (i >= d->seek_table_size) + i = d->seek_table_size - 1; + fpos = d->seek_table[i]; + i <<= d->seek_pwr - d->si.block_pwr; + d->d->decoded_samples = i * block_samples; + + if (d->si.stream_version >= 8) { + mpc_block b; + int size; + mpc_demux_seek(d, fpos, 11); + size = mpc_bits_get_block(&d->bits_reader, &b); + while(i < fwd) { + if (memcmp(b.key, "AP", 2) == 0) { + if (d->d->decoded_samples == (d->seek_table_size << d->seek_pwr) * MPC_FRAME_LENGTH) { + d->seek_table[d->seek_table_size] = (mpc_seek_t) mpc_demux_pos(d) - 8 * size; + d->seek_table_size ++; + } + d->d->decoded_samples += block_samples; + i++; + } + fpos += ((mpc_uint32_t)b.size + size) * 8; + mpc_demux_seek(d, fpos, 11); + size = mpc_bits_get_block(&d->bits_reader, &b); + } + d->bits_reader.buff -= size; + } else { + mpc_decoder_reset_scf(d->d, fwd != 0); + mpc_demux_seek(d, fpos, 4); + for( ; i < fwd; i++){ + if (d->d->decoded_samples == (d->seek_table_size << d->seek_pwr) * MPC_FRAME_LENGTH) { + d->seek_table[d->seek_table_size] = (mpc_seek_t) mpc_demux_pos(d); + d->seek_table_size ++; + } + d->d->decoded_samples += block_samples; + fpos += mpc_bits_read(&d->bits_reader, 20) + 20; + mpc_demux_seek(d, fpos, 4); + } + } + d->d->samples_to_skip = samples_to_skip; + return MPC_STATUS_OK; +} + +/* rockbox: not used +void mpc_set_replay_level(mpc_demux * d, float level, mpc_bool_t use_gain, + mpc_bool_t use_title, mpc_bool_t clip_prevention) +{ + float peak = use_title ? d->si.peak_title : d->si.peak_album; + float gain = use_title ? d->si.gain_title : d->si.gain_album; + + if(!use_gain && !clip_prevention) + return; + + if(!peak) + peak = 1.; + else + peak = (1 << 15) / pow(10, peak / (20 * 256)); + + if(!gain) + gain = 1.; + else + gain = pow(10, (level - gain / 256) / 20); + + if(clip_prevention && (peak < gain || !use_gain)) + gain = peak; + + mpc_decoder_scale_output(d->d, gain); +} +*/ diff --git a/apps/codecs/libmusepack/mpc_types.h b/apps/codecs/libmusepack/mpc_types.h new file mode 100755 index 0000000000..61ee5ea67f --- /dev/null +++ b/apps/codecs/libmusepack/mpc_types.h @@ -0,0 +1,148 @@ +/* + Copyright (c) 2005-2009, The Musepack Development Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the The Musepack Development Team nor the + names of its contributors may be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef _MPC_TYPES_H_ +#define _MPC_TYPES_H_ +#ifdef WIN32 +#pragma once +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MSC_VER +typedef __int8 mpc_int8_t; +typedef unsigned __int8 mpc_uint8_t; +typedef __int16 mpc_int16_t; +typedef unsigned __int16 mpc_uint16_t; +typedef __int32 mpc_int32_t; +typedef unsigned __int32 mpc_uint32_t; +typedef __int64 mpc_int64_t; +typedef unsigned __int64 mpc_uint64_t; +#define mpc_inline __inline +#else +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; +typedef unsigned int mpc_uint32_t; +typedef long long mpc_int64_t; +typedef unsigned long long mpc_uint64_t; +#define mpc_inline inline +#endif + +typedef int mpc_int_t; +typedef unsigned int mpc_uint_t; +typedef size_t mpc_size_t; +typedef mpc_uint8_t mpc_bool_t; + +// #define LONG_SEEK_TABLE +#ifdef LONG_SEEK_TABLE // define as needed (mpc_uint32_t supports files up to 512 MB) +typedef mpc_uint64_t mpc_seek_t; +#else +typedef mpc_uint32_t mpc_seek_t; +#endif + +# define mpc_int64_min -9223372036854775808ll +# define mpc_int64_max 9223372036854775807ll + +typedef struct mpc_quantizer { + mpc_int16_t L [36]; + mpc_int16_t R [36]; +} mpc_quantizer; + +/// Libmpcdec error codes +typedef enum mpc_status { + MPC_STATUS_OK = 0, + MPC_STATUS_FILE = -1, + MPC_STATUS_SV7BETA = -2, + MPC_STATUS_CBR = -3, + MPC_STATUS_IS = -4, + MPC_STATUS_BLOCKSIZE = -5, + MPC_STATUS_INVALIDSV = -6 +} mpc_status; + +#define MPC_FIXED_POINT +#define MPC_FIXED_POINT_SHIFT 16 + +#ifdef MPC_FIXED_POINT +# define MPC_FIXED_POINT_FRACTPART 14 +# define MPC_FIXED_POINT_SCALE_SHIFT (MPC_FIXED_POINT_SHIFT + MPC_FIXED_POINT_FRACTPART) +# define MPC_FIXED_POINT_SCALE (1 << (MPC_FIXED_POINT_SCALE_SHIFT - 1)) +typedef mpc_int32_t MPC_SAMPLE_FORMAT; +#else +typedef float MPC_SAMPLE_FORMAT; +#endif + +enum { + MPC_FALSE = 0, + MPC_TRUE = !MPC_FALSE +}; + +//// 'Cdecl' forces the use of standard C/C++ calling convention /////// +#if defined _WIN32 +# define mpc_cdecl __cdecl +#elif defined __ZTC__ +# define mpc_cdecl _cdecl +#elif defined __TURBOC__ +# define mpc_cdecl cdecl +#else +# define mpc_cdecl +#endif + +/* DLL building support on win32 hosts */ +#ifndef MPC_API +# ifdef DLL_EXPORT /* defined by libtool (if required) */ +# define MPC_API __declspec(dllexport) +# endif +# ifdef MPC_DLL_IMPORT /* define if linking with this dll */ +# define MPC_API __declspec(dllimport) +# endif +# ifndef MPC_API /* static linking or !_WIN32 */ +# if defined(__GNUC__) && (__GNUC__ >= 4) +# define MPC_API __attribute__ ((visibility("default"))) +# else +# define MPC_API +# endif +# endif +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/apps/codecs/libmusepack/mpcdec.h b/apps/codecs/libmusepack/mpcdec.h new file mode 100755 index 0000000000..a359951745 --- /dev/null +++ b/apps/codecs/libmusepack/mpcdec.h @@ -0,0 +1,186 @@ +/* + Copyright (c) 2005-2009, The Musepack Development Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the The Musepack Development Team nor the + names of its contributors may be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/// \file mpcdec.h +/// Top level include file for libmpcdec. +#ifndef _MPCDEC_H_ +#define _MPCDEC_H_ +#ifdef WIN32 +#pragma once +#endif + +#include "reader.h" +#include "streaminfo.h" +#include "config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef IBSS_ATTR_MPC_LARGE_IRAM +#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) || (CONFIG_CPU == MCF5250) +/* PP5022/24 and MCF5250 have 128KB of IRAM */ +#define IBSS_ATTR_MPC_LARGE_IRAM IBSS_ATTR +#else +/* other PP's and MCF5249 have 96KB of IRAM */ +#define IBSS_ATTR_MPC_LARGE_IRAM +#endif +#endif + +#ifndef ICODE_ATTR_MPC_LARGE_IRAM +#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) +/* PP5022/24 have 128KB of IRAM and have better performance with ICODE_ATTR */ +#define ICODE_ATTR_MPC_LARGE_IRAM ICODE_ATTR +#else +/* all other targets either haven't enough IRAM or performance suffers */ +#define ICODE_ATTR_MPC_LARGE_IRAM +#endif +#endif + +#ifndef ICONST_ATTR_MPC_LARGE_IRAM +#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) || (CONFIG_CPU == MCF5250) +/* PP5022/24 and MCF5250 have 128KB of IRAM */ +#define ICONST_ATTR_MPC_LARGE_IRAM ICONST_ATTR +#else +/* other PP's and MCF5249 have 96KB of IRAM */ +#define ICONST_ATTR_MPC_LARGE_IRAM +#endif +#endif + +enum { + MPC_FRAME_LENGTH = (36 * 32), ///< Samples per mpc frame + MPC_DECODER_BUFFER_LENGTH = (MPC_FRAME_LENGTH * 2), ///< Required buffer size for decoder (2 channels) + MPC_DECODER_SYNTH_DELAY = 481 +}; + +typedef struct mpc_decoder_t mpc_decoder; +typedef struct mpc_demux_t mpc_demux; + +typedef struct mpc_bits_reader_t { + unsigned char * buff; /// pointer on current byte + unsigned int count; /// unread bits in current byte + mpc_uint8_t *buffered_addr; /// used for rockbox Coldfire optimization only + mpc_uint32_t buffered_code; /// used for rockbox Coldfire optimization only +} mpc_bits_reader; + +typedef struct mpc_frame_info_t { + mpc_uint32_t samples; /// number of samples in the frame (counting once for multiple channels) + mpc_int32_t bits; /// number of bits consumed by this frame (-1) if end of stream + MPC_SAMPLE_FORMAT * buffer; /// frame samples buffer (size = samples * channels * sizeof(MPC_SAMPLE_FORMAT)) + mpc_bool_t is_key_frame; /// 1 if this frame is a key frame (first in block) 0 else. Set by the demuxer. +} mpc_frame_info; + +typedef struct mpc_chap_info_t { + mpc_uint64_t sample; /// sample where the chapter starts + mpc_uint16_t gain; /// replaygain chapter value + mpc_uint16_t peak; /// peak chapter loudness level + mpc_uint_t tag_size; /// size of the tag element (0 if no tag is present for this chapter) + char * tag; /// pointer to an APEv2 tag without the preamble +} mpc_chap_info; + +/// Initializes mpc decoder with the supplied stream info parameters. +/// \param si streaminfo structure indicating format of source stream +/// \return pointer on the initialized decoder structure if successful, 0 if not +MPC_API mpc_decoder * mpc_decoder_init(mpc_streaminfo *si); + +/// Releases input mpc decoder +MPC_API void mpc_decoder_exit(mpc_decoder *p_dec); + +/** + * Sets decoder sample scaling factor. All decoded samples will be multiplied + * by this factor. Useful for applying replay gain. + * @param scale_factor multiplicative scaling factor + */ +MPC_API void mpc_decoder_scale_output(mpc_decoder *p_dec, double scale_factor); + +MPC_API void mpc_decoder_decode_frame(mpc_decoder * d, mpc_bits_reader * r, mpc_frame_info * i); + +// This is the gain reference used in old replaygain +#define MPC_OLD_GAIN_REF 64.82 + +/** + * init demuxer + * @param p_reader initialized mpc_reader pointer + * @return an initialized mpc_demux pointer + */ +MPC_API mpc_demux * mpc_demux_init(mpc_reader * p_reader); +/// free demuxer +MPC_API void mpc_demux_exit(mpc_demux * d); +/** + * Calls mpc_decoder_scale_output to set the scaling factor according to the + * replay gain stream information and the supplied ouput level + * @param d pointer to a musepack demuxer + * @param level the desired ouput level (in db). Must be MPC_OLD_GAIN_REF (64.82 db) if you want to get the old replaygain behavior + * @param use_gain set it to MPC_TRUE if you want to set the scaling factor according to the stream gain + * @param use_title MPC_TRUE : uses the title gain, MPC_FALSE : uses the album gain + * @param clip_prevention MPC_TRUE : uses cliping prevention + */ +/* rockbox: not used +MPC_API void mpc_set_replay_level(mpc_demux * d, float level, mpc_bool_t use_gain, + mpc_bool_t use_title, mpc_bool_t clip_prevention); +*/ +/// decode frame +MPC_API mpc_status mpc_demux_decode(mpc_demux * d, mpc_frame_info * i); +/// get streaminfo +MPC_API void mpc_demux_get_info(mpc_demux * d, mpc_streaminfo * i); +/// seeks to a given sample +MPC_API mpc_status mpc_demux_seek_sample(mpc_demux * d, mpc_uint64_t destsample); +/// seeks to a given second +MPC_API mpc_status mpc_demux_seek_second(mpc_demux * d, double seconds); + +/// \return the current position in the stream (in bits) from the beginning of the file +MPC_API mpc_seek_t mpc_demux_pos(mpc_demux * d); + +/// chapters : only for sv8 streams +/** + * Gets the number of chapters in the stream + * @param d pointer to a musepack demuxer + * @return the number of chapters found in the stream + */ +/* rockbox: not used +MPC_API mpc_int_t mpc_demux_chap_nb(mpc_demux * d); +*/ +/** + * Gets datas associated to a given chapter + * The chapter tag is an APEv2 tag without the preamble + * @param d pointer to a musepack demuxer + * @param chap_nb chapter number you want datas (from 0 to mpc_demux_chap_nb(d) - 1) + * @return the chapter information structure + */ +/* rockbox: not used +MPC_API mpc_chap_info const * mpc_demux_chap(mpc_demux * d, int chap_nb); +*/ +#ifdef __cplusplus +} +#endif +#endif diff --git a/apps/codecs/libmusepack/math.h b/apps/codecs/libmusepack/mpcdec_math.h old mode 100644 new mode 100755 similarity index 95% rename from apps/codecs/libmusepack/math.h rename to apps/codecs/libmusepack/mpcdec_math.h index e4c2ffce20..55295dba32 --- a/apps/codecs/libmusepack/math.h +++ b/apps/codecs/libmusepack/mpcdec_math.h @@ -38,7 +38,7 @@ #ifndef _mpcdec_math_h_ #define _mpcdec_math_h_ -#include "mpc_config.h" +#include "mpc_types.h" #define MPC_FIXED_POINT_SHIFT 16 @@ -48,15 +48,9 @@ #include #define MPC_HAVE_MULHIGH #endif - - #define MPC_FIXED_POINT_SCALE_SHIFT (MPC_FIXED_POINT_SHIFT + MPC_FIXED_POINT_FRACTPART) - #define MPC_FIXED_POINT_SCALE (1 << (MPC_FIXED_POINT_SCALE_SHIFT - 1)) - //in fixedpoint mode, results in decode output buffer are in -MPC_FIXED_POINT_SCALE ... MPC_FIXED_POINT_SCALE range - - #define MPC_FIXED_POINT_FRACTPART 14 - typedef mpc_int32_t MPC_SAMPLE_FORMAT; + typedef mpc_int64_t MPC_SAMPLE_FORMAT_MULTIPLY; - + #define MAKE_MPC_SAMPLE(X) (MPC_SAMPLE_FORMAT)((double)(X) * (double)(((mpc_int64_t)1)< -#include - -#ifndef SIMULATOR -#include "codecs.h" -#endif -#include "config_types.h" -#include "decoder.h" -#include "math.h" -#include "reader.h" -#include "streaminfo.h" - -#ifndef IBSS_ATTR_MPC_SAMPLE_BUF -#define IBSS_ATTR_MPC_SAMPLE_BUF IBSS_ATTR -#endif - -#ifndef IBSS_ATTR_MPC_LARGE_IRAM -#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) || (CONFIG_CPU == MCF5250) -/* PP5022/24 and MCF5250 have 128KB of IRAM */ -#define IBSS_ATTR_MPC_LARGE_IRAM IBSS_ATTR -#else -/* other PP's and MCF5249 have 96KB of IRAM */ -#define IBSS_ATTR_MPC_LARGE_IRAM -#endif -#endif - -#ifndef ICODE_ATTR_MPC_LARGE_IRAM -#if (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024) -/* PP5022/24 have 128KB of IRAM and have better performance with ICODE_ATTR */ -#define ICODE_ATTR_MPC_LARGE_IRAM ICODE_ATTR -#else -/* all other targets either haven't enough IRAM or performance suffers */ -#define ICODE_ATTR_MPC_LARGE_IRAM -#endif -#endif - -#ifdef ROCKBOX_LITTLE_ENDIAN -#define MPC_LITTLE_ENDIAN -#endif - -enum { - MPC_FRAME_LENGTH = (36 * 32), /// samples per mpc frame - MPC_DECODER_BUFFER_LENGTH = 2 * MPC_FRAME_LENGTH /// required buffer size for decoder -}; - -// error codes -#define ERROR_CODE_OK 0 -#define ERROR_CODE_FILE -1 -#define ERROR_CODE_SV7BETA 1 -#define ERROR_CODE_CBR 2 -#define ERROR_CODE_IS 3 -#define ERROR_CODE_BLOCKSIZE 4 -#define ERROR_CODE_INVALIDSV 5 - -/// Initializes a streaminfo structure. -/// \param si streaminfo structure to initialize -void mpc_streaminfo_init(mpc_streaminfo *si); - -/// Reads streaminfo header from the mpc stream supplied by r. -/// \param si streaminfo pointer to which info will be written -/// \param r stream reader to supply raw data -/// \return error code -mpc_int32_t mpc_streaminfo_read(mpc_streaminfo *si, mpc_reader *r); - -/// Gets length of stream si, in seconds. -/// \return length of stream in seconds -double mpc_streaminfo_get_length(mpc_streaminfo *si); - -/// Returns length of stream si, in samples. -/// \return length of stream in samples -mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si); - -/// Sets up decoder library. -/// Call this first when preparing to decode an mpc stream. -/// \param r reader that will supply raw data to the decoder -void mpc_decoder_setup(mpc_decoder *d, mpc_reader *r); - -/// Initializes mpc decoder with the supplied stream info parameters. -/// Call this next after calling mpc_decoder_setup. -/// \param si streaminfo structure indicating format of source stream -/// \return TRUE if decoder was initalized successfully, FALSE otherwise -mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si); - -/// Sets decoder sample scaling factor. All decoded samples will be multiplied -/// by this factor. -/// \param scale_factor multiplicative scaling factor -void mpc_decoder_scale_output(mpc_decoder *d, double scale_factor); - -/// Actually reads data from previously initialized stream. Call -/// this iteratively to decode the mpc stream. -/// \param buffer destination buffer for decoded samples -/// \param vbr_update_acc \todo document me -/// \param vbr_update_bits \todo document me -/// \return -1 if an error is encountered -/// \return 0 if the stream has been completely decoded successfully and there are no more samples -/// \return > 0 to indicate the number of bytes that were actually read from the stream. -mpc_uint32_t mpc_decoder_decode( - mpc_decoder *d, - MPC_SAMPLE_FORMAT *buffer, - mpc_uint32_t *vbr_update_acc, - mpc_uint32_t *vbr_update_bits); - -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); - -/// Seeks to the specified sample in the source stream. -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); - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif // _mpcdec_h_ diff --git a/apps/codecs/libmusepack/reader.h b/apps/codecs/libmusepack/reader.h index 397319b292..60a0ef939d 100644 --- a/apps/codecs/libmusepack/reader.h +++ b/apps/codecs/libmusepack/reader.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, The Musepack Development Team + Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,52 +31,68 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /// \file reader.h +#ifndef _MPCDEC_READER_H_ +#define _MPCDEC_READER_H_ +#ifdef WIN32 +#pragma once +#endif + +#include "mpc_types.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif -#ifndef _mpcdec_reader_h_ -#define _mpcdec_reader_h_ /// \brief Stream reader interface structure. /// /// This is the structure you must supply to the musepack decoding library /// to feed it with raw data. Implement the five member functions to provide /// a functional reader. -typedef struct mpc_reader_t { +typedef struct mpc_reader_t mpc_reader; +struct mpc_reader_t { /// Reads size bytes of data into buffer at ptr. - mpc_int32_t (*read)(void *t, void *ptr, mpc_int32_t size); + mpc_int32_t (*read)(mpc_reader *p_reader, void *ptr, mpc_int32_t size); /// Seeks to byte position offset. - mpc_bool_t (*seek)(void *t, mpc_int32_t offset); + mpc_bool_t (*seek)(mpc_reader *p_reader, mpc_int32_t offset); /// Returns the current byte offset in the stream. - mpc_int32_t (*tell)(void *t); + mpc_int32_t (*tell)(mpc_reader *p_reader); /// Returns the total length of the source stream, in bytes. - mpc_int32_t (*get_size)(void *t); + mpc_int32_t (*get_size)(mpc_reader *p_reader); /// True if the stream is a seekable stream. - mpc_bool_t (*canseek)(void *t); + mpc_bool_t (*canseek)(mpc_reader *p_reader); /// Field that can be used to identify a particular instance of /// reader or carry along data associated with that reader. void *data; - -} mpc_reader; -/* No standard STDIO based reader in Rockbox -typedef struct mpc_reader_file_t { - mpc_reader reader; - - FILE *file; - long file_size; - mpc_bool_t is_seekable; -} mpc_reader_file; -*/ +}; +/* rockbox: not used /// Initializes reader with default stdio file reader implementation. Use /// this if you're just reading from a plain file. /// -/// \param r reader struct to initalize -/// \param input input stream to attach to the reader -/* void mpc_reader_setup_file_reader(mpc_reader_file *r, FILE *input); */ +/// \param r p_reader handle to initialize +/// \param filename input filename to attach to the reader +MPC_API mpc_status mpc_reader_init_stdio(mpc_reader *p_reader, const char *filename); -#endif // _mpcdec_reader_h_ +/// Initializes reader with default stdio file reader implementation. Use +/// this if you prefer to open the file yourself. +/// +/// \param r p_reader handle to initialize +/// \param p_file input file handle (already open) +MPC_API mpc_status mpc_reader_init_stdio_stream(mpc_reader * p_reader, FILE * p_file); + +/// Release reader with default stdio file reader implementation. +/// +/// \param r reader handle to release +MPC_API void mpc_reader_exit_stdio(mpc_reader *p_reader); +*/ +#ifdef __cplusplus +} +#endif +#endif diff --git a/apps/codecs/libmusepack/requant.c b/apps/codecs/libmusepack/requant.c index d40f36fded..d8ded7ecf9 100644 --- a/apps/codecs/libmusepack/requant.c +++ b/apps/codecs/libmusepack/requant.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, The Musepack Development Team + Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,117 +31,93 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /// \file requant.c /// Requantization function implementations. /// \todo document me - -#include "musepack.h" -#include "internal.h" +#include "mpcdec.h" +#include "requant.h" +#include "mpcdec_math.h" +#include "decoder.h" /* C O N S T A N T S */ -// bits per sample for chosen quantizer -const mpc_uint32_t Res_bit [18] ICONST_ATTR = { +// Bits per sample for chosen quantizer +const mpc_uint8_t Res_bit [18] ICONST_ATTR = { 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; -// coefficients for requantization +// Requantization coefficients // 65536/step bzw. 65536/(2*D+1) #define _(X) MAKE_MPC_SAMPLE_EX(X,14) const MPC_SAMPLE_FORMAT __Cc [1 + 18] ICONST_ATTR = { - _(111.285962475327f), // 32768/2/255*sqrt(3) + _(111.285962475327f), // 32768/2/255*sqrt(3) _(65536.000000000000f), _(21845.333333333332f), _(13107.200000000001f), _(9362.285714285713f), - _(7281.777777777777f), _(4369.066666666666f), _(2114.064516129032f), _(1040.253968253968f), - _(516.031496062992f), _(257.003921568627f), _(128.250489236790f), _(64.062561094819f), - _(32.015632633121f), _(16.003907203907f), _(8.000976681723f), _(4.000244155527f), - _(2.000061037018f), _(1.000015259021f) + _(7281.777777777777f), _(4369.066666666666f), _(2114.064516129032f), _(1040.253968253968f), + _(516.031496062992f), _(257.003921568627f), _(128.250489236790f), _(64.062561094819f), + _(32.015632633121f), _(16.003907203907f), _(8.000976681723f), _(4.000244155527f), + _(2.000061037018f), _(1.000015259021f) }; #undef _ -// offset for requantization +// Requantization offset // 2*D+1 = steps of quantizer -const mpc_int32_t __Dc [1 + 18] ICONST_ATTR = { +const mpc_int16_t __Dc [1 + 18] ICONST_ATTR = { 2, 0, 1, 2, 3, 4, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767 }; -// decoding results (requantized) for bundled quantizers (3- and 5-step) -// 1st value of bundled 3-step quantizer -const mpc_int32_t idx30[27] ICONST_ATTR = { -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}; -// 2nd value of bundled 3-step quantizer -const mpc_int32_t idx31[27] ICONST_ATTR = { -1,-1,-1, 0, 0, 0, 1, 1, 1, - -1,-1,-1, 0, 0, 0, 1, 1, 1, - -1,-1,-1, 0, 0, 0, 1, 1, 1}; -// 3rd value of bundled 3-step quantizer -const mpc_int32_t idx32[27] ICONST_ATTR = { -1,-1,-1,-1,-1,-1,-1,-1,-1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1}; -// 1st value of bundled 5-step quantizer -const mpc_int32_t idx50[25] ICONST_ATTR = { -2,-1, 0, 1, 2, - -2,-1, 0, 1, 2, - -2,-1, 0, 1, 2, - -2,-1, 0, 1, 2, - -2,-1, 0, 1, 2}; -// 2nd value of bundled 5-step quantizer -const mpc_int32_t idx51[25] ICONST_ATTR = { -2,-2,-2,-2,-2, - -1,-1,-1,-1,-1, - 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, - 2, 2, 2, 2, 2}; - - #ifdef MPC_FIXED_POINT static mpc_uint32_t find_shift(double fval) { - mpc_int64_t val = (mpc_int64_t)fval; + mpc_int64_t val = (mpc_int64_t) fval; mpc_uint32_t ptr = 0; - if (val<0) val = -val; - while(val) {val>>=1;ptr++;} - + if(val<0) + val = -val; + while(val) + { + val >>= 1; + ptr++; + } return ptr > 31 ? 0 : 31 - ptr; } #endif /* F U N C T I O N S */ -#define SET_SCF(N,X) d->SCF[N] = MAKE_MPC_SAMPLE_EX(X,d->SCF_shift[N] = (unsigned char)find_shift(X)); +#define SET_SCF(N,X) d->SCF[N] = MAKE_MPC_SAMPLE_EX(X,d->SCF_shift[N] = (mpc_uint8_t) find_shift(X)); void -mpc_decoder_scale_output(mpc_decoder *d, double factor) +mpc_decoder_scale_output(mpc_decoder *d, double factor) { - mpc_int32_t n; - double f1; - double f2; + mpc_int32_t n; double f1, f2; + #ifndef MPC_FIXED_POINT - factor *= 1.0 / (double)(1<<(MPC_FIXED_POINT_SHIFT-1)); + factor *= 1.0 / (double) (1<<(MPC_FIXED_POINT_SHIFT-1)); #else - factor *= 1.0 / (double)(1<<(16 - MPC_FIXED_POINT_SHIFT)); + factor *= 1.0 / (double) (1<<(16-MPC_FIXED_POINT_SHIFT)); #endif f1 = f2 = factor; // handles +1.58...-98.41 dB, where's scf[n] / scf[n-1] = 1.20050805774840750476 - + SET_SCF(1,factor); f1 *= 0.83298066476582673961; f2 *= 1/0.83298066476582673961; for ( n = 1; n <= 128; n++ ) { - SET_SCF((unsigned char)(1+n),f1); - SET_SCF((unsigned char)(1-n),f2); + SET_SCF((mpc_uint8_t)(1+n),f1); + SET_SCF((mpc_uint8_t)(1-n),f2); f1 *= 0.83298066476582673961; f2 *= 1/0.83298066476582673961; } } void -mpc_decoder_initialisiere_quantisierungstabellen(mpc_decoder *d, double scale_factor) +mpc_decoder_init_quant(mpc_decoder *d, double scale_factor) { mpc_decoder_scale_output(d, scale_factor); } diff --git a/apps/codecs/libmusepack/requant.h b/apps/codecs/libmusepack/requant.h index 1a21c21143..8458d4d0fa 100644 --- a/apps/codecs/libmusepack/requant.h +++ b/apps/codecs/libmusepack/requant.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, The Musepack Development Team + Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,27 +31,31 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /// \file requant.h /// Requantization function definitions. +#ifndef _MPCDEC_REQUANT_H_ +#define _MPCDEC_REQUANT_H_ +#ifdef WIN32 +#pragma once +#endif -#ifndef _mpcdec_requant_h -#define _mpcdec_requant_h_ +#include "mpc_types.h" + +#ifdef __cplusplus +extern "C" { +#endif -#include "musepack.h" /* C O N S T A N T S */ -extern const mpc_uint32_t Res_bit[18]; // bits per sample for chosen quantizer -extern const MPC_SAMPLE_FORMAT __Cc[1 + 18]; // coefficients for requantization -extern const mpc_int32_t __Dc[1 + 18]; // offset for requantization -extern const mpc_int32_t idx30[27]; // 1st value of bundled 3-step quantizer -extern const mpc_int32_t idx31[27]; // 2nd value of bundled 3-step quantizer -extern const mpc_int32_t idx32[27]; // 3rd value of bundled 3-step quantizer -extern const mpc_int32_t idx50[25]; // 1st value of bundled 5-step quantizer -extern const mpc_int32_t idx51[25]; // 2nd value of bundled 5-step quantizer +const mpc_uint8_t Res_bit [18]; ///< Bits per sample for chosen quantizer +const MPC_SAMPLE_FORMAT __Cc [1 + 18]; ///< Requantization coefficients +const mpc_int16_t __Dc [1 + 18]; ///< Requantization offset + +#define Cc (__Cc + 1) +#define Dc (__Dc + 1) -#define Cc (__Cc + 1) -#define Dc (__Dc + 1) - -#endif // _mpcdec_requant_h_ +#ifdef __cplusplus +} +#endif +#endif diff --git a/apps/codecs/libmusepack/streaminfo.c b/apps/codecs/libmusepack/streaminfo.c index 3edf50a5ea..5c135ef64a 100644 --- a/apps/codecs/libmusepack/streaminfo.c +++ b/apps/codecs/libmusepack/streaminfo.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, The Musepack Development Team + Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,256 +31,226 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /// \file streaminfo.c /// Implementation of streaminfo reading functions. -#include "musepack.h" +#include +#include "mpcdec.h" +#include "streaminfo.h" +#include #include "internal.h" +#include "huffman.h" +#include "mpc_bits_reader.h" +unsigned long mpc_crc32(unsigned char *buf, int len); +/* rockbox: not used +static const char na[] = "n.a."; +static char const * const versionNames[] = { + na, "'Unstable/Experimental'", na, na, na, "'quality 0'", "'quality 1'", + "'Telephone'", "'Thumb'", "'Radio'", "'Standard'", "'Extreme'", "'Insane'", + "'BrainDead'", "'quality 9'", "'quality 10'" +}; +*/ +static const mpc_int32_t samplefreqs[8] = { 44100, 48000, 37800, 32000 }; +/* rockbox: not used static const char * -Stringify(mpc_uint32_t profile) // profile is 0...15, where 7...13 is used +mpc_get_version_string(float profile) // profile is 0...15, where 7...13 is used { - static const char na[] = "n.a."; - static const char *Names[] = { - na, "'Unstable/Experimental'", na, na, - na, "'quality 0'", "'quality 1'", "'Telephone'", - "'Thumb'", "'Radio'", "'Standard'", "'Xtreme'", - "'Insane'", "'BrainDead'", "'quality 9'", "'quality 10'" - }; + return profile >= sizeof versionNames / sizeof *versionNames ? na : versionNames[(int)profile]; +} +*/ +/* rockbox: not used +static void +mpc_get_encoder_string(mpc_streaminfo* si) +{ + int ver = si->encoder_version; + if (si->stream_version >= 8) + ver = (si->encoder_version >> 24) * 100 + ((si->encoder_version >> 16) & 0xFF); + if (ver <= 116) { + if (ver == 0) { + sprintf(si->encoder, "Buschmann 1.7.0...9, Klemm 0.90...1.05"); + } else { + switch (ver % 10) { + case 0: + sprintf(si->encoder, "Release %u.%u", ver / 100, + ver / 10 % 10); + break; + case 2: case 4: case 6: case 8: + sprintf(si->encoder, "Beta %u.%02u", ver / 100, + ver % 100); + break; + default: + sprintf(si->encoder, "--Alpha-- %u.%02u", + ver / 100, ver % 100); + break; + } + } + } else { + int major = si->encoder_version >> 24; + int minor = (si->encoder_version >> 16) & 0xFF; + int build = (si->encoder_version >> 8) & 0xFF; + char * tmp = "--Stable--"; - return profile >= sizeof(Names) / sizeof(*Names) ? na : Names[profile]; + if (minor & 1) + tmp = "--Unstable--"; + + sprintf(si->encoder, "%s %u.%u.%u", tmp, major, minor, build); + } +} +*/ + +static mpc_status check_streaminfo(mpc_streaminfo * si) +{ + if (si->max_band == 0 || si->max_band >= 32 + || si->channels > 2) + return MPC_STATUS_FILE; + return MPC_STATUS_OK; } -void -mpc_streaminfo_init(mpc_streaminfo * si) +/// Reads streaminfo from SV7 header. +mpc_status +streaminfo_read_header_sv7(mpc_streaminfo* si, mpc_bits_reader * r) { - memset(si, 0, sizeof(mpc_streaminfo)); -} - -/// Reads streaminfo from SV7 header. -static mpc_int32_t -streaminfo_read_header_sv7(mpc_streaminfo * si, mpc_uint32_t HeaderData[8]) -{ - const mpc_int32_t samplefreqs[4] = { 44100, 48000, 37800, 32000 }; - - //mpc_uint32_t HeaderData [8]; mpc_uint16_t Estimatedpeak_title = 0; + mpc_uint32_t frames, last_frame_samples; - if (si->stream_version > 0x71) { - // Update (si->stream_version); - return 0; + si->bitrate = 0; + frames = (mpc_bits_read(r, 16) << 16) | mpc_bits_read(r, 16); + mpc_bits_read(r, 1); // intensity stereo : should be 0 + si->ms = mpc_bits_read(r, 1); + si->max_band = mpc_bits_read(r, 6); + si->profile = mpc_bits_read(r, 4); +/* rockbox: not used + si->profile_name = mpc_get_version_string(si->profile); +*/ + mpc_bits_read(r, 2); // Link ? + si->sample_freq = samplefreqs[mpc_bits_read(r, 2)]; + Estimatedpeak_title = (mpc_uint16_t) mpc_bits_read(r, 16); // read the ReplayGain data + si->gain_title = (mpc_uint16_t) mpc_bits_read(r, 16); + si->peak_title = (mpc_uint16_t) mpc_bits_read(r, 16); + si->gain_album = (mpc_uint16_t) mpc_bits_read(r, 16); + si->peak_album = (mpc_uint16_t) mpc_bits_read(r, 16); + si->is_true_gapless = mpc_bits_read(r, 1); // true gapless: used? + last_frame_samples = mpc_bits_read(r, 11); // true gapless: valid samples for last frame + si->fast_seek = mpc_bits_read(r, 1); // fast seeking + mpc_bits_read(r, 19); // unused + si->encoder_version = mpc_bits_read(r, 8); + si->channels = 2; + si->block_pwr = 0; + +/* rockbox: not used + // convert gain info + if (si->gain_title != 0) { + int tmp = (int)((MPC_OLD_GAIN_REF - (mpc_int16_t)si->gain_title / 100.) * 256. + .5); + if (tmp >= (1 << 16) || tmp < 0) tmp = 0; + si->gain_title = (mpc_int16_t) tmp; } - /* - if ( !fp->seek ( si->header_position ) ) // seek to header start - return ERROR_CODE_FILE; - if ( fp->read ( HeaderData, sizeof HeaderData) != sizeof HeaderData ) - return ERROR_CODE_FILE; - */ + if (si->gain_album != 0) { + int tmp = (int)((MPC_OLD_GAIN_REF - (mpc_int16_t)si->gain_album / 100.) * 256. + .5); + if (tmp >= (1 << 16) || tmp < 0) tmp = 0; + si->gain_album = (mpc_int16_t) tmp; + } + + if (si->peak_title != 0) + si->peak_title = (mpc_uint16_t) (log10(si->peak_title) * 20 * 256 + .5); + + if (si->peak_album != 0) + si->peak_album = (mpc_uint16_t) (log10(si->peak_album) * 20 * 256 + .5); + + mpc_get_encoder_string(si); +*/ + + if (last_frame_samples == 0) last_frame_samples = MPC_FRAME_LENGTH; + si->samples = (mpc_int64_t) frames * MPC_FRAME_LENGTH; + if (si->is_true_gapless) + si->samples -= (MPC_FRAME_LENGTH - last_frame_samples); + else + si->samples -= MPC_DECODER_SYNTH_DELAY; + + si->average_bitrate = (si->tag_offset - si->header_position) * 8.0 + * si->sample_freq / si->samples; + + return check_streaminfo(si); +} + +/// Reads replay gain datas +void streaminfo_gain(mpc_streaminfo* si, const mpc_bits_reader * r_in) +{ + mpc_bits_reader r = *r_in; + + int version = mpc_bits_read(&r, 8); // gain version + if (version != 1) // we only know ver 1 + return; + si->gain_title = (mpc_uint16_t) mpc_bits_read(&r, 16); + si->peak_title = (mpc_uint16_t) mpc_bits_read(&r, 16); + si->gain_album = (mpc_uint16_t) mpc_bits_read(&r, 16); + si->peak_album = (mpc_uint16_t) mpc_bits_read(&r, 16); +} + +/// Reads streaminfo from SV8 header. +mpc_status +streaminfo_read_header_sv8(mpc_streaminfo* si, const mpc_bits_reader * r_in, + mpc_size_t block_size) +{ + mpc_uint32_t CRC; + mpc_bits_reader r = *r_in; + + CRC = (mpc_bits_read(&r, 16) << 16) | mpc_bits_read(&r, 16); + if (CRC != mpc_crc32(r.buff + 1 - (r.count >> 3), (int)block_size - 4)) + return MPC_STATUS_FILE; + + si->stream_version = mpc_bits_read(&r, 8); + if (si->stream_version != 8) + return MPC_STATUS_INVALIDSV; + + mpc_bits_get_size(&r, &si->samples); + mpc_bits_get_size(&r, &si->beg_silence); + + si->is_true_gapless = 1; + si->sample_freq = samplefreqs[mpc_bits_read(&r, 3)]; + si->max_band = mpc_bits_read(&r, 5) + 1; + si->channels = mpc_bits_read(&r, 4) + 1; + si->ms = mpc_bits_read(&r, 1); + si->block_pwr = mpc_bits_read(&r, 3) * 2; si->bitrate = 0; - si->frames = HeaderData[1]; - si->is = 0; - si->ms = (HeaderData[2] >> 30) & 0x0001; - si->max_band = (HeaderData[2] >> 24) & 0x003F; - si->block_size = 1; - si->profile = (HeaderData[2] << 8) >> 28; - si->profile_name = Stringify(si->profile); - si->sample_freq = samplefreqs[(HeaderData[2] >> 16) & 0x0003]; - Estimatedpeak_title = (mpc_uint16_t) (HeaderData[2] & 0xFFFF); // read the ReplayGain data - si->gain_title = (mpc_uint16_t) ((HeaderData[3] >> 16) & 0xFFFF); - si->peak_title = (mpc_uint16_t) (HeaderData[3] & 0xFFFF); - si->gain_album = (mpc_uint16_t) ((HeaderData[4] >> 16) & 0xFFFF); - si->peak_album = (mpc_uint16_t) (HeaderData[4] & 0xFFFF); - si->is_true_gapless = (HeaderData[5] >> 31) & 0x0001; // true gapless: used? - si->last_frame_samples = (HeaderData[5] >> 20) & 0x07FF; // true gapless: valid samples for last frame - si->encoder_version = (HeaderData[6] >> 24) & 0x00FF; - if (si->encoder_version == 0) { - //sprintf(si->encoder, "Buschmann 1.7.0...9, Klemm 0.90...1.05"); - } - else { - switch (si->encoder_version % 10) { - case 0: - //sprintf(si->encoder, "Release %u.%u", si->encoder_version / 100, - // si->encoder_version / 10 % 10); - break; - case 2: - case 4: - case 6: - case 8: - //sprintf(si->encoder, "Beta %u.%02u", si->encoder_version / 100, - // si->encoder_version % 100); - break; - default: - //sprintf(si->encoder, "--Alpha-- %u.%02u", - // si->encoder_version / 100, si->encoder_version % 100); - break; - } - } + if ((si->samples - si->beg_silence) != 0) + si->average_bitrate = (si->tag_offset - si->header_position) * 8.0 + * si->sample_freq / (si->samples - si->beg_silence); - // if ( si->peak_title == 0 ) // there is no correct peak_title contained within header - // si->peak_title = (mpc_uint16_t)(Estimatedpeak_title * 1.18); - // if ( si->peak_album == 0 ) - // si->peak_album = si->peak_title; // no correct peak_album, use peak_title - - //si->sample_freq = 44100; // AB: used by all files up to SV7 - si->channels = 2; - - return ERROR_CODE_OK; + return check_streaminfo(si); } -// read information from SV4-SV6 header -#ifdef MPC_SUPPORT_SV456 -static mpc_int32_t -streaminfo_read_header_sv6(mpc_streaminfo * si, mpc_uint32_t HeaderData[8]) +/// Reads encoder informations +void streaminfo_encoder_info(mpc_streaminfo* si, const mpc_bits_reader * r_in) { - //mpc_uint32_t HeaderData [8]; + mpc_bits_reader r = *r_in; - /* - if ( !fp->seek ( si->header_position ) ) // seek to header start - return ERROR_CODE_FILE; - if ( fp->read ( HeaderData, sizeof HeaderData ) != sizeof HeaderData ) - return ERROR_CODE_FILE; - */ + si->profile = mpc_bits_read(&r, 7) / 8.; +/* rockbox: not used + si->profile_name = mpc_get_version_string(si->profile); +*/ + si->pns = mpc_bits_read(&r, 1); + si->encoder_version = mpc_bits_read(&r, 8) << 24; // major + si->encoder_version |= mpc_bits_read(&r, 8) << 16; // minor + si->encoder_version |= mpc_bits_read(&r, 8) << 8; // build - si->bitrate = (HeaderData[0] >> 23) & 0x01FF; // read the file-header (SV6 and below) - si->is = (HeaderData[0] >> 22) & 0x0001; - si->ms = (HeaderData[0] >> 21) & 0x0001; - si->stream_version = (HeaderData[0] >> 11) & 0x03FF; - si->max_band = (HeaderData[0] >> 6) & 0x001F; - si->block_size = (HeaderData[0]) & 0x003F; - si->profile = 0; - si->profile_name = Stringify((mpc_uint32_t) (-1)); - if (si->stream_version >= 5) - si->frames = HeaderData[1]; // 32 bit - else - si->frames = (HeaderData[1] >> 16); // 16 bit - - si->gain_title = 0; // not supported - si->peak_title = 0; - si->gain_album = 0; - si->peak_album = 0; - - si->last_frame_samples = 0; - si->is_true_gapless = 0; - - si->encoder_version = 0; - si->encoder[0] = '\0'; - - if (si->stream_version == 7) - return ERROR_CODE_SV7BETA; // are there any unsupported parameters used? - if (si->bitrate != 0) - return ERROR_CODE_CBR; - if (si->is != 0) - return ERROR_CODE_IS; - if (si->block_size != 1) - return ERROR_CODE_BLOCKSIZE; - - if (si->stream_version < 6) // Bugfix: last frame was invalid for up to SV5 - si->frames -= 1; - - si->sample_freq = 44100; // AB: used by all files up to SV7 - si->channels = 2; - - if (si->stream_version < 4 || si->stream_version > 7) - return ERROR_CODE_INVALIDSV; - - return ERROR_CODE_OK; -} -#endif -// reads file header and tags -mpc_int32_t -mpc_streaminfo_read(mpc_streaminfo * si, mpc_reader * r) -{ - mpc_uint32_t HeaderData[8]; - mpc_int32_t Error = 0; - - // get header position - if ((si->header_position = JumpID3v2(r)) < 0) { - return ERROR_CODE_FILE; - } - // seek to first byte of mpc data - if (!r->seek(r->data, si->header_position)) { - return ERROR_CODE_FILE; - } - if (r->read(r->data, HeaderData, 8 * 4) != 8 * 4) { - return ERROR_CODE_FILE; - } - if (!r->seek(r->data, si->header_position + 6 * 4)) { - return ERROR_CODE_FILE; - } - - si->total_file_length = r->get_size(r->data); - si->tag_offset = si->total_file_length; - if (memcmp(HeaderData, "MP+", 3) == 0) { -#ifndef MPC_LITTLE_ENDIAN - mpc_uint32_t ptr; - for (ptr = 0; ptr < 8; ptr++) { - HeaderData[ptr] = mpc_swap32(HeaderData[ptr]); - } -#endif - si->stream_version = HeaderData[0] >> 24; - - // stream version 7 - if ((si->stream_version & 15) == 7) { - Error = streaminfo_read_header_sv7(si, HeaderData); - if (Error != ERROR_CODE_OK) return Error; - } else { - // only sv7 allowed with "MP+" signature - return ERROR_CODE_INVALIDSV; - } - } else if (memcmp(HeaderData, "MPCK", 4) == 0) { - // stream version 8 uses "MPCK" signature - return ERROR_CODE_INVALIDSV; - } else { -#ifdef MPC_SUPPORT_SV456 -#ifndef MPC_LITTLE_ENDIAN - mpc_uint32_t ptr; - for (ptr = 0; ptr < 8; ptr++) { - HeaderData[ptr] = mpc_swap32(HeaderData[ptr]); - } -#endif - // stream version 4-6 - Error = streaminfo_read_header_sv6(si, HeaderData); - if (Error != ERROR_CODE_OK) return Error; -#else - return ERROR_CODE_INVALIDSV; -#endif - } - - // estimation, exact value needs too much time - si->pcm_samples = 1152 * si->frames - 576; - - if (si->pcm_samples > 0) { - si->average_bitrate = - (si->tag_offset - - si->header_position) * 8.0 * si->sample_freq / si->pcm_samples; - } - else { - si->average_bitrate = 0; - } - - return ERROR_CODE_OK; +/* rockbox: not used + mpc_get_encoder_string(si); +*/ } +/* rockbox: not used double mpc_streaminfo_get_length(mpc_streaminfo * si) { - return (double)mpc_streaminfo_get_length_samples(si) / - (double)si->sample_freq; + return (double) (si->samples - si->beg_silence) / si->sample_freq; } -mpc_int64_t -mpc_streaminfo_get_length_samples(mpc_streaminfo * si) +mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si) { - mpc_int64_t samples = (mpc_int64_t) si->frames * MPC_FRAME_LENGTH; - if (si->is_true_gapless) { - samples -= (MPC_FRAME_LENGTH - si->last_frame_samples); - } - else { - samples -= MPC_DECODER_SYNTH_DELAY; - } - return samples; + return si->samples - si->beg_silence; } +*/ diff --git a/apps/codecs/libmusepack/streaminfo.h b/apps/codecs/libmusepack/streaminfo.h index 6c4b4ca108..739d40acf3 100644 --- a/apps/codecs/libmusepack/streaminfo.h +++ b/apps/codecs/libmusepack/streaminfo.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2005, The Musepack Development Team + Copyright (c) 2005-2009, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,11 +31,19 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - /// \file streaminfo.h +#ifndef _MPCDEC_STREAMINFO_H_ +#define _MPCDEC_STREAMINFO_H_ +#ifdef WIN32 +#pragma once +#endif + +#include "mpc_types.h" + +#ifdef __cplusplus +extern "C" { +#endif -#ifndef _mpcdec_streaminfo_h_ -#define _mpcdec_streaminfo_h_ typedef mpc_int32_t mpc_streaminfo_off_t; @@ -44,43 +52,63 @@ typedef mpc_int32_t mpc_streaminfo_off_t; /// Structure containing all the properties of an mpc stream. Populated /// by the streaminfo_read function. typedef struct mpc_streaminfo { - /// @name core mpc stream properties + /// @name Core mpc stream properties //@{ - mpc_uint32_t sample_freq; ///< sample frequency of stream - mpc_uint32_t channels; ///< number of channels in stream - mpc_streaminfo_off_t header_position; ///< byte offset of position of header in stream - mpc_uint32_t stream_version; ///< streamversion of stream - mpc_uint32_t bitrate; ///< bitrate of stream file (in bps) - double average_bitrate; ///< average bitrate of stream (in bits/sec) - mpc_uint32_t frames; ///< number of frames in stream - mpc_int64_t pcm_samples; - mpc_uint32_t max_band; ///< maximum band-index used in stream (0...31) - mpc_uint32_t is; ///< intensity stereo (0: off, 1: on) - mpc_uint32_t ms; ///< mid/side stereo (0: off, 1: on) - mpc_uint32_t block_size; ///< only needed for SV4...SV6 -> not supported - mpc_uint32_t profile; ///< quality profile of stream - const char* profile_name; ///< name of profile used by stream + mpc_uint32_t sample_freq; ///< Sample frequency of stream + mpc_uint32_t channels; ///< Number of channels in stream + mpc_uint32_t stream_version; ///< Streamversion of stream + mpc_uint32_t bitrate; ///< Bitrate of stream file (in bps) + double average_bitrate; ///< Average bitrate of stream (in bits/sec) + mpc_uint32_t max_band; ///< Maximum band-index used in stream (0...31) + mpc_uint32_t ms; ///< Mid/side stereo (0: off, 1: on) + mpc_uint32_t fast_seek; ///< True if stream supports fast-seeking (sv7) + mpc_uint32_t block_pwr; ///< Number of frames in a block = 2^block_pwr (sv8) //@} - /// @name replaygain related fields + /// @name Replaygain properties //@{ - mpc_int16_t gain_title; ///< replaygain title value - mpc_int16_t gain_album; ///< replaygain album value - mpc_uint16_t peak_album; ///< peak album loudness level - mpc_uint16_t peak_title; ///< peak title loudness level + mpc_uint16_t gain_title; ///< Replaygain title value + mpc_uint16_t gain_album; ///< Replaygain album value + mpc_uint16_t peak_album; ///< Peak album loudness level + mpc_uint16_t peak_title; ///< Peak title loudness level //@} - /// @name true gapless support data + /// @name True gapless properties //@{ - mpc_uint32_t is_true_gapless; ///< true gapless? (0: no, 1: yes) - mpc_uint32_t last_frame_samples; ///< number of valid samples within last frame - - mpc_uint32_t encoder_version; ///< version of encoder used - char encoder[256]; ///< encoder name - - mpc_streaminfo_off_t tag_offset; ///< offset to file tags - mpc_streaminfo_off_t total_file_length; ///< total length of underlying file + mpc_uint32_t is_true_gapless; ///< True gapless? (0: no, 1: yes) + mpc_uint64_t samples; ///< Number of samples in the stream + mpc_uint64_t beg_silence; ///< Number of samples that must not be played at the beginning of the stream //@} + + /// @name Encoder informations + //@{ + mpc_uint32_t encoder_version; ///< Version of encoder used +/* rockbox: not used + char encoder[256]; ///< Encoder name +*/ + mpc_bool_t pns; ///< pns used + float profile; ///< Quality profile of stream +/* rockbox: not used + const char* profile_name; ///< Name of profile used by stream +*/ + //@} + + + mpc_streaminfo_off_t header_position; ///< Byte offset of position of header in stream + mpc_streaminfo_off_t tag_offset; ///< Offset to file tags + mpc_streaminfo_off_t total_file_length; ///< Total length of underlying file } mpc_streaminfo; -#endif // _mpcdec_streaminfo_h_ +/* rockbox: not used +/// Gets length of stream si, in seconds. +/// \return length of stream in seconds +MPC_API double mpc_streaminfo_get_length(mpc_streaminfo *si); + +/// Returns length of stream si, in samples. +/// \return length of stream in samples +MPC_API mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si); +*/ +#ifdef __cplusplus +} +#endif +#endif diff --git a/apps/codecs/libmusepack/synth_filter.c b/apps/codecs/libmusepack/synth_filter.c index 587b88dada..b6caf4a3d7 100644 --- a/apps/codecs/libmusepack/synth_filter.c +++ b/apps/codecs/libmusepack/synth_filter.c @@ -35,9 +35,10 @@ /// \file synth_filter.c /// Synthesis functions. /// \todo document me - -#include "musepack.h" -#include "internal.h" +#include +#include "mpcdec.h" +#include "decoder.h" +#include "mpcdec_math.h" /* C O N S T A N T S */ #undef _ @@ -127,7 +128,7 @@ static const MPC_SAMPLE_FORMAT Di_opt [512] ICONST_ATTR = { *****************************************************************************/ void mpc_dct32(const MPC_SAMPLE_FORMAT *in, MPC_SAMPLE_FORMAT *v) -ICODE_ATTR_MPC_LARGE_IRAM; +ICODE_ATTR_MPC_LARGE_IRAM; void mpc_dct32(const MPC_SAMPLE_FORMAT *in, MPC_SAMPLE_FORMAT *v) @@ -548,27 +549,26 @@ mpc_full_synthesis_filter(MPC_SAMPLE_FORMAT *OutData, MPC_SAMPLE_FORMAT *V, cons mpc_dct32(Y, V); mpc_decoder_windowing_D( OutData, V, Di_opt ); } - } + } } void -mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT *OutData) +mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT *OutData, + int num_channels) { + (void)num_channels; + /********* left channel ********/ memmove(d->V_L + MPC_V_MEM, d->V_L, 960 * sizeof(MPC_SAMPLE_FORMAT) ); - - mpc_full_synthesis_filter( - OutData, - (MPC_SAMPLE_FORMAT *)(d->V_L + MPC_V_MEM), - (MPC_SAMPLE_FORMAT *)(d->Y_L [0])); + mpc_full_synthesis_filter(OutData, + (MPC_SAMPLE_FORMAT *)(d->V_L + MPC_V_MEM), + (MPC_SAMPLE_FORMAT *)(d->Y_L)); /******** right channel ********/ memmove(d->V_R + MPC_V_MEM, d->V_R, 960 * sizeof(MPC_SAMPLE_FORMAT) ); - - mpc_full_synthesis_filter( - (OutData == NULL ? NULL : OutData + MPC_FRAME_LENGTH), - (MPC_SAMPLE_FORMAT *)(d->V_R + MPC_V_MEM), - (MPC_SAMPLE_FORMAT *)(d->Y_R [0])); + mpc_full_synthesis_filter((OutData == NULL ? NULL : OutData + MPC_FRAME_LENGTH), + (MPC_SAMPLE_FORMAT *)(d->V_R + MPC_V_MEM), + (MPC_SAMPLE_FORMAT *)(d->Y_R)); } /*******************************************/ @@ -577,7 +577,7 @@ mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT *OutData) /* */ /*******************************************/ -static const unsigned char Parity [256] ICONST_ATTR = { // parity +static const unsigned char Parity [256] = { // parity 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, diff --git a/apps/codecs/libmusepack/synth_filter_arm.S b/apps/codecs/libmusepack/synth_filter_arm.S index 51526040ca..3f78469948 100644 --- a/apps/codecs/libmusepack/synth_filter_arm.S +++ b/apps/codecs/libmusepack/synth_filter_arm.S @@ -18,8 +18,6 @@ * KIND, either express or implied. * ****************************************************************************/ - -#include "mpc_config.h" .section .text, "ax", %progbits diff --git a/apps/codecs/mpc.c b/apps/codecs/mpc.c index 250a03fbfd..b9ae558c67 100644 --- a/apps/codecs/mpc.c +++ b/apps/codecs/mpc.c @@ -20,79 +20,81 @@ ****************************************************************************/ #include "codeclib.h" -#include +#include +#include CODEC_HEADER -mpc_decoder decoder IBSS_ATTR; +MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH] IBSS_ATTR; /* Our implementations of the mpc_reader callback functions. */ -static mpc_int32_t read_impl(void *data, void *ptr, mpc_int32_t size) +static mpc_int32_t read_impl(mpc_reader *reader, void *ptr, mpc_int32_t size) { - struct codec_api *ci = (struct codec_api *)data; - + struct codec_api *ci = (struct codec_api *)(reader->data); return ((mpc_int32_t)(ci->read_filebuf(ptr, size))); } -static mpc_bool_t seek_impl(void *data, mpc_int32_t offset) +static mpc_bool_t seek_impl(mpc_reader *reader, mpc_int32_t offset) { - struct codec_api *ci = (struct codec_api *)data; + struct codec_api *ci = (struct codec_api *)(reader->data); /* WARNING: assumes we don't need to skip too far into the past, this might not be supported by the buffering layer yet */ return ci->seek_buffer(offset); } -static mpc_int32_t tell_impl(void *data) +static mpc_int32_t tell_impl(mpc_reader *reader) { - struct codec_api *ci = (struct codec_api *)data; + struct codec_api *ci = (struct codec_api *)(reader->data); return ci->curpos; } -static mpc_int32_t get_size_impl(void *data) +static mpc_int32_t get_size_impl(mpc_reader *reader) { - struct codec_api *ci = (struct codec_api *)data; + struct codec_api *ci = (struct codec_api *)(reader->data); return ci->filesize; } -static mpc_bool_t canseek_impl(void *data) +static mpc_bool_t canseek_impl(mpc_reader *reader) { - (void)data; + (void)reader; /* doesn't much matter, libmusepack ignores this anyway */ return true; } -MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH] - IBSS_ATTR_MPC_SAMPLE_BUF; - /* this is the codec entry point */ enum codec_status codec_main(void) { mpc_int64_t samplesdone; uint32_t frequency; /* 0.1 kHz accuracy */ uint32_t elapsed_time; /* milliseconds */ - unsigned status; + mpc_status status; mpc_reader reader; mpc_streaminfo info; + mpc_frame_info frame; + mpc_demux *demux = NULL; int retval = CODEC_OK; + frame.buffer = sample_buffer; + /* musepack's sample representation is 18.14 * DSP_SET_SAMPLE_DEPTH = 14 (FRACT) + 16 (NATIVE) - 1 (SIGN) = 29 */ ci->configure(DSP_SET_SAMPLE_DEPTH, 29); /* Create a decoder instance */ - reader.read = read_impl; - reader.seek = seek_impl; - reader.tell = tell_impl; + reader.read = read_impl; + reader.seek = seek_impl; + reader.tell = tell_impl; reader.get_size = get_size_impl; - reader.canseek = canseek_impl; - reader.data = ci; + reader.canseek = canseek_impl; + reader.data = ci; next_track: - if (codec_init()) { + if (codec_init()) + { retval = CODEC_ERROR; goto exit; } @@ -102,42 +104,45 @@ next_track: samplesdone = ci->id3->offset; - /* read file's streaminfo data */ - mpc_streaminfo_init(&info); - if (mpc_streaminfo_read(&info, &reader) != ERROR_CODE_OK) { + /* initialize demux/decoder */ + demux = mpc_demux_init(&reader); + if (NULL == demux) + { retval = CODEC_ERROR; goto done; } + /* read file's streaminfo data */ + mpc_demux_get_info(demux, &info); + + frequency = info.sample_freq / 100; /* 0.1 kHz accuracy */ ci->configure(DSP_SWITCH_FREQUENCY, info.sample_freq); /* set playback engine up for correct number of channels */ /* NOTE: current musepack format only allows for stereo files but code is here to handle other configurations anyway */ - if (info.channels == 2) + if (info.channels == 2) ci->configure(DSP_SET_STEREO_MODE, STEREO_NONINTERLEAVED); else if (info.channels == 1) ci->configure(DSP_SET_STEREO_MODE, STEREO_MONO); - else { + else + { retval = CODEC_ERROR; goto done; } codec_set_replaygain(ci->id3); - /* instantiate a decoder with our file reader */ - mpc_decoder_setup(&decoder, &reader); - if (!mpc_decoder_initialize(&decoder, &info)) { - retval = CODEC_ERROR; - goto done; - } - + /* Resume to saved sample offset. */ if (samplesdone > 0) { /* hack to improve seek time if filebuf goes empty */ - if (mpc_decoder_seek_sample(&decoder, samplesdone)) { + if (mpc_demux_seek_sample(demux, samplesdone) == MPC_STATUS_OK) + { elapsed_time = (samplesdone*10)/frequency; ci->set_elapsed(elapsed_time); - } else { + } + else + { samplesdone = 0; } /* reset chunksize */ @@ -146,10 +151,12 @@ next_track: /* This is the decoding loop. */ do { /* Complete seek handler. */ - if (ci->seek_time) { + if (ci->seek_time) + { /* hack to improve seek time if filebuf goes empty */ mpc_int64_t new_offset = ((ci->seek_time - 1)/10)*frequency; - if (mpc_decoder_seek_sample(&decoder, new_offset)) { + if (mpc_demux_seek_sample(demux, new_offset) == MPC_STATUS_OK) + { samplesdone = new_offset; ci->set_elapsed(ci->seek_time); } @@ -159,24 +166,24 @@ next_track: if (ci->stop_codec || ci->new_track) break; - status = mpc_decoder_decode(&decoder, sample_buffer, NULL, NULL); + status = mpc_demux_decode(demux, &frame); ci->yield(); - if (status == 0) /* end of file reached */ + if (frame.bits == -1) /* decoding stopped */ + { + retval = (status == MPC_STATUS_OK) ? CODEC_OK : CODEC_ERROR; goto done; - if (status == (unsigned)(-1)) { /* decode error */ - retval = CODEC_ERROR; - goto done; - } else { - ci->pcmbuf_insert(sample_buffer, - sample_buffer + MPC_FRAME_LENGTH, - status); - samplesdone += status; + } + else + { + ci->pcmbuf_insert(frame.buffer, + frame.buffer + MPC_FRAME_LENGTH, + frame.samples); + samplesdone += frame.samples; elapsed_time = (samplesdone*10)/frequency; ci->set_elapsed(elapsed_time); ci->set_offset(samplesdone); } - } while (status != 0); - retval = CODEC_OK; + } while (true); done: if (ci->request_next_track()) diff --git a/apps/metadata/mpc.c b/apps/metadata/mpc.c index 3f8907a934..9894bb8b54 100644 --- a/apps/metadata/mpc.c +++ b/apps/metadata/mpc.c @@ -28,15 +28,27 @@ #include "logf.h" #include "replaygain.h" -static int set_replaygain(struct mp3entry* id3, bool album, long value, - long used) +#include "fixedpoint.h" +#include +#include +#include + +/* Needed for replay gain in sv8, please search MPC_OLD_GAIN_REF in libmusepack */ +#define SV8_TO_SV7_CONVERT_GAIN (64.82*100) + +static int set_replaygain_sv7(struct mp3entry* id3, + bool album, + long value, + long used) { long gain = (int16_t) ((value >> 16) & 0xffff); long peak = (uint16_t) (value & 0xffff); + /* Remark: mpc sv7 outputs peak as amplitude, not as dB. The following + * useage of peak is not correct and needs to be fixed. */ + /* We use a peak value of 0 to indicate a given gain type isn't used. */ - if (peak != 0) - { + if (peak != 0) { /* Use the Xing TOC field to store ReplayGain strings for use in the * ID3 screen, since Musepack files shouldn't need to use it in any * other way. @@ -48,9 +60,44 @@ static int set_replaygain(struct mp3entry* id3, bool album, long value, return used; } +static int set_replaygain_sv8(struct mp3entry* id3, + bool album, + long gain, + long peak, + long used) +{ + gain = (long)(SV8_TO_SV7_CONVERT_GAIN - (gain*100./256.)); + + /* We use a peak value of 0 to indicate a given gain type isn't used. */ + if (peak != 0) { + /* Use the Xing TOC field to store ReplayGain strings for use in the + * ID3 screen, since Musepack files shouldn't need to use it in any + * other way. + */ + used += parse_replaygain_int(album, gain * 512 / 100, peak << 9, + id3, id3->toc + used, sizeof(id3->toc) - used); + } + + return used; +} + +static int sv8_get_size(uint8_t *buffer, int index, uint64_t *p_size) +{ + unsigned char tmp; + uint64_t size = 0; + + do { + tmp = buffer[index++]; + size = (size << 7) | (tmp & 0x7F); + } while((tmp & 0x80)); + + *p_size = size; + return index; +} + bool get_musepack_metadata(int fd, struct mp3entry *id3) { - static const int32_t sfreqs_sv7[4] = { 44100, 48000, 37800, 32000 }; + static const int32_t sfreqs[4] = { 44100, 48000, 37800, 32000 }; uint32_t header[8]; uint64_t samples = 0; int i; @@ -63,7 +110,6 @@ bool get_musepack_metadata(int fd, struct mp3entry *id3) header[i] = letoh32(header[i]); if (!memcmp(header, "MP+", 3)) { /* Compare to sig "MP+" */ unsigned int streamversion; - header[0] = letoh32(header[0]); streamversion = (header[0] >> 24) & 15; if (streamversion == 7) { @@ -71,20 +117,78 @@ bool get_musepack_metadata(int fd, struct mp3entry *id3) unsigned int last_frame_samples = (header[5] >> 20) & 0x07ff; unsigned int bufused = 0; - id3->frequency = sfreqs_sv7[(header[2] >> 16) & 0x0003]; + id3->frequency = sfreqs[(header[2] >> 16) & 0x0003]; samples = (uint64_t)header[1]*1152; /* 1152 is mpc frame size */ if (gapless) samples -= 1152 - last_frame_samples; else samples -= 481; /* Musepack subband synth filter delay */ - bufused = set_replaygain(id3, false, header[3], bufused); - bufused = set_replaygain(id3, true, header[4], bufused); + bufused = set_replaygain_sv7(id3, false, header[3], bufused); + bufused = set_replaygain_sv7(id3, true , header[4], bufused); } else { return false; /* only SV7 is allowed within a "MP+" signature */ } - } else if (!memcmp(header, "MPCK", 4)) { /* Compare to sig "MPCK" */ - return false; /* SV8 is not supported yet */ + } else if (!memcmp(header, "MPCK", 4)) { /* Compare to sig "MPCK" */ + uint8_t sv8_header[32]; + /* 4 bytes 'MPCK' */ + lseek(fd, 4, SEEK_SET); + if (read(fd, sv8_header, 2) != 2) return false; /* read frame ID */ + if (!memcmp(sv8_header, "SH", 2)) { /* Stream Header ID */ + int32_t k = 0; + uint32_t streamversion; + uint64_t size = 0; + + /* 4 bytes 'MPCK' + 4 bytes crc + 2 'SH' */ + lseek(fd, 10, SEEK_SET); + if (read(fd, sv8_header, 32) != 32) return false; + + /* dummy read the correct amount of bits within the header data. */ + size = sv8_header[k++]; + + /* Read stream version */ + streamversion = sv8_header[k++]; + if (streamversion != 8) return false; /* Only SV8 is allowed. */ + + /* Number of samples */ + k = sv8_get_size(sv8_header, k, &samples); + + /* Number of leading zero-samples */ + k = sv8_get_size(sv8_header, k, &size); + + /* Sampling frequency */ + id3->frequency = sfreqs[(sv8_header[k++] >> 5) & 0x0003]; + + /* Number of channels */ + id3->channels = (sv8_header[k++] >> 4) + 1; + + if (!memcmp(sv8_header+k, "RG", 2)) { /* Replay Gain ID */ + long peak, gain; + int bufused = 0; + + k += 2; /* 2 bytes 'RG' */ + + /* sv8_get_size must be called to skip the right amount of + * bits within the header data. */ + k = sv8_get_size(sv8_header, k, &size); + + /* Read and set replay gain */ + if (sv8_header[k++] == 1) { + /* Title's peak and gain */ + gain = (int16_t) ((sv8_header[k]<<8) + sv8_header[k+1]); k += 2; + peak = (uint16_t)((sv8_header[k]<<8) + sv8_header[k+1]); k += 2; + bufused += set_replaygain_sv8(id3, false, gain, peak, bufused); + + /* Album's peak and gain */ + gain = (int16_t) ((sv8_header[k]<<8) + sv8_header[k+1]); k += 2; + peak = (uint16_t)((sv8_header[k]<<8) + sv8_header[k+1]); k += 2; + bufused += set_replaygain_sv8(id3, true , gain, peak, bufused); + } + } + } else { + /* No sv8 stream header found */ + return false; + } } else { return false; /* SV4-6 is not supported anymore */ } diff --git a/manual/appendix/file_formats.tex b/manual/appendix/file_formats.tex index 92e2a06713..a60e7fc08d 100644 --- a/manual/appendix/file_formats.tex +++ b/manual/appendix/file_formats.tex @@ -114,7 +114,7 @@ ADX & \fname{.adx} & \\ Advanced Audio Coding & \fname{.m4a, .m4b, .mp4} & \\ MPEG audio & \fname{.mp1, .mpa, .mp2, .mp3} & \\ - Musepack & \fname{.mpc} & Supports SV7 only \\ + Musepack & \fname{.mpc} & Supports SV7 and SV8 in mono/stereo \\ OGG/Vorbis & \fname{.ogg, .oga} & Some old ``floor 0'' files may crash Rockbox. \\ Sony Audio & \fname{.oma, .aa3} & \\ RealAudio & \fname{.rm, .ra, .rmvb} & \\