From b3d9578c27160280dc01350f6e7b87d0be53d70f Mon Sep 17 00:00:00 2001 From: Andree Buschmann Date: Sun, 7 Mar 2010 19:34:44 +0000 Subject: Major change to musepack decoder: Import v1.3.0 (r458 from svn.musepack.net) to rockbox. Several adaptions in the musepack decoder were made to get the library work and perform fast under rockbox on several targets. With this change mpc sv8 is supported, including seek, replay gain and metadata support. The decoding speed is a 1-4% lower than the last implementation. Reason for this is main restructuring in the bitstream demuxer. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25056 a1c6a512-1295-4272-9138-f99709370657 --- apps/codecs/libmusepack/AUTHORS | 2 +- apps/codecs/libmusepack/ChangeLog | 28 + apps/codecs/libmusepack/README | 6 - apps/codecs/libmusepack/README.rockbox | 27 - apps/codecs/libmusepack/SOURCES | 7 +- apps/codecs/libmusepack/config-mpc.h | 105 -- apps/codecs/libmusepack/config_types.h | 51 - apps/codecs/libmusepack/crc32.c | 56 + apps/codecs/libmusepack/decoder.h | 120 +- apps/codecs/libmusepack/huffman.c | 530 ++++++++ apps/codecs/libmusepack/huffman.h | 56 +- apps/codecs/libmusepack/huffsv46.c | 75 -- apps/codecs/libmusepack/huffsv7.c | 81 -- apps/codecs/libmusepack/idtag.c | 83 -- apps/codecs/libmusepack/internal.h | 90 +- apps/codecs/libmusepack/mainpage.h | 38 - apps/codecs/libmusepack/math.h | 237 ---- apps/codecs/libmusepack/minimax.h | 57 + apps/codecs/libmusepack/mpc_bits_reader.c | 179 +++ apps/codecs/libmusepack/mpc_bits_reader.h | 175 +++ apps/codecs/libmusepack/mpc_config.h | 50 - apps/codecs/libmusepack/mpc_decoder.c | 1979 +++++++--------------------- apps/codecs/libmusepack/mpc_demux.c | 666 ++++++++++ apps/codecs/libmusepack/mpc_types.h | 148 +++ apps/codecs/libmusepack/mpcdec.h | 186 +++ apps/codecs/libmusepack/mpcdec_math.h | 231 ++++ apps/codecs/libmusepack/musepack.h | 163 --- apps/codecs/libmusepack/reader.h | 66 +- apps/codecs/libmusepack/requant.c | 90 +- apps/codecs/libmusepack/requant.h | 36 +- apps/codecs/libmusepack/streaminfo.c | 392 +++--- apps/codecs/libmusepack/streaminfo.h | 94 +- apps/codecs/libmusepack/synth_filter.c | 34 +- apps/codecs/libmusepack/synth_filter_arm.S | 2 - apps/codecs/mpc.c | 109 +- apps/metadata/mpc.c | 126 +- manual/appendix/file_formats.tex | 2 +- 37 files changed, 3387 insertions(+), 2990 deletions(-) delete mode 100644 apps/codecs/libmusepack/README delete mode 100644 apps/codecs/libmusepack/README.rockbox delete mode 100644 apps/codecs/libmusepack/config-mpc.h delete mode 100644 apps/codecs/libmusepack/config_types.h create mode 100755 apps/codecs/libmusepack/crc32.c create mode 100755 apps/codecs/libmusepack/huffman.c delete mode 100644 apps/codecs/libmusepack/huffsv46.c delete mode 100644 apps/codecs/libmusepack/huffsv7.c delete mode 100644 apps/codecs/libmusepack/idtag.c delete mode 100644 apps/codecs/libmusepack/mainpage.h delete mode 100644 apps/codecs/libmusepack/math.h create mode 100755 apps/codecs/libmusepack/minimax.h create mode 100755 apps/codecs/libmusepack/mpc_bits_reader.c create mode 100755 apps/codecs/libmusepack/mpc_bits_reader.h delete mode 100644 apps/codecs/libmusepack/mpc_config.h create mode 100755 apps/codecs/libmusepack/mpc_demux.c create mode 100755 apps/codecs/libmusepack/mpc_types.h create mode 100755 apps/codecs/libmusepack/mpcdec.h create mode 100755 apps/codecs/libmusepack/mpcdec_math.h delete mode 100644 apps/codecs/libmusepack/musepack.h 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_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_uint64_t samples; ///< Number of samples in stream - 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_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_uint32_t __r1; + mpc_uint32_t __r2; + + mpc_int32_t SCF_Index_L [32] [3]; + mpc_int32_t SCF_Index_R [32] [3]; // holds scalefactor-indices + mpc_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 "mpc_types.h" -#include "config_types.h" -#include "decoder.h" +#ifdef __cplusplus +extern "C" { +#endif -struct mpc_decoder_t; // forward declare to break circular dependencies +// 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; + +/// 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); -#endif // _mpcdec_huffman_h_ +#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 - - -enum { - MPC_DECODER_SYNTH_DELAY = 481 -}; +#include "mpcdec.h" +/* rockbox: not used, rockbox's swap32 is used now. /// 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 +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)); + return (((val & 0xFF000000) >> 24) | ((val & 0x00FF0000) >> 8) + | ((val & 0x0000FF00) << 8) | ((val & 0x000000FF) << 24)); } -#endif +*/ +typedef struct mpc_block_t { + char key[2]; // block key + mpc_uint64_t size; // block size minus the block header size +} mpc_block; -#ifndef min -#define min(a, b) (((a) < (b)) ? (a) : (b)) -#endif +#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; -/// 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); + // 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 + +}; + +/** + * 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; +} /// 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/math.h b/apps/codecs/libmusepack/math.h deleted file mode 100644 index e4c2ffce20..0000000000 --- a/apps/codecs/libmusepack/math.h +++ /dev/null @@ -1,237 +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 math.h -/// Libmpcdec internal math routines. - -#ifndef _mpcdec_math_h_ -#define _mpcdec_math_h_ - -#include "mpc_config.h" - -#define MPC_FIXED_POINT_SHIFT 16 - -#ifdef MPC_FIXED_POINT - - #ifdef _WIN32_WCE - #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)<>Y) - - #if defined(CPU_COLDFIRE) - - #define MPC_MULTIPLY(X,Y) mpc_multiply((X), (Y)) - #define MPC_MULTIPLY_EX(X,Y,Z) mpc_multiply_ex((X), (Y), (Z)) - - static inline MPC_SAMPLE_FORMAT mpc_multiply(MPC_SAMPLE_FORMAT x, - MPC_SAMPLE_FORMAT y) - { - MPC_SAMPLE_FORMAT t1, t2; - asm volatile ( - "mac.l %[x],%[y],%%acc0\n" /* multiply */ - "mulu.l %[y],%[x] \n" /* get lower half, avoid emac stall */ - "movclr.l %%acc0,%[t1] \n" /* get higher half */ - "moveq.l #17,%[t2] \n" - "asl.l %[t2],%[t1] \n" /* hi <<= 17, plus one free */ - "moveq.l #14,%[t2] \n" - "lsr.l %[t2],%[x] \n" /* (unsigned)lo >>= 14 */ - "or.l %[x],%[t1] \n" /* combine result */ - : /* outputs */ - [t1]"=&d"(t1), - [t2]"=&d"(t2), - [x] "+d" (x) - : /* inputs */ - [y] "d" (y) - ); - return t1; - } - - static inline MPC_SAMPLE_FORMAT mpc_multiply_ex(MPC_SAMPLE_FORMAT x, - MPC_SAMPLE_FORMAT y, - unsigned shift) - { - MPC_SAMPLE_FORMAT t1, t2; - asm volatile ( - "mac.l %[x],%[y],%%acc0\n" /* multiply */ - "mulu.l %[y],%[x] \n" /* get lower half, avoid emac stall */ - "movclr.l %%acc0,%[t1] \n" /* get higher half */ - "moveq.l #31,%[t2] \n" - "sub.l %[sh],%[t2] \n" /* t2 = 31 - shift */ - "ble.s 1f \n" - "asl.l %[t2],%[t1] \n" /* hi <<= 31 - shift */ - "lsr.l %[sh],%[x] \n" /* (unsigned)lo >>= shift */ - "or.l %[x],%[t1] \n" /* combine result */ - "bra.s 2f \n" - "1: \n" - "neg.l %[t2] \n" /* t2 = shift - 31 */ - "asr.l %[t2],%[t1] \n" /* hi >>= t2 */ - "2: \n" - : /* outputs */ - [t1]"=&d"(t1), - [t2]"=&d"(t2), - [x] "+d" (x) - : /* inputs */ - [y] "d" (y), - [sh]"d" (shift) - ); - return t1; - } - #elif defined(CPU_ARM) - // borrowed and adapted from libMAD - #define MPC_MULTIPLY(X,Y) \ - ({ \ - MPC_SAMPLE_FORMAT low; \ - MPC_SAMPLE_FORMAT high; \ - asm volatile ( /* will calculate: result = (X*Y)>>14 */ \ - "smull %0,%1,%2,%3 \n\t" /* multiply with result %0 [0..31], %1 [32..63] */ \ - "mov %0, %0, lsr #14 \n\t" /* %0 = %0 >> 14 */ \ - "orr %0, %0, %1, lsl #18 \n\t"/* result = %0 OR (%1 << 18) */ \ - : "=&r"(low), "=&r" (high) \ - : "r"(X),"r"(Y)); \ - low; \ - }) - - // borrowed and adapted from libMAD - #define MPC_MULTIPLY_EX(X,Y,Z) \ - ({ \ - MPC_SAMPLE_FORMAT low; \ - MPC_SAMPLE_FORMAT high; \ - asm volatile ( /* will calculate: result = (X*Y)>>Z */ \ - "smull %0,%1,%2,%3 \n\t" /* multiply with result %0 [0..31], %1 [32..63] */ \ - "mov %0, %0, lsr %4 \n\t" /* %0 = %0 >> Z */ \ - "orr %0, %0, %1, lsl %5 \n\t" /* result = %0 OR (%1 << (32-Z)) */ \ - : "=&r"(low), "=&r" (high) \ - : "r"(X),"r"(Y),"r"(Z),"r"(32-Z)); \ - low; \ - }) - #else /* libmusepack standard */ - - #define MPC_MULTIPLY_NOTRUNCATE(X,Y) \ - (((MPC_SAMPLE_FORMAT_MULTIPLY)(X) * (MPC_SAMPLE_FORMAT_MULTIPLY)(Y)) >> MPC_FIXED_POINT_FRACTPART) - - #define MPC_MULTIPLY_EX_NOTRUNCATE(X,Y,Z) \ - (((MPC_SAMPLE_FORMAT_MULTIPLY)(X) * (MPC_SAMPLE_FORMAT_MULTIPLY)(Y)) >> (Z)) - - #ifdef _DEBUG - static inline MPC_SAMPLE_FORMAT MPC_MULTIPLY(MPC_SAMPLE_FORMAT item1,MPC_SAMPLE_FORMAT item2) - { - MPC_SAMPLE_FORMAT_MULTIPLY temp = MPC_MULTIPLY_NOTRUNCATE(item1,item2); - assert(temp == (MPC_SAMPLE_FORMAT_MULTIPLY)(MPC_SAMPLE_FORMAT)temp); - return (MPC_SAMPLE_FORMAT)temp; - } - - static inline MPC_SAMPLE_FORMAT MPC_MULTIPLY_EX(MPC_SAMPLE_FORMAT item1,MPC_SAMPLE_FORMAT item2,unsigned shift) - { - MPC_SAMPLE_FORMAT_MULTIPLY temp = MPC_MULTIPLY_EX_NOTRUNCATE(item1,item2,shift); - assert(temp == (MPC_SAMPLE_FORMAT_MULTIPLY)(MPC_SAMPLE_FORMAT)temp); - return (MPC_SAMPLE_FORMAT)temp; - } - #else - #define MPC_MULTIPLY(X,Y) ((MPC_SAMPLE_FORMAT)MPC_MULTIPLY_NOTRUNCATE(X,Y)) - #define MPC_MULTIPLY_EX(X,Y,Z) ((MPC_SAMPLE_FORMAT)MPC_MULTIPLY_EX_NOTRUNCATE(X,Y,Z)) - #endif - - #endif - - #ifdef MPC_HAVE_MULHIGH - #define MPC_MULTIPLY_FRACT(X,Y) _MulHigh(X,Y) - #else - #if defined(CPU_COLDFIRE) - /* loses one bit of accuracy. The rest of the macros won't be as easy as this... */ - #define MPC_MULTIPLY_FRACT(X,Y) \ - ({ \ - MPC_SAMPLE_FORMAT t; \ - asm volatile ( \ - "mac.l %[A], %[B], %%acc0\n\t" \ - "movclr.l %%acc0, %[t]\n\t" \ - "asr.l #1, %[t]\n\t" \ - : [t] "=d" (t) \ - : [A] "r" ((X)), [B] "r" ((Y))); \ - t; \ - }) - #elif defined(CPU_ARM) - // borrowed and adapted from libMAD - #define MPC_MULTIPLY_FRACT(X,Y) \ - ({ \ - MPC_SAMPLE_FORMAT low; \ - MPC_SAMPLE_FORMAT high; \ - asm volatile ( /* will calculate: result = (X*Y)>>32 */ \ - "smull %0,%1,%2,%3 \n\t" /* multiply with result %0 [0..31], %1 [32..63] */ \ - : "=&r"(low), "=&r" (high) /* result = %1 [32..63], saves the >>32 */ \ - : "r"(X),"r"(Y)); \ - high; \ - }) - #else - #define MPC_MULTIPLY_FRACT(X,Y) MPC_MULTIPLY_EX(X,Y,32) - #endif - #endif - - #define MPC_MAKE_FRACT_CONST(X) (MPC_SAMPLE_FORMAT)((X) * (double)(((mpc_int64_t)1)<<32) ) - - #define MPC_MULTIPLY_FLOAT_INT(X,Y) ((X)*(Y)) - -#else - //in floating-point mode, decoded samples are in -1...1 range - - typedef float MPC_SAMPLE_FORMAT; - - #define MAKE_MPC_SAMPLE(X) ((MPC_SAMPLE_FORMAT)(X)) - #define MAKE_MPC_SAMPLE_EX(X,Y) ((MPC_SAMPLE_FORMAT)(X)) - - #define MPC_MULTIPLY_FRACT(X,Y) ((X)*(Y)) - #define MPC_MAKE_FRACT_CONST(X) (X) - - #define MPC_MULTIPLY_FLOAT_INT(X,Y) ((X)*(Y)) - #define MPC_MULTIPLY(X,Y) ((X)*(Y)) - #define MPC_MULTIPLY_EX(X,Y,Z) ((X)*(Y)) - - #define MPC_SHR_RND(X, Y) (X) - -#endif - -#endif // _mpcdec_math_h_ - 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 +#include "mpcdec.h" +#include "minimax.h" +#include "decoder.h" +#include "huffman.h" #include "internal.h" +#include "mpcdec_math.h" #include "requant.h" -#include "huffman.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]; - - -#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]; - -#endif - -#ifndef MPC_LITTLE_ENDIAN -#define SWAP(X) mpc_swap32(X) -#else -#define SWAP(X) X -#endif - -#ifdef SCF_HACK -#define SCF_DIFF(SCF, D) (SCF == 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 +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; + +//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; + +//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}; + +//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) - }; - -//------------------------------------------------------------------------------ -// 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); - -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) { - count = f_read(d, ptr, count << 2) >> 2; - return count; -} + MEMSIZE = MPC_DECODER_MEMSIZE, // overall buffer size + MEMSIZE2 = (MEMSIZE/2), // size of one buffer + MEMMASK = (MEMSIZE-1) +}; //------------------------------------------------------------------------------ -// huffman & bitstream functions +// forward declarations //------------------------------------------------------------------------------ -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) -{ - d->dword = 0; - d->next = 0; - d->pos = 0; - d->Zaehler = 0; - d->WordsRead = 0; -} - -// reports the number of read bits -static mpc_uint32_t -mpc_decoder_bits_read(mpc_decoder *d) -{ - return 32 * d->WordsRead + d->pos; -} - -static void mpc_move_next(mpc_decoder *d) { - d->Zaehler = (d->Zaehler + 1) & MEMMASK; - d->dword = d->next; - d->next = SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]); - d->pos -= 32; - ++(d->WordsRead); -} - -// read desired number of bits out of the bitstream -static inline mpc_uint32_t -mpc_decoder_bitstream_read(mpc_decoder *d, const mpc_uint32_t bits) -{ - mpc_uint32_t out = d->dword; - - d->pos += bits; - - if (d->pos < 32) { - out >>= (32 - d->pos); - } - else { - mpc_move_next(d); - if (d->pos) { - out <<= d->pos; - out |= d->dword >> (32 - d->pos); - } - } - - 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) +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); + +/** + * set the scf indexes for seeking use + * needed only for sv7 seeking + * @param d + */ +void mpc_decoder_reset_scf(mpc_decoder * d, int value) { - // 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; + memset(d->SCF_Index_L, value, sizeof d->SCF_Index_L ); + memset(d->SCF_Index_R, value, sizeof d->SCF_Index_R ); } -#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) +void mpc_decoder_setup(mpc_decoder *d) { - // 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; -} + memset(d, 0, sizeof *d); -// 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; + d->__r1 = 1; + d->__r2 = 1; + d->Y_L = g_Y_L; + d->Y_R = g_Y_R; - if (d->pos > 27) { - code |= d->next >> (32 - d->pos); - } - while (code < Table->Code) { - Table++; - } + memset(d->Y_L, 0, sizeof(g_Y_L)); + memset(d->Y_R, 0, sizeof(g_Y_R)); - // set the new position within bitstream without performing a dummy-read - if ((d->pos += Table->Length) >= 32) { - mpc_move_next(d); - } - - return Table->Value; + mpc_decoder_init_quant(d, 1.0f); } -/* 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) +void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si) { - // 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); - } + 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; - return Table->Value; + 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; } -/* 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) +mpc_decoder * mpc_decoder_init(mpc_streaminfo *si) { - // load preview and decode - mpc_uint32_t code = d->dword << d->pos; + mpc_decoder* p_tmp = &g_mpc_decoder; - if (d->pos > unused_bits) { - code |= d->next >> (32 - d->pos); + if (p_tmp != 0) { + mpc_decoder_setup(p_tmp); + mpc_decoder_set_streaminfo(p_tmp, si); + huff_init_lut(LUT_DEPTH); } - 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 ); + return p_tmp; } -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) +void mpc_decoder_exit(mpc_decoder *d) { - 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); + (void)d; } -static mpc_uint32_t -mpc_decoder_decode_internal(mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer) +void mpc_decoder_decode_frame(mpc_decoder * d, + mpc_bits_reader * r, + mpc_frame_info * i) { - mpc_uint32_t output_frame_length = MPC_FRAME_LENGTH; - - mpc_uint32_t FrameBitCnt = 0; + mpc_bits_reader r_sav = *r; + mpc_int64_t samples_left; - // 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 - } + samples_left = d->samples - d->decoded_samples + MPC_DECODER_SYNTH_DELAY; - if (d->DecodedFrames == 0) - { - d->SeekTable[0] = mpc_decoder_bits_read(d); - d->SeekTableCounter = 0; + if (samples_left <= 0 && d->samples != 0) { + i->samples = 0; + i->bits = -1; + return; } - // 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); + if (d->stream_version == 8) { + mpc_decoder_read_bitstream_sv8(d, r, i->is_key_frame); + } else { + mpc_decoder_read_bitstream_sv7(d, r); } - 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; + 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); } - // 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; + d->decoded_samples += MPC_FRAME_LENGTH; - 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; + // 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; } } + 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; + mpc_int32_t n, idx, Max_used_Band = 0; - /************************ 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; + /***************************** Header *****************************/ - *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)]; + // first subband + 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 + 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); - // only perform the following procedure up to the maximum non-zero subband - if (*ResL || *ResR) Max_used_Band = n; + 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->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-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 ******************************/ + 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); } - /***************************** 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/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]; + 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; } - /************ 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; + Res = d->Res_R[n]; + SCFI = d->SCFI_R[n]; + } while ( SCF == d->SCF_Index_L[n] && (SCF = d->SCF_Index_R[n])); + } + +// if (d->seeking == TRUE) +// return; + + /***************************** Samples ****************************/ + 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; - } - } - } - 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]; + 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: - 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]; + 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: - 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; + 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; - } - } - /************ 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); + 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 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); + 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; - } - } - } - } - - /**************************** 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]; - } + Res = d->Res_R[n]; + } while (q == d->Q[n].L && (q = d->Q[n].R)); } } -#endif //MPC_SUPPORT_SV456 -/****************************************** SV 7 ******************************************/ -void -mpc_decoder_read_bitstream_sv7(mpc_decoder *d, mpc_bool_t fastSeeking) + +void mpc_decoder_read_bitstream_sv8(mpc_decoder * d, mpc_bits_reader * r, mpc_bool_t is_key_frame) { - 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, Max_used_Band; + const mpc_can_data * Table, * Tables[2]; /***************************** 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); + if (is_key_frame == MPC_TRUE) { + Max_used_Band = mpc_bits_log_dec(r, d->max_band + 1); } else { - d->MS_Flag[0] = 0; - } - - // 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); - - idx = mpc_decoder_huffman_decode_fast(d, mpc_table_HuffHdr); - *ResR = (idx!=4) ? *(ResR-1) + idx : (int) mpc_decoder_bitstream_read(d, 4); - - if (d->MS_used && !(*ResL==0 && *ResR==0)) { - d->MS_Flag[n] = mpc_decoder_bitstream_read(d, 1); + 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; } - // 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->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; + } } } - /****************************** 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); - } - /**************************** 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; - } - } - 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; - } + 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; } } - if (fastSeeking) - return; + /**************************** SCF/DSCF ****************************/ - /***************************** 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; - } - 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; + 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 { - Table = mpc_table_HuffQ[0][4]; - LUT = LUT4_0; - max_length = 4; + 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 (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( 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]; } - 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; - } - } -} - -void mpc_decoder_setup(mpc_decoder *d, mpc_reader *r) -{ - d->r = r; - - 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++; + 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])); } - 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; + /***************************** 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]; + } + } } - } - } - // 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); - } + Res = d->Res_R[n]; + } while (q == d->Q[n].L && (q = d->Q[n].R)); } - - 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); - - - } else { - - // DWORD aligned - f_seek(d, fpos*4 + d->MPCHeaderPos); - d->Zaehler = 0; - d->pos = bitPos & 31; - d->WordsRead = fpos; - - mpc_decoder_fill_buffer(d); - - } - -} - -void mpc_decoder_seek_forward(mpc_decoder *d, mpc_uint32_t bits) { - - bits += d->pos; - d->pos = bits & 31; - bits = bits >> 5; // to DWORDs - d->Zaehler = (d->Zaehler + bits) & MEMMASK; - d->dword = SWAP(d->Speicher[d->Zaehler]); - d->next = SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]); - d->WordsRead += bits; - } 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/mpcdec_math.h b/apps/codecs/libmusepack/mpcdec_math.h new file mode 100755 index 0000000000..55295dba32 --- /dev/null +++ b/apps/codecs/libmusepack/mpcdec_math.h @@ -0,0 +1,231 @@ +/* + 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 math.h +/// Libmpcdec internal math routines. + +#ifndef _mpcdec_math_h_ +#define _mpcdec_math_h_ + +#include "mpc_types.h" + +#define MPC_FIXED_POINT_SHIFT 16 + +#ifdef MPC_FIXED_POINT + + #ifdef _WIN32_WCE + #include + #define MPC_HAVE_MULHIGH + #endif + + typedef mpc_int64_t MPC_SAMPLE_FORMAT_MULTIPLY; + + #define MAKE_MPC_SAMPLE(X) (MPC_SAMPLE_FORMAT)((double)(X) * (double)(((mpc_int64_t)1)<>Y) + + #if defined(CPU_COLDFIRE) + + #define MPC_MULTIPLY(X,Y) mpc_multiply((X), (Y)) + #define MPC_MULTIPLY_EX(X,Y,Z) mpc_multiply_ex((X), (Y), (Z)) + + static inline MPC_SAMPLE_FORMAT mpc_multiply(MPC_SAMPLE_FORMAT x, + MPC_SAMPLE_FORMAT y) + { + MPC_SAMPLE_FORMAT t1, t2; + asm volatile ( + "mac.l %[x],%[y],%%acc0\n" /* multiply */ + "mulu.l %[y],%[x] \n" /* get lower half, avoid emac stall */ + "movclr.l %%acc0,%[t1] \n" /* get higher half */ + "moveq.l #17,%[t2] \n" + "asl.l %[t2],%[t1] \n" /* hi <<= 17, plus one free */ + "moveq.l #14,%[t2] \n" + "lsr.l %[t2],%[x] \n" /* (unsigned)lo >>= 14 */ + "or.l %[x],%[t1] \n" /* combine result */ + : /* outputs */ + [t1]"=&d"(t1), + [t2]"=&d"(t2), + [x] "+d" (x) + : /* inputs */ + [y] "d" (y) + ); + return t1; + } + + static inline MPC_SAMPLE_FORMAT mpc_multiply_ex(MPC_SAMPLE_FORMAT x, + MPC_SAMPLE_FORMAT y, + unsigned shift) + { + MPC_SAMPLE_FORMAT t1, t2; + asm volatile ( + "mac.l %[x],%[y],%%acc0\n" /* multiply */ + "mulu.l %[y],%[x] \n" /* get lower half, avoid emac stall */ + "movclr.l %%acc0,%[t1] \n" /* get higher half */ + "moveq.l #31,%[t2] \n" + "sub.l %[sh],%[t2] \n" /* t2 = 31 - shift */ + "ble.s 1f \n" + "asl.l %[t2],%[t1] \n" /* hi <<= 31 - shift */ + "lsr.l %[sh],%[x] \n" /* (unsigned)lo >>= shift */ + "or.l %[x],%[t1] \n" /* combine result */ + "bra.s 2f \n" + "1: \n" + "neg.l %[t2] \n" /* t2 = shift - 31 */ + "asr.l %[t2],%[t1] \n" /* hi >>= t2 */ + "2: \n" + : /* outputs */ + [t1]"=&d"(t1), + [t2]"=&d"(t2), + [x] "+d" (x) + : /* inputs */ + [y] "d" (y), + [sh]"d" (shift) + ); + return t1; + } + #elif defined(CPU_ARM) + // borrowed and adapted from libMAD + #define MPC_MULTIPLY(X,Y) \ + ({ \ + MPC_SAMPLE_FORMAT low; \ + MPC_SAMPLE_FORMAT high; \ + asm volatile ( /* will calculate: result = (X*Y)>>14 */ \ + "smull %0,%1,%2,%3 \n\t" /* multiply with result %0 [0..31], %1 [32..63] */ \ + "mov %0, %0, lsr #14 \n\t" /* %0 = %0 >> 14 */ \ + "orr %0, %0, %1, lsl #18 \n\t"/* result = %0 OR (%1 << 18) */ \ + : "=&r"(low), "=&r" (high) \ + : "r"(X),"r"(Y)); \ + low; \ + }) + + // borrowed and adapted from libMAD + #define MPC_MULTIPLY_EX(X,Y,Z) \ + ({ \ + MPC_SAMPLE_FORMAT low; \ + MPC_SAMPLE_FORMAT high; \ + asm volatile ( /* will calculate: result = (X*Y)>>Z */ \ + "smull %0,%1,%2,%3 \n\t" /* multiply with result %0 [0..31], %1 [32..63] */ \ + "mov %0, %0, lsr %4 \n\t" /* %0 = %0 >> Z */ \ + "orr %0, %0, %1, lsl %5 \n\t" /* result = %0 OR (%1 << (32-Z)) */ \ + : "=&r"(low), "=&r" (high) \ + : "r"(X),"r"(Y),"r"(Z),"r"(32-Z)); \ + low; \ + }) + #else /* libmusepack standard */ + + #define MPC_MULTIPLY_NOTRUNCATE(X,Y) \ + (((MPC_SAMPLE_FORMAT_MULTIPLY)(X) * (MPC_SAMPLE_FORMAT_MULTIPLY)(Y)) >> MPC_FIXED_POINT_FRACTPART) + + #define MPC_MULTIPLY_EX_NOTRUNCATE(X,Y,Z) \ + (((MPC_SAMPLE_FORMAT_MULTIPLY)(X) * (MPC_SAMPLE_FORMAT_MULTIPLY)(Y)) >> (Z)) + + #ifdef _DEBUG + static inline MPC_SAMPLE_FORMAT MPC_MULTIPLY(MPC_SAMPLE_FORMAT item1,MPC_SAMPLE_FORMAT item2) + { + MPC_SAMPLE_FORMAT_MULTIPLY temp = MPC_MULTIPLY_NOTRUNCATE(item1,item2); + assert(temp == (MPC_SAMPLE_FORMAT_MULTIPLY)(MPC_SAMPLE_FORMAT)temp); + return (MPC_SAMPLE_FORMAT)temp; + } + + static inline MPC_SAMPLE_FORMAT MPC_MULTIPLY_EX(MPC_SAMPLE_FORMAT item1,MPC_SAMPLE_FORMAT item2,unsigned shift) + { + MPC_SAMPLE_FORMAT_MULTIPLY temp = MPC_MULTIPLY_EX_NOTRUNCATE(item1,item2,shift); + assert(temp == (MPC_SAMPLE_FORMAT_MULTIPLY)(MPC_SAMPLE_FORMAT)temp); + return (MPC_SAMPLE_FORMAT)temp; + } + #else + #define MPC_MULTIPLY(X,Y) ((MPC_SAMPLE_FORMAT)MPC_MULTIPLY_NOTRUNCATE(X,Y)) + #define MPC_MULTIPLY_EX(X,Y,Z) ((MPC_SAMPLE_FORMAT)MPC_MULTIPLY_EX_NOTRUNCATE(X,Y,Z)) + #endif + + #endif + + #ifdef MPC_HAVE_MULHIGH + #define MPC_MULTIPLY_FRACT(X,Y) _MulHigh(X,Y) + #else + #if defined(CPU_COLDFIRE) + /* loses one bit of accuracy. The rest of the macros won't be as easy as this... */ + #define MPC_MULTIPLY_FRACT(X,Y) \ + ({ \ + MPC_SAMPLE_FORMAT t; \ + asm volatile ( \ + "mac.l %[A], %[B], %%acc0\n\t" \ + "movclr.l %%acc0, %[t]\n\t" \ + "asr.l #1, %[t]\n\t" \ + : [t] "=d" (t) \ + : [A] "r" ((X)), [B] "r" ((Y))); \ + t; \ + }) + #elif defined(CPU_ARM) + // borrowed and adapted from libMAD + #define MPC_MULTIPLY_FRACT(X,Y) \ + ({ \ + MPC_SAMPLE_FORMAT low; \ + MPC_SAMPLE_FORMAT high; \ + asm volatile ( /* will calculate: result = (X*Y)>>32 */ \ + "smull %0,%1,%2,%3 \n\t" /* multiply with result %0 [0..31], %1 [32..63] */ \ + : "=&r"(low), "=&r" (high) /* result = %1 [32..63], saves the >>32 */ \ + : "r"(X),"r"(Y)); \ + high; \ + }) + #else + #define MPC_MULTIPLY_FRACT(X,Y) MPC_MULTIPLY_EX(X,Y,32) + #endif + #endif + + #define MPC_MAKE_FRACT_CONST(X) (MPC_SAMPLE_FORMAT)((X) * (double)(((mpc_int64_t)1)<<32) ) + + #define MPC_MULTIPLY_FLOAT_INT(X,Y) ((X)*(Y)) + +#else + //in floating-point mode, decoded samples are in -1...1 range + + typedef float MPC_SAMPLE_FORMAT; + + #define MAKE_MPC_SAMPLE(X) ((MPC_SAMPLE_FORMAT)(X)) + #define MAKE_MPC_SAMPLE_EX(X,Y) ((MPC_SAMPLE_FORMAT)(X)) + + #define MPC_MULTIPLY_FRACT(X,Y) ((X)*(Y)) + #define MPC_MAKE_FRACT_CONST(X) (X) + + #define MPC_MULTIPLY_FLOAT_INT(X,Y) ((X)*(Y)) + #define MPC_MULTIPLY(X,Y) ((X)*(Y)) + #define MPC_MULTIPLY_EX(X,Y,Z) ((X)*(Y)) + + #define MPC_SHR_RND(X, Y) (X) + +#endif + +#endif // _mpcdec_math_h_ + diff --git a/apps/codecs/libmusepack/musepack.h b/apps/codecs/libmusepack/musepack.h deleted file mode 100644 index 1c98de654b..0000000000 --- a/apps/codecs/libmusepack/musepack.h +++ /dev/null @@ -1,163 +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 mpcdec.h -/// Top level include file for libmpcdec. - -#ifndef _mpcdec_h_ -#define _mpcdec_h_ - -#ifdef __cplusplus -extern "C" { -#endif - -//#include -#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 + +#include "mpc_types.h" -#ifndef _mpcdec_requant_h -#define _mpcdec_requant_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(Names) / sizeof(*Names) ? na : Names[profile]; + return profile >= sizeof versionNames / sizeof *versionNames ? na : versionNames[(int)profile]; } - -void -mpc_streaminfo_init(mpc_streaminfo * si) +*/ +/* rockbox: not used +static void +mpc_get_encoder_string(mpc_streaminfo* si) { - memset(si, 0, sizeof(mpc_streaminfo)); + 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--"; + + if (minor & 1) + tmp = "--Unstable--"; + + sprintf(si->encoder, "%s %u.%u.%u", tmp, major, minor, build); + } } +*/ -/// Reads streaminfo from SV7 header. -static mpc_int32_t -streaminfo_read_header_sv7(mpc_streaminfo * si, mpc_uint32_t HeaderData[8]) +static mpc_status check_streaminfo(mpc_streaminfo * si) { - const mpc_int32_t samplefreqs[4] = { 44100, 48000, 37800, 32000 }; + if (si->max_band == 0 || si->max_band >= 32 + || si->channels > 2) + return MPC_STATUS_FILE; + return MPC_STATUS_OK; +} - //mpc_uint32_t HeaderData [8]; +/// Reads streaminfo from SV7 header. +mpc_status +streaminfo_read_header_sv7(mpc_streaminfo* si, mpc_bits_reader * r) +{ mpc_uint16_t Estimatedpeak_title = 0; - - if (si->stream_version > 0x71) { - // Update (si->stream_version); - return 0; + mpc_uint32_t frames, last_frame_samples; + + 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; - */ - - 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->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 ( 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 + 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->sample_freq = 44100; // AB: used by all files up to SV7 - si->channels = 2; + si->average_bitrate = (si->tag_offset - si->header_position) * 8.0 + * si->sample_freq / si->samples; - 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 replay gain datas +void streaminfo_gain(mpc_streaminfo* si, const mpc_bits_reader * r_in) { - //mpc_uint32_t HeaderData [8]; - - /* - 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->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 + 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); +} - si->gain_title = 0; // not supported - si->peak_title = 0; - si->gain_album = 0; - si->peak_album = 0; +/// 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; - si->last_frame_samples = 0; - si->is_true_gapless = 0; + 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->encoder_version = 0; - si->encoder[0] = '\0'; + si->stream_version = mpc_bits_read(&r, 8); + if (si->stream_version != 8) + return MPC_STATUS_INVALIDSV; - 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; + mpc_bits_get_size(&r, &si->samples); + mpc_bits_get_size(&r, &si->beg_silence); - if (si->stream_version < 6) // Bugfix: last frame was invalid for up to SV5 - si->frames -= 1; + 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->sample_freq = 44100; // AB: used by all files up to SV7 - si->channels = 2; + si->bitrate = 0; - if (si->stream_version < 4 || si->stream_version > 7) - return ERROR_CODE_INVALIDSV; + 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); - return ERROR_CODE_OK; + return check_streaminfo(si); } -#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; +/// Reads encoder informations +void streaminfo_encoder_info(mpc_streaminfo* si, const mpc_bits_reader * r_in) +{ + mpc_bits_reader r = *r_in; - 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; - } + 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 - 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_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 + //@} - mpc_streaminfo_off_t tag_offset; ///< offset to file tags - mpc_streaminfo_off_t total_file_length; ///< total length of underlying file + /// @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 */ - goto done; - if (status == (unsigned)(-1)) { /* decode error */ - retval = CODEC_ERROR; + if (frame.bits == -1) /* decoding stopped */ + { + retval = (status == MPC_STATUS_OK) ? CODEC_OK : 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,48 @@ #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. + */ + used += parse_replaygain_int(album, gain * 512 / 100, peak << 9, + id3, id3->toc + used, sizeof(id3->toc) - used); + } + + 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. @@ -48,9 +81,23 @@ static int set_replaygain(struct mp3entry* id3, bool album, long value, 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} & \\ -- cgit v1.2.3