Add codecs to librbcodec.

Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
This commit is contained in:
Sean Bartell 2011-06-25 21:32:25 -04:00 committed by Nils Wallménius
parent a0009907de
commit f40bfc9267
757 changed files with 122 additions and 122 deletions

View file

@ -0,0 +1,10 @@
libmpcdec is the result of the work of many people:
* Andree Buschmann and Frank Klemm
Original implementation and core development.
* Peter Pawlowski and Benoit Amiaux
Portability and further optimizations.
* Miles Egan
Port to pure C, documentation, and api refinements.

View file

@ -0,0 +1,31 @@
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.

View file

@ -0,0 +1,40 @@
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 <mpcdec/stuff> 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
* switch to BSD license
* port to pure C
* add doxygen documentation
* revise API somewhat
1.0.3
* autotools build process
* sample binary added
* floating-point mode by default

View file

@ -0,0 +1,14 @@
crc32.c
huffman.c
mpc_bits_reader.c
mpc_decoder.c
mpc_demux.c
requant.c
streaminfo.c
synth_filter.c
#if defined(CPU_ARM)
synth_filter_arm.S
#endif
#if defined(CPU_COLDFIRE)
synth_filter_coldfire.S
#endif

View file

@ -0,0 +1,57 @@
/*
* C Implementation: crc32
*
* code from http://www.w3.org/TR/PNG/#D-CRCAppendix
*
*/
#include "internal.h"
/* 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;
}

View file

@ -0,0 +1,101 @@
/*
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 decoder.h
#ifndef _MPCDEC_DECODER_H_
#define _MPCDEC_DECODER_H_
#ifdef WIN32
#pragma once
#endif
#include "reader.h"
#ifdef __cplusplus
extern "C" {
#endif
#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
};
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_uint64_t samples; ///< Number of samples in stream
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_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?
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?
#ifdef MPC_FIXED_POINT
mpc_uint8_t SCF_shift[256];
#endif
MPC_SAMPLE_FORMAT *V_L;
MPC_SAMPLE_FORMAT *V_R;
MPC_SAMPLE_FORMAT *Y_L;
MPC_SAMPLE_FORMAT *Y_R;
mpc_uint32_t SCF[256]; ///< holds adapted scalefactors (for clipping prevention)
//@}
};
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,530 @@
/*
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 huffman.c
/// Implementations of sv7/sv8 huffman decoding functions.
#include "mpcdec.h"
#include "huffman.h"
// sv7 huffman tables
static const mpc_huffman mpc_table_HuffHdr [10] ICONST_ATTR = {
{0x8000, 1, 0}, {0x6000, 3, 1}, {0x5e00, 7,-4}, {0x5d80, 9, 3}, {0x5d00, 9, 4},
{0x5c00, 8,-5}, {0x5800, 6, 2}, {0x5000, 5,-3}, {0x4000, 4,-2}, {0x0000, 2,-1}
};
const mpc_huffman mpc_table_HuffSCFI [4] ICONST_ATTR = {
{0x8000, 1, 1}, {0x6000, 3, 2}, {0x4000, 3, 0}, {0x0000, 2, 3}
};
static const mpc_huffman mpc_table_HuffDSCF [16] ICONST_ATTR = {
{0xf800, 5, 5}, {0xf000, 5,-4}, {0xe000, 4, 3}, {0xd000, 4,-3},
{0xc000, 4, 8}, {0xa000, 3, 1}, {0x9000, 4, 0}, {0x8800, 5,-5},
{0x8400, 6, 7}, {0x8000, 6,-7}, {0x6000, 3,-1}, {0x4000, 3, 2},
{0x3000, 4, 4}, {0x2800, 5, 6}, {0x2000, 5,-6}, {0x0000, 3,-2}
};
static const mpc_huffman mpc_table_HuffQ1 [2] [27] ICONST_ATTR = {
{
{0xe000, 3, 13}, {0xdc00, 6, 26}, {0xd800, 6, 0},
{0xd400, 6, 20}, {0xd000, 6, 6}, {0xc000, 4, 14},
{0xb000, 4, 12}, {0xa000, 4, 4}, {0x9000, 4, 22},
{0x8c00, 6, 8}, {0x8800, 6, 18}, {0x8400, 6, 24},
{0x8000, 6, 2}, {0x7000, 4, 16}, {0x6000, 4, 10},
{0x5800, 5, 17}, {0x5000, 5, 9}, {0x4800, 5, 1},
{0x4000, 5, 25}, {0x3800, 5, 5}, {0x3000, 5, 21},
{0x2800, 5, 3}, {0x2000, 5, 11}, {0x1800, 5, 15},
{0x1000, 5, 23}, {0x0800, 5, 19}, {0x0000, 5, 7}
}, {
{0x8000, 1, 13}, {0x7e00, 7, 15}, {0x7c00, 7, 1},
{0x7a00, 7, 11}, {0x7800, 7, 7}, {0x7600, 7, 17},
{0x7400, 7, 25}, {0x7200, 7, 19}, {0x7180, 9, 8},
{0x7100, 9, 18}, {0x7080, 9, 2}, {0x7000, 9, 24},
{0x6e00, 7, 3}, {0x6c00, 7, 23}, {0x6a00, 7, 21},
{0x6800, 7, 5}, {0x6700, 8, 0}, {0x6600, 8, 26},
{0x6500, 8, 6}, {0x6400, 8, 20}, {0x6000, 6, 9},
{0x5000, 4, 14}, {0x4000, 4, 12}, {0x3000, 4, 4},
{0x2000, 4, 22}, {0x1000, 4, 16}, {0x0000, 4, 10}
}
};
static const mpc_huffman mpc_table_HuffQ2 [2] [25] ICONST_ATTR = {
{
{0xf000, 4, 13}, {0xe000, 4, 17}, {0xd000, 4, 7}, {0xc000, 4, 11}, {0xbc00, 6, 1},
{0xb800, 6, 23}, {0xb600, 7, 4}, {0xb400, 7, 20}, {0xb200, 7, 0}, {0xb000, 7, 24},
{0xa800, 5, 22}, {0xa000, 5, 10}, {0x8000, 3, 12}, {0x7800, 5, 2}, {0x7000, 5, 14},
{0x6000, 4, 6}, {0x5000, 4, 18}, {0x4000, 4, 8}, {0x3000, 4, 16}, {0x2800, 5, 9},
{0x2000, 5, 5}, {0x1800, 5, 15}, {0x1000, 5, 21}, {0x0800, 5, 19}, {0x0000, 5, 3}
}, {
{0xf800, 5, 18}, {0xf000, 5, 6}, {0xe800, 5, 8}, {0xe700, 8, 3}, {0xe6c0,10, 24},
{0xe680,10, 4}, {0xe640,10, 0}, {0xe600,10, 20}, {0xe400, 7, 23}, {0xe200, 7, 1},
{0xe000, 7, 19}, {0xd800, 5, 16}, {0xd600, 7, 15}, {0xd400, 7, 21}, {0xd200, 7, 9},
{0xd000, 7, 5}, {0xcc00, 6, 2}, {0xc800, 6, 10}, {0xc400, 6, 14}, {0xc000, 6, 22},
{0x8000, 2, 12}, {0x6000, 3, 13}, {0x4000, 3, 17}, {0x2000, 3, 11}, {0x0000, 3, 7}
}
};
static const mpc_huffman mpc_table_HuffQ3 [2] [7] ICONST_ATTR = {
{
{0xe000, 3, 1}, {0xd000, 4, 3}, {0xc000, 4,-3}, {0xa000, 3, 2},
{0x8000, 3,-2}, {0x4000, 2, 0}, {0x0000, 2,-1}
}, {
{0xc000, 2, 0}, {0x8000, 2,-1}, {0x4000, 2, 1}, {0x3000, 4,-2},
{0x2800, 5, 3}, {0x2000, 5,-3}, {0x0000, 3, 2}
}
};
static const mpc_huffman mpc_table_HuffQ4 [2] [9] ICONST_ATTR = {
{
{0xe000, 3, 0}, {0xc000, 3,-1}, {0xa000, 3, 1},
{0x8000, 3,-2}, {0x6000, 3, 2}, {0x5000, 4,-4},
{0x4000, 4, 4}, {0x2000, 3, 3}, {0x0000, 3,-3}
}, {
{0xe000, 3, 1}, {0xd000, 4, 2}, {0xc000, 4,-3},
{0x8000, 2, 0}, {0x6000, 3,-2}, {0x5000, 4, 3},
{0x4800, 5,-4}, {0x4000, 5, 4}, {0x0000, 2,-1}
}
};
static const mpc_huffman mpc_table_HuffQ5 [2] [15] ICONST_ATTR = {
{
{0xf000, 4, 2}, {0xe800, 5, 5}, {0xe400, 6,-7}, {0xe000, 6, 7}, {0xd000, 4,-3},
{0xc000, 4, 3}, {0xb800, 5,-6}, {0xb000, 5, 6}, {0xa000, 4,-4}, {0x9000, 4, 4},
{0x8000, 4,-5}, {0x6000, 3, 0}, {0x4000, 3,-1}, {0x2000, 3, 1}, {0x0000, 3,-2}
}, {
{0xf000, 4, 3}, {0xe800, 5, 4}, {0xe600, 7, 6}, {0xe500, 8,-7}, {0xe400, 8, 7},
{0xe000, 6,-6}, {0xc000, 3, 0}, {0xa000, 3,-1}, {0x8000, 3, 1}, {0x6000, 3,-2},
{0x4000, 3, 2}, {0x3800, 5,-5}, {0x3000, 5, 5}, {0x2000, 4,-4}, {0x0000, 3,-3}
}
};
static const mpc_huffman mpc_table_HuffQ6 [2] [31] ICONST_ATTR = {
{
{0xf800, 5, 3}, {0xf000, 5, -4}, {0xec00, 6,-11}, {0xe800, 6, 12}, {0xe000, 5, 4},
{0xd800, 5, 6}, {0xd000, 5, -5}, {0xc800, 5, 5}, {0xc000, 5, 7}, {0xb800, 5, -7},
{0xb400, 6,-12}, {0xb000, 6,-13}, {0xa800, 5, -6}, {0xa000, 5, 8}, {0x9800, 5, -8},
{0x9000, 5, 9}, {0x8800, 5, -9}, {0x8400, 6, 13}, {0x8200, 7,-15}, {0x8000, 7, 15},
{0x7000, 4, 0}, {0x6800, 5,-10}, {0x6000, 5, 10}, {0x5000, 4, -1}, {0x4000, 4, 2},
{0x3000, 4, 1}, {0x2000, 4, -2}, {0x1c00, 6, 14}, {0x1800, 6,-14}, {0x1000, 5, 11},
{0x0000, 4, -3}
}, {
{0xf800, 5, -6}, {0xf000, 5, 6}, {0xe000, 4, 1}, {0xd000, 4, -1}, {0xce00, 7, 10},
{0xcc00, 7,-10}, {0xcb00, 8,-11}, {0xca80, 9,-12}, {0xca60,11, 13}, {0xca58,13, 15},
{0xca50,13,-14}, {0xca48,13, 14}, {0xca40,13,-15}, {0xca00,10,-13}, {0xc900, 8, 11},
{0xc800, 8, 12}, {0xc400, 6, -9}, {0xc000, 6, 9}, {0xb000, 4, -2}, {0xa000, 4, 2},
{0x9000, 4, 3}, {0x8000, 4, -3}, {0x7800, 5, -7}, {0x7000, 5, 7}, {0x6000, 4, -4},
{0x5000, 4, 4}, {0x4800, 5, -8}, {0x4000, 5, 8}, {0x3000, 4, 5}, {0x2000, 4, -5},
{0x0000, 3, 0}
}
};
static const mpc_huffman mpc_table_HuffQ7 [2] [63] ICONST_ATTR = {
{
{0xfc00, 6, 7}, {0xf800, 6, 8}, {0xf400, 6, 9}, {0xf000, 6, -8}, {0xec00, 6, 11},
{0xea00, 7, 21}, {0xe900, 8,-28}, {0xe800, 8, 28}, {0xe400, 6, -9}, {0xe200, 7,-22},
{0xe000, 7,-21}, {0xdc00, 6,-10}, {0xd800, 6,-11}, {0xd400, 6, 10}, {0xd000, 6, 12},
{0xcc00, 6,-13}, {0xca00, 7, 22}, {0xc800, 7, 23}, {0xc400, 6,-12}, {0xc000, 6, 13},
{0xbc00, 6, 14}, {0xb800, 6,-14}, {0xb600, 7,-23}, {0xb500, 8,-29}, {0xb400, 8, 29},
{0xb000, 6,-15}, {0xac00, 6, 15}, {0xa800, 6, 16}, {0xa400, 6,-16}, {0xa200, 7,-24},
{0xa000, 7, 24}, {0x9c00, 6, 17}, {0x9a00, 7,-25}, {0x9900, 8,-30}, {0x9800, 8, 30},
{0x9400, 6,-17}, {0x9000, 6, 18}, {0x8c00, 6,-18}, {0x8a00, 7, 25}, {0x8800, 7, 26},
{0x8400, 6, 19}, {0x8200, 7,-26}, {0x8000, 7,-27}, {0x7800, 5, 2}, {0x7400, 6,-19},
{0x7000, 6, 20}, {0x6800, 5, -1}, {0x6700, 8,-31}, {0x6600, 8, 31}, {0x6400, 7, 27},
{0x6000, 6,-20}, {0x5800, 5, 1}, {0x5000, 5, -5}, {0x4800, 5, -3}, {0x4000, 5, 3},
{0x3800, 5, 0}, {0x3000, 5, -2}, {0x2800, 5, -4}, {0x2000, 5, 4}, {0x1800, 5, 5},
{0x1000, 5, -6}, {0x0800, 5, 6}, {0x0000, 5, -7}
}, {
{0xf800, 5, -1}, {0xf000, 5, 2}, {0xe800, 5, -2}, {0xe000, 5, 3}, {0xdf00, 8,-20},
{0xdec0,10, 24}, {0xdebc,14, 28}, {0xdeb8,14,-28}, {0xdeb4,14,-30}, {0xdeb0,14, 30},
{0xdea0,12,-27}, {0xde9c,14, 29}, {0xde98,14,-29}, {0xde94,14, 31}, {0xde90,14,-31},
{0xde80,12, 27}, {0xde00, 9,-22}, {0xdc00, 7,-17}, {0xd800, 6,-11}, {0xd000, 5, -3},
{0xc800, 5, 4}, {0xc000, 5, -4}, {0xbe00, 7, 17}, {0xbd00, 8, 20}, {0xbc80, 9, 22},
{0xbc40,10,-25}, {0xbc00,10,-26}, {0xb800, 6, 12}, {0xb000, 5, 5}, {0xa800, 5, -5},
{0xa000, 5, 6}, {0x9800, 5, -6}, {0x9400, 6,-12}, {0x9200, 7,-18}, {0x9000, 7, 18},
{0x8c00, 6, 13}, {0x8800, 6,-13}, {0x8000, 5, -7}, {0x7c00, 6, 14}, {0x7b00, 8, 21},
{0x7a00, 8,-21}, {0x7800, 7,-19}, {0x7000, 5, 7}, {0x6800, 5, 8}, {0x6400, 6,-14},
{0x6000, 6,-15}, {0x5800, 5, -8}, {0x5400, 6, 15}, {0x5200, 7, 19}, {0x51c0,10, 25},
{0x5180,10, 26}, {0x5100, 9,-23}, {0x5080, 9, 23}, {0x5000, 9,-24}, {0x4800, 5,-9},
{0x4000, 5, 9}, {0x3c00, 6, 16}, {0x3800, 6,-16}, {0x3000, 5, 10}, {0x2000, 4, 0},
{0x1800, 5,-10}, {0x1000, 5, 11}, {0x0000, 4, 1}
}
};
// sv8 huffman tables
static const mpc_huffman mpc_huff_SCFI_1 [3] ICONST_ATTR = {
{0x8000, 1, 1}, {0x4000, 2, 2}, {0x0, 3, 3}
}; // 3
static const mpc_int8_t mpc_sym_SCFI_1 [4] ICONST_ATTR = {
2, 3, 1, 0
};
static const mpc_huffman mpc_huff_SCFI_2 [5] ICONST_ATTR = {
{0x8000, 2, 3}, {0x4000, 3, 5}, {0x1800, 5, 11}, {0x400, 6, 14}, {0x0, 7, 15}
}; // 5
static const mpc_int8_t mpc_sym_SCFI_2 [16] ICONST_ATTR = {
15, 10, 14, 11, 13, 9, 7, 6, 5, 12, 8, 3, 2, 0, 4, 1
};
static const mpc_huffman mpc_huff_DSCF_1 [12] ICONST_ATTR = {
{0xa000, 3, 7}, {0x4000, 4, 12}, {0x2800, 5, 16}, {0x1800, 6, 21},
{0x0e00, 7, 27}, {0x0700, 8, 34}, {0x0380, 9, 41}, {0x0140, 10, 48},
{0x0080, 11, 53}, {0x0030, 12, 57}, {0x0018, 13, 60}, {0x0000, 14, 63}
}; // 12
static const mpc_int8_t mpc_sym_DSCF_1 [64] ICONST_ATTR = {
35, 34, 33, 36, 32, 30, 29, 27, 26, 37, 28, 25, 39, 38, 24, 23,
40, 22, 21, 20, 19, 43, 42, 41, 18, 17, 16, 15, 46, 45, 44, 14,
13, 12, 11, 49, 48, 47, 31, 10, 9, 8, 7, 6, 52, 51, 50, 5,
4, 3, 54, 53, 2, 1, 0, 57, 56, 55, 63, 62, 61, 60, 59, 58
};
static const mpc_huffman mpc_huff_DSCF_2 [13] ICONST_ATTR = {
{0x6000, 3, 7}, {0x3000, 4, 10}, {0x1800, 5, 13}, {0x1000, 6, 16},
{0x0a00, 7, 20}, {0x0600, 8, 25}, {0x0380, 9, 31}, {0x01c0, 10, 38},
{0x00e0, 11, 45}, {0x0050, 12, 52}, {0x0020, 13, 57}, {0x000c, 14, 61},
{0x0000, 15, 64}
}; // 13
static const mpc_int8_t mpc_sym_DSCF_2 [65] ICONST_ATTR = {
33, 32, 31, 30, 29, 34, 28, 27, 36, 35, 26, 37, 25, 38, 24, 23,
40, 39, 22, 21, 42, 41, 20, 19, 18, 45, 44, 43, 17, 16, 15, 14,
48, 47, 46, 13, 12, 11, 10, 64, 52, 51, 50, 49, 9, 8, 7, 6,
55, 54, 53, 5, 4, 3, 58, 57, 56, 2, 1, 63, 62, 61, 60, 59,
0
};
static const mpc_huffman mpc_huff_Bands [12] ICONST_ATTR = {
{0x8000, 1, 1}, {0x4000, 2, 2}, {0x2000, 3, 3}, {0x1000, 5, 6},
{0x0800, 6, 8}, {0x0600, 7, 10}, {0x0300, 8, 13}, {0x0200, 9, 16},
{0x0140, 10, 20}, {0x00c0, 11, 25}, {0x0010, 12, 31}, {0x0000, 13, 32}
}; // 12
static const mpc_int8_t mpc_sym_Bands [33] ICONST_ATTR = {
0, 32, 1, 31, 2, 30, 3, 4, 29, 6, 5, 28, 7, 27, 26, 8,
25, 24, 23, 9, 22, 21, 20, 18, 17, 16, 15, 14, 12, 11, 10, 19,
13
};
static const mpc_huffman mpc_huff_Res_1 [16] ICONST_ATTR = {
{0x8000, 1, 1}, {0x4000, 2, 2}, {0x2000, 3, 3}, {0x1000, 4, 4},
{0x0800, 5, 5}, {0x0400, 6, 6}, {0x0200, 7, 7}, {0x0100, 8, 8},
{0x0080, 9, 9}, {0x0040, 10, 10}, {0x0020, 11, 11}, {0x0010, 12, 12},
{0x0008, 13, 13}, {0x0004, 14, 14}, {0x0002, 15, 15}, {0x0000, 16, 16}
}; // 16
static const mpc_int8_t mpc_sym_Res_1 [17] ICONST_ATTR = {
0, 1, 16, 2, 3, 4, 5, 15, 6, 7, 8, 9, 10, 11, 12, 14, 13
};
static const mpc_huffman mpc_huff_Res_2 [12] ICONST_ATTR = {
{0x4000, 2, 3}, {0x2000, 3, 4}, {0x1000, 4, 5}, {0x0800, 5, 6},
{0x0400, 6, 7}, {0x0200, 7, 8}, {0x0100, 8, 9}, {0x0080, 9, 10},
{0x0040, 10, 11}, {0x0020, 11, 12}, {0x0010, 12, 13}, {0x0000, 14, 16}
}; // 12
static const mpc_int8_t mpc_sym_Res_2 [17] ICONST_ATTR = {
16, 1, 0, 2, 15, 3, 14, 4, 5, 13, 6, 12, 7, 11, 10, 9, 8
};
static const mpc_huffman mpc_huff_Q1 [10] ICONST_ATTR = {
{0x6000, 3, 7}, {0x1000, 4, 10}, {0x0800, 5, 11}, {0x0400, 6, 12},
{0x0200, 7, 13}, {0x0100, 8, 14}, {0x0080, 9, 15}, {0x0040, 10, 16},
{0x0020, 11, 17}, {0x0000, 12, 18}
}; // 10
static const mpc_int8_t mpc_sym_Q1 [19] ICONST_ATTR = {
7, 6, 5, 4, 3, 10, 9, 8, 2, 1, 11, 0, 12, 13, 14, 15, 16, 18, 17
};
static const mpc_huffman mpc_huff_Q2_1 [10] ICONST_ATTR = {
{0xe000, 3, 7}, {0x8000, 4, 14}, {0x3c00, 6, 38}, {0x2a00, 7, 53},
{0x1200, 8, 74}, {0x0600, 9, 92}, {0x03c0, 10,104}, {0x0060, 11,119},
{0x0020, 12,122}, {0x0000, 13,124}
}; // 10
static const mpc_int8_t mpc_sym_Q2_1 [125] ICONST_ATTR = {
62, 87, 67, 63, 61, 57, 37, 93, 92, 88, 86, 83, 82, 81, 68, 66, 58, 56, 42, 41, 38, 36, 32, 31,112,
91, 72, 64, 60, 52, 43, 33, 12,117,113,111,107, 97, 89, 85, 77, 73, 71, 69, 65, 59, 55, 53, 51, 47,
39, 35, 27, 17, 13, 11, 7,118,116,108,106, 98, 96, 94, 90, 84, 80, 78, 76, 48, 46, 44, 40, 34, 30,
28, 26, 18, 16, 8, 6,122,110,102, 74, 70, 54, 50, 22, 2,123,121,119,115,114,109,105,103,101, 99,
95, 79, 75, 49, 45, 29, 25, 23, 21, 19, 15, 14, 10, 9, 5, 3, 1,124,104, 20, 0,120,100, 24, 4
};
static const mpc_huffman mpc_huff_Q2_2 [9] ICONST_ATTR = {
{0xf000, 4, 15}, {0x7000, 5, 30}, {0x4800, 6, 44},
{0x3c00, 7, 62}, {0x0c00, 8, 92}, {0x0780, 9,104},
{0x00c0, 10,119}, {0x0040, 11,122}, {0x0000, 12,124}
}; // 9
static const mpc_int8_t mpc_sym_Q2_2 [125] ICONST_ATTR = {
62, 92, 87, 86, 82, 68, 67, 66, 63, 61, 58, 57, 56, 42, 38, 37, 32, 93, 91, 88, 83, 81, 43, 41, 36,
33, 31,112, 72, 64, 60, 52, 12,118,117,116,113,111,108,107,106, 98, 97, 96, 94, 90, 89, 85, 84, 80,
78, 77, 76, 73, 71, 69, 65, 59, 55, 53, 51, 48, 47, 46, 44, 40, 39, 35, 34, 30, 28, 27, 26, 18, 17,
16, 13, 11, 8, 7, 6,122,110, 74, 70, 54, 50, 22, 14, 2,123,121,119,115,114,109,105,103,102,101,
99, 95, 79, 75, 49, 45, 29, 25, 23, 21, 19, 15, 10, 9, 5, 3, 1,124,104, 20, 0,120,100, 24, 4
};
static const mpc_huffman mpc_huff_Q3 [7] ICONST_ATTR = {
{0xe000, 3, 7}, {0x8000, 4, 14}, {0x5000, 5, 22}, {0x2400, 6, 32},
{0x0a00, 7, 41}, {0x0200, 8, 46}, {0x0000, 9, 48}
}; // 7
static const mpc_int8_t mpc_sym_Q3 [49] ICONST_ATTR = {
0, 17, 16, 1, 15,-16, -1,
32, 31, 2, 14,-15,-32, 34,
33, 47, 46, 18, 30,-14, -2,
-31,-17,-18, 49, 48, 63, 19,
29, 3, 13,-13, -3,-30,-47,
-48,-33, 50, 62, 35, 45,-29,
-19,-46,-34, 51, 61,-45,-35
};
static const mpc_huffman mpc_huff_Q4 [8] ICONST_ATTR = {
{0xf000, 4, 15}, {0x9000, 5, 30}, {0x3400, 6, 48}, {0x1800, 7, 61},
{0x0500, 8, 73}, {0x0100, 9, 78}, {0x0000, 10, 80}, {0x0000, 0, 90}
}; // 8
static const mpc_int8_t mpc_sym_Q4 [91] ICONST_ATTR = {
0, 32, 17, 16, 31, 2, 1, 15, 14,-15,-16, -1,-32, 49, 48,
34, 33, 47, 46, 19, 18, 30, 29, 3, 13,-13,-14, -2, -3,-30,
-31,-17,-18,-47,-48,-33, 64, 50, 63, 62, 35, 45, 4, 12,-29,
-19,-46,-34,-64,-49, 66, 65, 79, 78, 51, 61, 36, 44, 20, 28,
-12, -4,-28,-20,-45,-35,-62,-63,-50, 67, 77, 52, 60,-44,-36,
-61,-51, 68, 76,-60,-52, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0
};
static const mpc_huffman mpc_huff_Q5_1 [6] ICONST_ATTR = {
{0xc000, 2, 3}, {0x4000, 3, 6}, {0x2000, 4, 8},
{0x1000, 5, 10}, {0x0800, 6, 12}, {0x0000, 7, 14}
}; // 6
static const mpc_int8_t mpc_sym_Q5_1 [15] ICONST_ATTR = {
0, 2, 1, -1, -2, 3, -3, 4, -4, 5, -5, 7, 6, -6, -7
};
static const mpc_huffman mpc_huff_Q5_2 [4] ICONST_ATTR = {
{0x6000, 3, 7}, {0x2000, 4, 10}, {0x1000, 5, 12}, {0x0, 6, 14}
}; // 4
static const mpc_int8_t mpc_sym_Q5_2 [15] ICONST_ATTR = {
2, 1, 0, -1, -2, 4, 3, -3, -4, 5, -5, 7, 6, -6, -7
};
static const mpc_huffman mpc_huff_Q6_1 [8] ICONST_ATTR = {
{0xc000, 2, 3}, {0x8000, 3, 6}, {0x4000, 4, 10}, {0x2800, 5, 14},
{0x0c00, 6, 19}, {0x0800, 7, 22}, {0x0400, 8, 26}, {0x0000, 9, 30}
}; // 8
static const mpc_int8_t mpc_sym_Q6_1 [31] ICONST_ATTR = {
0, 1, -1, 3, 2, -2, -3, 4, -4, -5, 8, 7, 6, 5, -6,
-7, -8, 9, -9, 11, 10,-10,-11, 15, 14, 13, 12,-12,-13,-14,
-15
};
static const mpc_huffman mpc_huff_Q6_2 [5] ICONST_ATTR = {
{0x5000, 4, 15}, {0x2000, 5, 20}, {0x1000, 6, 24}, {0x400, 7, 28}, {0x0, 8, 30}
}; // 5
static const mpc_int8_t mpc_sym_Q6_2 [31] ICONST_ATTR = {
5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, 8, 7, 6, -6,
-7, -8, 10, 9, -9,-10, 13, 12, 11,-11,-12,-13, 15, 14,-14,
-15
};
static const mpc_huffman mpc_huff_Q7_1 [9] ICONST_ATTR_MPC_LARGE_IRAM = {
{0xc000, 2, 3}, {0x8000, 3, 6}, {0x6000, 4, 10},
{0x4000, 5, 16}, {0x2800, 6, 24}, {0x1400, 7, 34},
{0x0a00, 8, 44}, {0x0400, 9, 54}, {0x0000, 10, 62}
}; // 9
static const mpc_int8_t mpc_sym_Q7_1 [63] ICONST_ATTR_MPC_LARGE_IRAM = {
0, 1, -1, 2, -2, 4, 3, -3, -4, 7, 6, 5, -5, -6, -7,
13, 11, 10, 9, 8, -8, -9,-10,-11,-12, 17, 16, 15, 14, 12,
-13,-14,-15,-16,-17, 28, 27, 21, 20, 19, 18,-18,-19,-20,-21,
-27,-28, 31, 30, 29, 26, 25, 24, 23, 22,-22,-23,-24,-25,-26,
-29,-30,-31
};
static const mpc_huffman mpc_huff_Q7_2 [5] ICONST_ATTR_MPC_LARGE_IRAM = {
{0x6000, 5, 31}, {0x2400, 6, 43}, {0x1000, 7, 52}, {0x200, 8, 60}, {0x0, 9, 62}
}; // 5
static const mpc_int8_t mpc_sym_Q7_2 [63] ICONST_ATTR_MPC_LARGE_IRAM = {
10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4,
-5, -6, -7, -8, -9, 17, 16, 15, 14, 13, 12, 11,-10,-11,-12,
-13,-14,-15,-16,-17, 22, 21, 20, 19, 18,-18,-19,-20,-21,-22,
29, 28, 27, 26, 25, 24, 23,-23,-24,-25,-26,-27,-28,-29, 31,
30,-30,-31
};
static const mpc_huffman mpc_huff_Q8_1 [11] ICONST_ATTR_MPC_LARGE_IRAM = {
{0xc000, 2, 3}, {0x8000, 3, 6}, {0x7000, 4, 10}, {0x5800, 5, 17},
{0x3800, 6, 28}, {0x2800, 7, 42}, {0x1900, 8, 62}, {0x0d00, 9, 87},
{0x0280, 10,113}, {0x0060, 11,123}, {0x0000, 12,126}
}; // 11
static const mpc_int8_t mpc_sym_Q8_1 [127] ICONST_ATTR_MPC_LARGE_IRAM = {
0, 1, -1, -2, 3, 2, -3, 7, 6, 5, 4, -4, -5, -6, -7, 11, 10, 9, 8, -8,
-9,-10,-11, 19, 18, 17, 16, 15, 14, 13, 12,-12,-13,-14,-15,-16,-17,-19, 56, 55,
31, 28, 27, 26, 25, 24, 23, 22, 21, 20,-18,-20,-21,-22,-23,-24,-25,-26,-27,-33,
-54,-56, 63, 62, 61, 60, 59, 58, 57, 54, 53, 43, 40, 39, 38, 37, 36, 35, 34, 33,
32, 30, 29,-28,-29,-30,-31,-32,-34,-35,-36,-37,-38,-39,-40,-41,-43,-53,-55,-57,
-58,-59,-60,-61, 49, 47, 46, 45, 44, 42, 41,-42,-44,-45,-46,-47,-48,-49,-50,-62,
-63, 52, 51, 50, 48,-51,-52
};
static const mpc_huffman mpc_huff_Q8_2 [4] ICONST_ATTR_MPC_LARGE_IRAM = {
{0x9800, 6, 63}, {0x2a00, 7, 101}, {0x400, 8, 122}, {0x0, 9, 126}
}; // 4
static const mpc_int8_t mpc_sym_Q8_2 [127] ICONST_ATTR_MPC_LARGE_IRAM = {
13, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7,
-8, -9,-10,-11,-12,-13, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26,
25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 12,-14,-15,-16,-17,-18,-19,-20,
-21,-22,-23,-24,-25,-26,-27,-28,-29,-30,-31,-32,-33,-34,-35,-36,-37,-38,-39,-40,
-41, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41,
40,-42,-43,-44,-45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-57,-58,-59, 63,
62, 61, 60,-60,-61,-62,-63
};
static const mpc_huffman mpc_huff_Q9up [6] ICONST_ATTR_MPC_LARGE_IRAM = {
{0xf800, 6, 63}, {0xac00, 7,125}, {0x2600, 8, -45},
{0x0280, 9, -7}, {0x0040, 10, -2}, {0x0000, 11, -1}
}; // 6
static const mpc_int8_t mpc_sym_Q9up [256] ICONST_ATTR_MPC_LARGE_IRAM = {
-128, 127,-108,-110,-111,-112,-113,-114,-115,-116,-117,-118,-119,-120,-121,-122,
-123,-124,-125,-126,-127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116,
115, 114, 113, 112, 111, 110, 109, 108, -44, -45, -46, -47, -48, -49, -50, -51,
-52, -53, -54, -55, -56, -57, -58, -59, -60, -61, -62, -63, -64, -65, -66, -67,
-68, -69, -70, -71, -72, -73, -74, -75, -76, -77, -78, -79, -80, -81, -82, -83,
-84, -85, -86, -87, -88, -89, -90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
-100,-101,-102,-103,-104,-105,-106,-107,-109, 107, 106, 105, 104, 103, 102, 101,
100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85,
84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69,
68, 67, 66, 65, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53,
52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 40, 20, 19, -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, -32, -33, -34, -35, -36, -37, -38, -39, -40,
-41, -42, -43, 41, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28,
27, 26, 25, 24, 23, 22, 21, 18, 17, 16, 15, 14, 13, 12, 11, 10,
9, 8, 7, 6, 5, -3, -4, -5, -6, 4, 3, 2, 1, 0, -1, -2
};
/* sv7 lookup tables */
mpc_lut_data mpc_HuffHdr IBSS_ATTR_MPC_LARGE_IRAM;
mpc_lut_data mpc_HuffDSCF IBSS_ATTR_MPC_LARGE_IRAM;
mpc_lut_data mpc_HuffQ [7] [2] IBSS_ATTR_MPC_LARGE_IRAM;
/* sv8 lookup tables */
mpc_can_data mpc_can_SCFI[2] IBSS_ATTR_MPC_LARGE_IRAM;
mpc_can_data mpc_can_DSCF[2] IBSS_ATTR_MPC_LARGE_IRAM;
mpc_can_data mpc_can_Bands IBSS_ATTR_MPC_LARGE_IRAM;
mpc_can_data mpc_can_Res[2] IBSS_ATTR_MPC_LARGE_IRAM;
mpc_can_data mpc_can_Q1 IBSS_ATTR_MPC_LARGE_IRAM;
mpc_can_data mpc_can_Q9up IBSS_ATTR_MPC_LARGE_IRAM;
mpc_can_data mpc_can_Q [6][2] IBSS_ATTR_MPC_LARGE_IRAM;
static void huff_fill_lut(const mpc_huffman *table, mpc_huff_lut *lut, const int bits)
{
int i, idx = 0;
const int shift = 16 - bits;
for (i = (1 << bits) - 1; i >= 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);
}

View file

@ -0,0 +1,83 @@
/*
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 huffman.h
/// Data structures and functions for huffman coding.
#ifndef _MPCDEC_HUFFMAN_H_
#define _MPCDEC_HUFFMAN_H_
#ifdef WIN32
#pragma once
#endif
#include "mpc_types.h"
#ifdef __cplusplus
extern "C" {
#endif
// LUT size parameter, LUT size is 1 << LUT_DEPTH
#define LUT_DEPTH 6
/// Huffman table entry.
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);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,123 @@
/*
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 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
#include "mpcdec.h"
/* rockbox: not used, rockbox's swap32 is used now.
/// Big/little endian 32 bit byte swapping routine.
static mpc_inline
mpc_uint32_t mpc_swap32(mpc_uint32_t val) {
return (((val & 0xFF000000) >> 24) | ((val & 0x00FF0000) >> 8)
| ((val & 0x0000FF00) << 8) | ((val & 0x000000FF) << 24));
}
*/
typedef struct mpc_block_t {
char key[2]; // block key
mpc_uint64_t size; // block size minus the block header size
} mpc_block;
#define MAX_FRAME_SIZE 4352
#define DEMUX_BUFFER_SIZE (32768 - MAX_FRAME_SIZE) // need some space as sand box
struct mpc_demux_t {
mpc_reader * r;
mpc_decoder * d;
mpc_streaminfo si;
// buffer
mpc_uint8_t *buffer;
mpc_size_t bytes_total;
mpc_bits_reader bits_reader;
mpc_int32_t block_bits; /// bits remaining in current audio block
mpc_uint_t block_frames; /// frames remaining in current audio block
// seeking
mpc_seek_t * seek_table;
mpc_uint_t seek_pwr; /// distance between 2 frames in seek_table = 2^seek_pwr
mpc_uint32_t seek_table_size; /// used size in seek_table
// chapters
/* rockbox: not used
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_FAIL 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_FAIL;
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_init_quant(mpc_decoder *d, MPC_SAMPLE_FORMAT factor); // in requant.c
void mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT* OutData, mpc_int_t channels);
unsigned long mpc_crc32(unsigned char *buf, int len);
// 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);
#define MPC_IS_FAILURE(X) ((int)(X) < (int)MPC_STATUS_OK)
#define MPC_AUTO_FAIL(X) { mpc_status s = (X); if (MPC_IS_FAILURE(s)) return s; }
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,18 @@
# __________ __ ___.
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
# \/ \/ \/ \/ \/
# $Id$
#
# libmusepack
MUSEPACKLIB := $(CODECDIR)/libmusepack.a
MUSEPACKLIB_SRC := $(call preprocess, $(RBCODECLIB_DIR)/codecs/libmusepack/SOURCES)
MUSEPACKLIB_OBJ := $(call c2obj, $(MUSEPACKLIB_SRC))
OTHER_SRC += $(MUSEPACKLIB_SRC)
$(MUSEPACKLIB): $(MUSEPACKLIB_OBJ)
$(SILENT)$(shell rm -f $@)
$(call PRINTS,AR $(@F))$(AR) rcs $@ $^ >/dev/null

View file

@ -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 maxd(A,B) ( (A) >? (B) )
# define mind(A,B) ( (A) <? (B) )
# define maxf(A,B) ( (A) >? (B) )
# define minf(A,B) ( (A) <? (B) )
#else
# define maxi(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

View file

@ -0,0 +1,181 @@
/*
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_BITSREADER =
{
{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_BITSREADER =
{
{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_BITSREADER =
{
{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_BITSREADER =
{ 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_BITSREADER =
{ 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 (max == 0)
return 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;
}

View file

@ -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;
}

View file

@ -0,0 +1,767 @@
/*
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 mpc_decoder.c
/// Core decoding routines and logic.
#include <string.h>
#include <codecs.h>
#include "mpcdec.h"
#include "minimax.h"
#include "decoder.h"
#include "huffman.h"
#include "internal.h"
#include "mpcdec_math.h"
#include "requant.h"
#include "mpc_bits_reader.h"
//SV7 tables
extern const 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_V_L[MPC_V_MEM + 960 ] IBSS_ATTR MEM_ALIGN_ATTR;
static MPC_SAMPLE_FORMAT g_Y_L[MPC_FRAME_LENGTH] IBSS_ATTR_MPC_LARGE_IRAM MEM_ALIGN_ATTR;
static MPC_SAMPLE_FORMAT g_V_R[MPC_V_MEM + 960 ] IBSS_ATTR MEM_ALIGN_ATTR;
static MPC_SAMPLE_FORMAT g_Y_R[MPC_FRAME_LENGTH] IBSS_ATTR_MPC_LARGE_IRAM MEM_ALIGN_ATTR;
//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
{
MEMSIZE = MPC_DECODER_MEMSIZE, // overall buffer size
MEMSIZE2 = (MEMSIZE/2), // size of one buffer
MEMMASK = (MEMSIZE-1)
};
//------------------------------------------------------------------------------
// forward declarations
//------------------------------------------------------------------------------
static void mpc_decoder_requantisierung (mpc_decoder *d)
ICODE_ATTR_MPC_LARGE_IRAM;
static void mpc_decoder_read_bitstream_sv7(mpc_decoder * d,
mpc_bits_reader * r)
ICODE_ATTR_MPC_LARGE_IRAM;
static void mpc_decoder_read_bitstream_sv8(mpc_decoder * d,
mpc_bits_reader * r,
mpc_bool_t is_key_frame)
ICODE_ATTR_MPC_SV8_BS_DEC;
//------------------------------------------------------------------------------
// macros
//------------------------------------------------------------------------------
#define REQUANT_M1_S1_SAMPLES(IDX) \
*(YL+=IDX) = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); \
*(YR+=IDX) = templ - tempr;
#define REQUANT_M1_S1(SUBFRAME) \
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][SUBFRAME] & 0xFF); \
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][SUBFRAME] & 0xFF); \
for (n = 0; n < 12; n+=4, YL += 32, YR += 32) { \
REQUANT_M1_S1_SAMPLES( 0); \
REQUANT_M1_S1_SAMPLES(32); \
REQUANT_M1_S1_SAMPLES(32); \
REQUANT_M1_S1_SAMPLES(32); \
}
#define REQUANT_M1_S0_SAMPLES(IDX) \
*(YR+=IDX) = *(YL+=IDX) = MPC_MULTIPLY_FLOAT_INT(facL,*L++);
#define REQUANT_M1_S0(SUBFRAME) \
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][SUBFRAME] & 0xFF); \
for (n = 0; n < 12; n+=4, YL += 32, YR += 32) { \
REQUANT_M1_S0_SAMPLES( 0); \
REQUANT_M1_S0_SAMPLES(32); \
REQUANT_M1_S0_SAMPLES(32); \
REQUANT_M1_S0_SAMPLES(32); \
}
#define REQUANT_M0_S1_SAMPLES(IDX) \
*(YR+=IDX) = -(*(YL+=IDX) = MPC_MULTIPLY_FLOAT_INT(facR,*R++));
#define REQUANT_M0_S1(SUBFRAME) \
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][SUBFRAME] & 0xFF); \
for (n = 0; n < 12; n+=4, YL += 32, YR += 32) { \
REQUANT_M0_S1_SAMPLES( 0); \
REQUANT_M0_S1_SAMPLES(32); \
REQUANT_M0_S1_SAMPLES(32); \
REQUANT_M0_S1_SAMPLES(32); \
}
#define REQUANT_L1_R1_SAMPLES(IDX) \
*(YL+=IDX) = MPC_MULTIPLY_FLOAT_INT(facL,*L++); \
*(YR+=IDX) = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
#define REQUANT_L1_R1(SUBFRAME) \
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][SUBFRAME] & 0xFF); \
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][SUBFRAME] & 0xFF); \
for (n = 0; n < 12; n+=4, YL += 32, YR += 32) { \
REQUANT_L1_R1_SAMPLES( 0); \
REQUANT_L1_R1_SAMPLES(32); \
REQUANT_L1_R1_SAMPLES(32); \
REQUANT_L1_R1_SAMPLES(32); \
}
#define REQUANT_L1_R0_SAMPLES(IDX) \
*(YL+=IDX) = MPC_MULTIPLY_FLOAT_INT(facL,*L++); \
*(YR+=IDX) = 0;
#define REQUANT_L1_R0(SUBFRAME) \
facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][SUBFRAME] & 0xFF); \
for (n = 0; n < 12; n+=4, YL += 32, YR += 32) { \
REQUANT_L1_R0_SAMPLES( 0); \
REQUANT_L1_R0_SAMPLES(32); \
REQUANT_L1_R0_SAMPLES(32); \
REQUANT_L1_R0_SAMPLES(32); \
}
#define REQUANT_L0_R1_SAMPLES(IDX) \
*(YL+=IDX) = 0; \
*(YR+=IDX) = MPC_MULTIPLY_FLOAT_INT(facR,*R++);
#define REQUANT_L0_R1(SUBFRAME) \
facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][SUBFRAME] & 0xFF); \
for (n = 0; n < 12; n+=4, YL += 32, YR += 32) { \
REQUANT_L0_R1_SAMPLES( 0); \
REQUANT_L0_R1_SAMPLES(32); \
REQUANT_L0_R1_SAMPLES(32); \
REQUANT_L0_R1_SAMPLES(32); \
}
#define REQUANT_SILENCE_SAMPLES(IDX) \
*(YR+=IDX) = *(YL+=IDX) = 0;
#define REQUANT_SILENCE \
for (n = 0; n < 36; n+=4, YL += 32, YR += 32) { \
REQUANT_SILENCE_SAMPLES( 0); \
REQUANT_SILENCE_SAMPLES(32); \
REQUANT_SILENCE_SAMPLES(32); \
REQUANT_SILENCE_SAMPLES(32); \
}
/**
* set the scf indexes for seeking use
* needed only for sv7 seeking
* @param d
*/
void mpc_decoder_reset_scf(mpc_decoder * d, int value)
{
memset(d->SCF_Index_L, value, sizeof d->SCF_Index_L );
memset(d->SCF_Index_R, value, sizeof d->SCF_Index_R );
}
static void mpc_decoder_setup(mpc_decoder *d)
{
#if defined(CPU_COLDFIRE)
coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE);
#endif
memset(d, 0, sizeof *d);
d->__r1 = 1;
d->__r2 = 1;
d->V_L = g_V_L;
d->V_R = g_V_R;
d->Y_L = g_Y_L;
d->Y_R = g_Y_R;
memset(d->V_L, 0, sizeof(g_V_L));
memset(d->V_R, 0, sizeof(g_V_R));
memset(d->Y_L, 0, sizeof(g_Y_L));
memset(d->Y_R, 0, sizeof(g_Y_R));
mpc_decoder_init_quant(d, MAKE_MPC_SAMPLE(1.0));
}
static void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si)
{
d->stream_version = si->stream_version;
d->ms = si->ms;
d->max_band = si->max_band;
d->channels = si->channels;
d->samples_to_skip = MPC_DECODER_SYNTH_DELAY + si->beg_silence;
if (si->stream_version == 7 && si->is_true_gapless)
d->samples = ((si->samples + MPC_FRAME_LENGTH - 1) / MPC_FRAME_LENGTH) * MPC_FRAME_LENGTH;
else
d->samples = si->samples;
}
mpc_decoder * mpc_decoder_init(mpc_streaminfo *si)
{
mpc_decoder* p_tmp = &g_mpc_decoder;
if (p_tmp != 0) {
mpc_decoder_setup(p_tmp);
mpc_decoder_set_streaminfo(p_tmp, si);
huff_init_lut(LUT_DEPTH);
}
return p_tmp;
}
/* rockbox: not used
void mpc_decoder_exit(mpc_decoder *d)
{
(void)d;
}
*/
void mpc_decoder_decode_frame(mpc_decoder * d,
mpc_bits_reader * r,
mpc_frame_info * i)
{
mpc_bits_reader r_sav = *r;
mpc_int64_t samples_left;
samples_left = d->samples - d->decoded_samples + MPC_DECODER_SYNTH_DELAY;
if (samples_left <= 0 && d->samples != 0) {
i->samples = 0;
i->bits = -1;
return;
}
if (d->stream_version == 8) {
mpc_decoder_read_bitstream_sv8(d, r, i->is_key_frame);
} else {
mpc_decoder_read_bitstream_sv7(d, r);
}
if (d->samples_to_skip < MPC_FRAME_LENGTH + MPC_DECODER_SYNTH_DELAY) {
mpc_decoder_requantisierung(d);
mpc_decoder_synthese_filter_float(d, i->buffer, d->channels);
}
d->decoded_samples += MPC_FRAME_LENGTH;
// reconstruct exact filelength
if (d->decoded_samples - d->samples < MPC_FRAME_LENGTH && d->stream_version == 7) {
int last_frame_samples = mpc_bits_read(r, 11);
if (d->decoded_samples == d->samples) {
if (last_frame_samples == 0) last_frame_samples = MPC_FRAME_LENGTH;
d->samples += last_frame_samples - MPC_FRAME_LENGTH;
samples_left += last_frame_samples - MPC_FRAME_LENGTH;
}
}
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 (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;
}
}
}
static void
mpc_decoder_requantisierung(mpc_decoder *d)
{
mpc_int32_t Band;
mpc_int32_t n;
MPC_SAMPLE_FORMAT facL;
MPC_SAMPLE_FORMAT facR;
MPC_SAMPLE_FORMAT templ;
MPC_SAMPLE_FORMAT tempr;
MPC_SAMPLE_FORMAT* YL;
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
#define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \
MPC_MULTIPLY_EX(CcVal, d->SCF[SCF_idx], d->SCF_shift[SCF_idx])
#else
#error FIXME, Cc table is in 18.14 format
#endif
#else
#define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \
MPC_MULTIPLY(CcVal, d->SCF[SCF_idx])
#endif
// requantization and scaling of subband-samples
for ( Band = 0; Band <= Last_Band; Band++ ) { // setting pointers
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
REQUANT_M1_S1(0);
REQUANT_M1_S1(1);
REQUANT_M1_S1(2);
} else { // M!=0, S==0
REQUANT_M1_S0(0);
REQUANT_M1_S0(1);
REQUANT_M1_S0(2);
}
} else {
if ( d->Res_R[Band] ) // M==0, S!=0
{
REQUANT_M0_S1(0);
REQUANT_M0_S1(1);
REQUANT_M0_S1(2);
} else { // M==0, S==0
REQUANT_SILENCE;
}
}
}
/************************** LR-coded **************************/
else {
if ( d->Res_L [Band] ) {
if ( d->Res_R [Band] ) { // L!=0, R!=0
REQUANT_L1_R1(0);
REQUANT_L1_R1(1);
REQUANT_L1_R1(2);
} else { // L!=0, R==0
REQUANT_L1_R0(0);
REQUANT_L1_R0(1);
REQUANT_L1_R0(2);
}
}
else {
if ( d->Res_R [Band] ) { // L==0, R!=0
REQUANT_L0_R1(0);
REQUANT_L0_R1(1);
REQUANT_L0_R1(2);
} else { // L==0, R==0
REQUANT_SILENCE;
}
}
}
}
}
static void mpc_decoder_read_bitstream_sv7(mpc_decoder * d, mpc_bits_reader * r)
{
mpc_int32_t n, idx, Max_used_Band = 0;
/***************************** Header *****************************/
// 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);
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 ******************************/
for ( n = 0; n < Max_used_Band; n++ ) {
if (d->Res_L[n])
d->SCFI_L[n] = mpc_bits_huff_dec(r, mpc_table_HuffSCFI);
if (d->Res_R[n])
d->SCFI_R[n] = mpc_bits_huff_dec(r, mpc_table_HuffSCFI);
}
/**************************** SCF/DSCF ****************************/
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;
}
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_uint32_t nbit;
mpc_int32_t k, dc;
const mpc_lut_data *Table;
switch (Res) {
case -2: case -3: case -4: case -5: case -6: case -7: case -8: case -9:
case -10: case -11: case -12: case -13: case -14: case -15: case -16: case -17: case 0:
break;
case -1:
for (k=0; k<36; k++ ) {
mpc_uint32_t tmp = mpc_random_int(d);
q[k] = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510;
}
break;
case 1:
Table = & mpc_HuffQ[0][mpc_bits_read(r, 1)];
for ( k = 0; k < 36; k += 3) {
idx = mpc_bits_huff_lut(r, Table);
q[k] = g_sv7_idx30[idx];
q[k + 1] = g_sv7_idx31[idx];
q[k + 2] = g_sv7_idx32[idx];
}
break;
case 2:
Table = & mpc_HuffQ[1][mpc_bits_read(r, 1)];
for ( k = 0; k < 36; k += 2) {
idx = mpc_bits_huff_lut(r, Table);
q[k] = g_sv7_idx50[idx];
q[k + 1] = g_sv7_idx51[idx];
}
break;
case 3:
case 4:
case 5:
case 6:
case 7:
Table = & mpc_HuffQ[Res - 1][mpc_bits_read(r, 1)];
for ( k = 0; k < 36; k++ )
q[k] = mpc_bits_huff_lut(r, Table);
break;
case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17:
nbit = Res_bit[Res];
dc = Dc[Res];
for ( k = 0; k < 36; k++ )
q[k] = (mpc_int32_t)mpc_bits_read(r, nbit) - dc;
break;
default:
return;
}
Res = d->Res_R[n];
} while (q == d->Q[n].L && (q = d->Q[n].R));
}
}
static void mpc_decoder_read_bitstream_sv8(mpc_decoder * d, mpc_bits_reader * r, mpc_bool_t is_key_frame)
{
mpc_int32_t n, Max_used_Band;
const mpc_can_data * Table, * Tables[2];
/***************************** Header *****************************/
if (is_key_frame == MPC_TRUE) {
Max_used_Band = mpc_bits_log_dec(r, d->max_band + 1);
} else {
Max_used_Band = d->last_max_band + mpc_bits_can_dec(r, & mpc_can_Bands);
if (Max_used_Band > 32) Max_used_Band -= 33;
}
d->last_max_band = Max_used_Band;
if (Max_used_Band) {
d->Res_L[Max_used_Band-1] = mpc_bits_can_dec(r, & mpc_can_Res[0]);
d->Res_R[Max_used_Band-1] = mpc_bits_can_dec(r, & mpc_can_Res[0]);
if (d->Res_L[Max_used_Band-1] > 15) d->Res_L[Max_used_Band-1] -= 17;
if (d->Res_R[Max_used_Band-1] > 15) d->Res_R[Max_used_Band-1] -= 17;
for ( n = Max_used_Band - 2; n >= 0; n--) {
d->Res_L[n] = mpc_bits_can_dec(r, & mpc_can_Res[d->Res_L[n + 1] > 2]) + d->Res_L[n + 1];
if (d->Res_L[n] > 15) d->Res_L[n] -= 17;
d->Res_R[n] = mpc_bits_can_dec(r, & mpc_can_Res[d->Res_R[n + 1] > 2]) + d->Res_R[n + 1];
if (d->Res_R[n] > 15) d->Res_R[n] -= 17;
}
if (d->ms) {
mpc_uint_t cnt = 0, tot = 0;
mpc_uint32_t tmp = 0;
for( n = 0; n < Max_used_Band; n++)
if ( d->Res_L[n] != 0 || d->Res_R[n] != 0 )
tot++;
cnt = mpc_bits_log_dec(r, tot);
if (cnt != 0 && cnt != tot)
tmp = mpc_bits_enum_dec(r, mini(cnt, tot-cnt), tot);
if (cnt * 2 > tot) tmp = ~tmp;
for( n = Max_used_Band - 1; n >= 0; n--)
if ( d->Res_L[n] != 0 || d->Res_R[n] != 0 ) {
d->MS_Flag[n] = tmp & 1;
tmp >>= 1;
}
}
}
for( n = Max_used_Band; n <= d->max_band; n++)
d->Res_L[n] = d->Res_R[n] = 0;
/****************************** SCFI ******************************/
if (is_key_frame == MPC_TRUE){
for( n = 0; n < 32; n++)
d->DSCF_Flag_L[n] = d->DSCF_Flag_R[n] = 1; // new block -> force key frame
}
Tables[0] = & mpc_can_SCFI[0];
Tables[1] = & mpc_can_SCFI[1];
for ( n = 0; n < Max_used_Band; n++ ) {
int tmp = 0, cnt = -1;
if (d->Res_L[n]) cnt++;
if (d->Res_R[n]) cnt++;
if (cnt >= 0) {
tmp = mpc_bits_can_dec(r, Tables[cnt]);
if (d->Res_L[n]) d->SCFI_L[n] = tmp >> (2 * cnt);
if (d->Res_R[n]) d->SCFI_R[n] = tmp & 3;
}
}
/**************************** SCF/DSCF ****************************/
for ( n = 0; n < Max_used_Band; n++ ) {
mpc_int32_t * SCF = d->SCF_Index_L[n];
mpc_uint32_t Res = d->Res_L[n], SCFI = d->SCFI_L[n];
mpc_bool_t * DSCF_Flag = &d->DSCF_Flag_L[n];
do {
if ( Res ) {
int m;
if (*DSCF_Flag == 1) {
SCF[0] = (mpc_int32_t)mpc_bits_read(r, 7) - 6;
*DSCF_Flag = 0;
} else {
mpc_uint_t tmp = mpc_bits_can_dec(r, & mpc_can_DSCF[1]);
if (tmp == 64)
tmp += mpc_bits_read(r, 6);
SCF[0] = ((SCF[2] - 25 + tmp) & 127) - 6;
}
for( m = 0; m < 2; m++){
if (((SCFI << m) & 2) == 0) {
mpc_uint_t tmp = mpc_bits_can_dec(r, & mpc_can_DSCF[0]);
if (tmp == 31)
tmp = 64 + mpc_bits_read(r, 6);
SCF[m + 1] = ((SCF[m] - 25 + tmp) & 127) - 6;
} else
SCF[m + 1] = SCF[m];
}
}
Res = d->Res_R[n];
SCFI = d->SCFI_R[n];
DSCF_Flag = &d->DSCF_Flag_R[n];
} while ( SCF == d->SCF_Index_L[n] && (SCF = d->SCF_Index_R[n]));
}
/***************************** Samples ****************************/
for ( n = 0; n < Max_used_Band; n++ ) {
mpc_int16_t *q = d->Q[n].L, Res = d->Res_L[n];
static const mpc_uint32_t thres[] = {0, 0, 3, 0, 0, 1, 3, 4, 8};
do {
mpc_uint32_t nbit;
mpc_uint32_t k = 0, idx = 1, dc;
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; ){
mpc_uint32_t 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 if (Res == 9) {
dc = Dc[Res];
for ( ; k < 36; k++ ) {
q[k] = (unsigned char) mpc_bits_can_dec(r, & mpc_can_Q9up);
q[k] -= dc;
}
} else {
nbit = (Res - 9);
dc = Dc[Res];
for ( ; k < 36; k++ ) {
q[k] = (unsigned char) mpc_bits_can_dec(r, & mpc_can_Q9up);
q[k] = (q[k] << nbit) | mpc_bits_read(r, nbit);
q[k] -= dc;
}
}
}
Res = d->Res_R[n];
} while (q == d->Q[n].L && (q = d->Q[n].R));
}
}

View file

@ -0,0 +1,730 @@
/*
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 <math.h>
#include <string.h>
#include "streaminfo.h"
#include "mpcdec.h"
#include "internal.h"
#include "decoder.h"
#include "huffman.h"
#include "mpc_bits_reader.h"
#include <codeclib.h>
/// 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
// defines
#define MAX_BUFFER_SIZE (DEMUX_BUFFER_SIZE + MAX_FRAME_SIZE)
// globals
static mpc_uint8_t g_buffer[MAX_BUFFER_SIZE] IBSS_ATTR_MPC_BITBUFFER;
static mpc_seek_t g_seek_table[MAX_SEEK_TABLE_SIZE];
static mpc_demux g_mpc_demux IBSS_ATTR;
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);
mpc_int32_t offset = 0;
if (min_bytes == 0 || min_bytes > MAX_BUFFER_SIZE ||
(unread_bytes < min_bytes && flags & MPC_BUFFER_FULL))
min_bytes = MAX_BUFFER_SIZE;
if (unread_bytes < min_bytes) {
mpc_uint32_t bytes2read = min_bytes - unread_bytes;
mpc_uint32_t bytes_free = MAX_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;
/* reset Coldfire optimized read when rebuffering */
d->bits_reader.buffered_addr = 0;
d->bits_reader.buffered_code = 0;
}
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 mpc_status
mpc_demux_seek(mpc_demux * d, mpc_seek_t fpos, mpc_uint32_t min_bytes) {
// d->bits_reader.buff - d->buffer = current byte position within buffer
// d->bytes_total = buffer is filled with bytes_total bytes
// fpos = desired file position in bit (not byte)
// buf_fpos = desired byte position within buffer
mpc_seek_t next_pos = fpos>>3;
mpc_int_t buf_fpos = next_pos - d->r->tell(d->r) + d->bytes_total;
// is desired byte position within lower and upper boundaries of buffer?
if (buf_fpos >= 0 && buf_fpos + min_bytes <= d->bytes_total) {
// desired bytes are available in current buffer
d->bits_reader.buff += buf_fpos - (d->bits_reader.buff - d->buffer);
d->bits_reader.count = 8 - (fpos & 7);
} else {
// buffer needs to be refilled
if (d->si.stream_version == 7)
next_pos = ((next_pos - d->si.header_position) & (-1 << 2)) + d->si.header_position;
buf_fpos = fpos - (next_pos << 3);
if (!d->r->seek(d->r, (mpc_int32_t) next_pos))
return MPC_STATUS_FAIL;
mpc_demux_clear_buff(d);
if (d->si.stream_version == 7)
mpc_demux_fill(d, MAX_BUFFER_SIZE, MPC_BUFFER_FULL | MPC_BUFFER_SWAP);
else
mpc_demux_fill(d, MAX_BUFFER_SIZE, MPC_BUFFER_FULL);
d->bits_reader.buff += buf_fpos >> 3;
d->bits_reader.count = 8 - (buf_fpos & 7);
}
return MPC_STATUS_OK;
}
/**
* 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
*/
static 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_FAIL 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_FAIL; // 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_FAIL; // 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_FAIL;
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_FAIL;
d->seek_table[0] = (mpc_seek_t)mpc_demux_pos(d);
d->seek_table_size = 1;
return MPC_STATUS_OK;
}
/* rockbox: do not use
static mpc_status 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_STATUS_OK;
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_STATUS_OK;
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];
}
return MPC_STATUS_OK;
}
static mpc_status 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_AUTO_FAIL( 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;
if (mpc_demux_fill(d, (mpc_uint32_t) b.size, 0) < b.size)
return MPC_STATUS_FAIL;
MPC_AUTO_FAIL( mpc_demux_ST(d) );
}
return mpc_demux_seek(d, cur, 11 + block_size);
}
*/
/* rockbox: not used
static void mpc_demux_chap_empty(mpc_demux * d) {
free(d->chap); d->chap = 0;
d->chap_nb = 0; // -1 for undefined, 0 for no chapters
d->chap_pos = 0;
}
*/
/* rockbox: not used
static mpc_status mpc_demux_chap_find_inner(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 MPC_STATUS_OK;
if (d->chap_pos == 0) {
mpc_uint64_t cur_pos = (d->si.header_position + 4) * 8;
MPC_AUTO_FAIL( 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) {
mpc_uint64_t new_pos = cur_pos + (size + b.size) * 8;
MPC_AUTO_FAIL(mpc_check_key(b.key));
if (memcmp(b.key, "CT", 2) == 0) {
if (d->chap_pos == 0) d->chap_pos = cur_pos;
} else {
d->chap_pos = 0;
}
if (new_pos <= cur_pos)
return MPC_STATUS_FAIL;
cur_pos = new_pos;
MPC_AUTO_FAIL( 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_AUTO_FAIL( 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);
if (d->chap == 0)
return MPC_STATUS_FAIL;
ptag = (char*)(d->chap + d->chap_nb);
MPC_AUTO_FAIL( 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_uint_t tmp_size;
char * tmp_ptag = ptag;
if (mpc_demux_fill(d, 11 + (mpc_uint32_t) b.size, 0) < b.size)
return MPC_STATUS_FAIL;
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);
tmp_size = b.size - size;
do {
mpc_uint_t rd_size = tmp_size;
mpc_uint8_t * tmp_buff = d->bits_reader.buff + ((8 - d->bits_reader.count) >> 3);
mpc_uint32_t avail_bytes = d->bytes_total + d->buffer - tmp_buff;
rd_size = mini(rd_size, avail_bytes);
memcpy(tmp_ptag, tmp_buff, rd_size);
tmp_size -= rd_size;
tmp_ptag += rd_size;
d->bits_reader.buff += rd_size;
mpc_demux_fill(d, tmp_size, 0);
} while (tmp_size > 0);
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;
return MPC_STATUS_OK;
}
*/
/* rockbox: not used
static mpc_status mpc_demux_chap_find(mpc_demux * d) {
mpc_status s = mpc_demux_chap_find_inner(d);
if (MPC_IS_FAILURE(s))
mpc_demux_chap_empty(d);
return s;
}
*/
/**
* 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_FAIL;
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)
return MPC_STATUS_FAIL;
if (mpc_demux_fill(d, 6 * 4, MPC_BUFFER_SWAP) < 6 * 4) // header block size + endian convertion
return MPC_STATUS_FAIL;
MPC_AUTO_FAIL( streaminfo_read_header_sv7(&d->si, &d->bits_reader) );
} 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_FAIL;
if (b.size > (mpc_uint64_t) MAX_BUFFER_SIZE - 11)
return MPC_STATUS_FAIL;
if (mpc_demux_fill(d, 11 + (mpc_uint32_t) b.size, 0) <= b.size)
return MPC_STATUS_FAIL;
if (memcmp(b.key, "SH", 2) == 0) {
MPC_AUTO_FAIL( streaminfo_read_header_sv8(&d->si, &d->bits_reader, (mpc_uint32_t) b.size) );
} 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);
/* rockbox: do not use
} else if (memcmp(b.key, "SO", 2) == 0) {
MPC_AUTO_FAIL( mpc_demux_SP(d, size, (mpc_uint32_t) b.size) );
} else if (memcmp(b.key, "ST", 2) == 0) {
MPC_AUTO_FAIL( 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_FAIL;
} else {
return MPC_STATUS_FAIL;
}
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;
/* rockbox: not used
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;
}
/* rockbox: not used
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);
}
static mpc_status mpc_demux_decode_inner(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, MPC_BUFFER_FULL); // max header block size
mpc_bits_get_block(&d->bits_reader, &b);
while( memcmp(b.key, "AP", 2) != 0 ) { // scan all blocks until audio
MPC_AUTO_FAIL( mpc_check_key(b.key) );
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, MPC_BUFFER_FULL) < b.size)
return MPC_STATUS_FAIL;
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;
}
mpc_demux_fill(d, MAX_FRAME_SIZE, MPC_BUFFER_FULL);
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))
return MPC_STATUS_FAIL;
} 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))
return MPC_STATUS_FAIL;
}
if (i->bits != -1 && d->buffer + d->bytes_total < d->bits_reader.buff + ((8 - d->bits_reader.count) >> 3))
return MPC_STATUS_FAIL;
return MPC_STATUS_OK;
}
mpc_status mpc_demux_decode(mpc_demux * d, mpc_frame_info * i) {
mpc_status s = mpc_demux_decode_inner(d, i);
if (MPC_IS_FAILURE(s))
i->bits = -1; // we pretend it's end of file
return s;
}
/* rockbox: not used
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 = (float) ( use_title ? d->si.peak_title : d->si.peak_album );
float gain = (float) ( use_title ? d->si.gain_title : d->si.gain_album );
if(!use_gain && !clip_prevention)
return;
if(!peak)
peak = 1.;
else
peak = (float) ( (1 << 15) / pow(10, peak / (20 * 256)) );
if(!gain)
gain = 1.;
else
gain = (float) pow(10, (level - gain / 256) / 20);
if(clip_prevention && (peak < gain || !use_gain))
gain = peak;
mpc_decoder_scale_output(d->d, gain);
}
*/

View file

@ -0,0 +1,145 @@
/*
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 <stdlib.h>
#include <inttypes.h>
#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 {
// Success.
MPC_STATUS_OK = 0,
// Generic failure (I/O error or invalid file).
MPC_STATUS_FAIL = -1
} 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

View file

@ -0,0 +1,212 @@
/*
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
#if (CONFIG_CPU == MCF5250)
/* Enough IRAM but performance suffers with ICODE_ATTR. */
#define IBSS_ATTR_MPC_LARGE_IRAM IBSS_ATTR
#define ICODE_ATTR_MPC_LARGE_IRAM
#define ICONST_ATTR_MPC_LARGE_IRAM ICONST_ATTR
/* Does not fit into IRAM. */
#define IBSS_ATTR_MPC_BITBUFFER
#define ICODE_ATTR_MPC_SV8_BS_DEC
/* Keep the data arrays of bitsreadr.c in IRAM. */
#define ICONST_ATTR_MPC_BITSREADER ICONST_ATTR
#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
/* Enough IRAM to move additional data and code to it. */
#define IBSS_ATTR_MPC_LARGE_IRAM IBSS_ATTR
#define ICODE_ATTR_MPC_LARGE_IRAM ICODE_ATTR
#define ICONST_ATTR_MPC_LARGE_IRAM ICONST_ATTR
/* Does not fit into IRAM. */
#define IBSS_ATTR_MPC_BITBUFFER
#define ICODE_ATTR_MPC_SV8_BS_DEC
/* Not putting the data arrays of bitsreader.c to IRAM allows to move the
* sv7/sv8 bitstream demuxing into IRAM. This config is faster. */
#define ICONST_ATTR_MPC_BITSREADER
#elif defined(CPU_S5L870X)
/* Enough IRAM to move additional data and code to it. */
#define IBSS_ATTR_MPC_LARGE_IRAM IBSS_ATTR
#define ICODE_ATTR_MPC_LARGE_IRAM ICODE_ATTR
#define ICONST_ATTR_MPC_LARGE_IRAM ICONST_ATTR
/* Faster when moved to IRAM. */
#define IBSS_ATTR_MPC_BITBUFFER IBSS_ATTR
#define ICODE_ATTR_MPC_SV8_BS_DEC ICODE_ATTR
/* Not faster when moved to IRAM. */
#define ICONST_ATTR_MPC_BITSREADER
#else
/* Not enough IRAM available. */
#define IBSS_ATTR_MPC_LARGE_IRAM
#define ICODE_ATTR_MPC_LARGE_IRAM
#define ICONST_ATTR_MPC_LARGE_IRAM
#define IBSS_ATTR_MPC_BITBUFFER
#define ICODE_ATTR_MPC_SV8_BS_DEC
#define ICONST_ATTR_MPC_BITSREADER
#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;
/* rockbox: not used
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);
/* rockbox: not used
/// 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
*/
/* rockbox: changed to static
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);
/* rockbox: not used
/// 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);
/* rockbox: not used
/// seeks to a given second
MPC_API mpc_status mpc_demux_seek_second(mpc_demux * d, double seconds);
*/
/* rockbox: keep static
/// \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

View file

@ -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 <cmnintrin.h>
#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)<<MPC_FIXED_POINT_FRACTPART))
#define MAKE_MPC_SAMPLE_EX(X,Y) (MPC_SAMPLE_FORMAT)((double)(X) * (double)(((mpc_int64_t)1)<<(Y)))
#define MPC_SHR_RND(X, Y) ((X+(1<<(Y-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)
/* Calculate: result = (X*Y)>>14 */
#define MPC_MULTIPLY(X,Y) \
({ \
MPC_SAMPLE_FORMAT lo; \
MPC_SAMPLE_FORMAT hi; \
asm volatile ( \
"smull %[lo], %[hi], %[x], %[y] \n\t" /* multiply */ \
"mov %[lo], %[lo], lsr #14 \n\t" /* lo >>= 14 */ \
"orr %[lo], %[lo], %[hi], lsl #18" /* lo |= (hi << 18) */ \
: [lo]"=&r"(lo), [hi]"=&r"(hi) \
: [x]"r"(X), [y]"r"(Y)); \
lo; \
})
/* Calculate: result = (X*Y)>>Z */
#define MPC_MULTIPLY_EX(X,Y,Z) \
({ \
MPC_SAMPLE_FORMAT lo; \
MPC_SAMPLE_FORMAT hi; \
asm volatile ( \
"smull %[lo], %[hi], %[x], %[y] \n\t" /* multiply */ \
"mov %[lo], %[lo], lsr %[shr] \n\t" /* lo >>= Z */ \
"orr %[lo], %[lo], %[hi], lsl %[shl]" /* lo |= (hi << (32-Z)) */ \
: [lo]"=&r"(lo), [hi]"=&r"(hi) \
: [x]"r"(X), [y]"r"(Y), [shr]"r"(Z), [shl]"r"(32-Z)); \
lo; \
})
#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)
/* Calculate: result = (X*Y)>>32, without need for >>32 */
#define MPC_MULTIPLY_FRACT(X,Y) \
({ \
MPC_SAMPLE_FORMAT lo; \
MPC_SAMPLE_FORMAT hi; \
asm volatile ( \
"smull %[lo], %[hi], %[x], %[y]" /* hi = result */ \
: [lo]"=&r"(lo), [hi]"=&r"(hi) \
: [x]"r"(X), [y]"r"(Y)); \
hi; \
})
#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_

View file

@ -0,0 +1,100 @@
/*
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 reader.h
#ifndef _MPCDEC_READER_H_
#define _MPCDEC_READER_H_
#ifdef WIN32
#pragma once
#endif
#include "mpc_types.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/// \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 mpc_reader;
struct mpc_reader_t {
/// Reads size bytes of data into buffer at ptr.
mpc_int32_t (*read)(mpc_reader *p_reader, void *ptr, mpc_int32_t size);
/// Seeks to byte position 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)(mpc_reader *p_reader);
/// Returns the total length of the source stream, in bytes.
mpc_int32_t (*get_size)(mpc_reader *p_reader);
/* rockbox: not used
/// True if the stream is a seekable stream.
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;
*/
};
/* rockbox: not used
/// Initializes reader with default stdio file reader implementation. Use
/// this if you're just reading from a plain file.
///
/// \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);
/// 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

View file

@ -0,0 +1,184 @@
/*
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 requant.c
/// Requantization function implementations.
/// \todo document me
#include "mpcdec.h"
#include "requant.h"
#include "mpcdec_math.h"
#include "decoder.h"
#include "internal.h"
#include <string.h>
/* C O N S T A N T S */
// 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
};
// 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)
_(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)
};
#undef _
// Requantization offset
// 2*D+1 = steps of quantizer
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
};
// Table'ized SCF calculated from mpc_decoder_scale_output(d, 1.0)
static const mpc_uint32_t SCF[] = {
1289035711, 1073741824, 1788812356, 1490046106, 1241179595, 1033878604, 861200887, 717363687,
597550081, 497747664, 414614180, 345365595, 287682863, 239634262, 199610707, 166271859,
138501244, 115368858, 96100028, 80049465, 66679657, 55542865, 46266132, 38538793,
32102070, 26740403, 22274239, 18554010, 15455132, 12873826, 10723648, 8932591,
7440676, 6197939, 5162763, 4300482, 3582218, 2983918, 2485546, 2070412,
1724613, 1436569, 1196634, 996773, 830293, 691618, 576104, 479883,
399734, 332970, 277358, 231034, 192446, 160304, 133530, 111228,
92651, 77176, 64286, 53549, 44605, 37155, 30949, 25780,
21474, 17888, 14900, 12411, 10338, 8612, 7173, 5975,
4977, 4146, 3453, 2876, 2396, 1996, 1662, 1385,
1153, 961, 800, 666, 555, 462, 385, 321,
267, 222, 185, 154, 128, 107, 89, 74,
61, 51, 43, 35, 29, 24, 20, 17,
14, 11, 9, 8, 6, 5, 4, 3,
3, 2, 2, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 2147483648, 2147483648, 2147483648, 2147483648, 2147483648, 2147483648, 2147483648,
2147483648, 2147483648, 2147483648, 2147483648, 1930697728, 1608233877, 1339627724, 1115883992,
1859019579, 1548527365, 1289893354, 1074456223, 1790002518, 1491037488, 1242005398, 2069132964,
1723547752, 1435681952, 1195895306, 1992315335, 1659560152, 1382381519, 1151497076, 1918349601,
1597948125, 1331059892, 1108747153, 1847129882, 1538623477, 1281643607, 2135168687, 1778554232,
1481501287, 1234061927, 2055899448, 1712524489, 1426499787, 1188246741, 1979573121, 1648946134,
1373540247, 1144132468, 1906080447, 1587728158, 1322546856, 1101655960, 1835316227, 1528782931,
1273446622, 2121512828, 1767179166, 1472026076, 1226169259, 2042750570, 1701571728, 1417376349,
1180647093, 1966912401, 1638400000, 1364755521, 1136814961, 1893889764, 1577573554, 1314088268,
1094610119, 1823578129, 1519005322, 1265302063, 2107944308, 1755876851, 1462611466, 1218327071,
2029685788, 1690689017, 1408311261, 1173096050, 1954332656, 1627921315, 1356026979, 1129544254,
1881777048, 1567483896, 1305683778, 1087609341, 1811915104, 1509290248, 1257209594, 2094462567,
1744646821, 1453257069, 1210535039, 2016704564, 1679875908, 1399304151, 1165593302, 1941833367,
1617509648, 1347354262, 1122320049, 1869741801, 1557458768, 1297333040, 1080653338, 1800326672,
1499637308, 1249168882, 2081067051, 1733488616, 1443962500, 1202792843, 2003806364, 1669131957,
1390354647, 1158138538, 1929414019, 1607164572, 1338737013, 1115142047, 1857783528, 1547497758
};
// Table'ized SCF_shift calculated from mpc_decoder_scale_output(d, 1.0)
static const mpc_uint8_t SCF_shift[] = {
30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5,
5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9,
9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13,
13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 17, 17, 17, 17,
18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 22,
22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26,
26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30
};
/* F U N C T I O N S */
/* not used anymore, tables from above are used
#ifdef MPC_FIXED_POINT
static mpc_uint32_t find_shift(double fval)
{
mpc_int64_t val = (mpc_int64_t) fval;
mpc_uint32_t ptr = 0;
if(val<0)
val = -val;
while(val)
{
val >>= 1;
ptr++;
}
return ptr > 31 ? 0 : 31 - ptr;
}
#endif
#define SET_SCF(N,X) d->SCF[N] = MAKE_MPC_SAMPLE_EX(X,d->SCF_shift[N] = (mpc_uint8_t) find_shift(X));
static void
mpc_decoder_scale_output(mpc_decoder *d, double factor)
{
mpc_int32_t n; double f1, f2;
#ifndef MPC_FIXED_POINT
factor *= 1.0 / (double) (1<<(MPC_FIXED_POINT_SHIFT-1));
#else
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((mpc_uint8_t)(1+n),f1);
SET_SCF((mpc_uint8_t)(1-n),f2);
f1 *= 0.83298066476582673961;
f2 *= 1/0.83298066476582673961;
}
}
*/
void
mpc_decoder_init_quant(mpc_decoder *d, MPC_SAMPLE_FORMAT factor)
{
//mpc_decoder_scale_output(d, (double)factor / MPC_FIXED_POINT_SHIFT)
(void)factor;
memcpy(d->SCF, SCF, sizeof(d->SCF));
memcpy(d->SCF_shift, SCF_shift, sizeof(d->SCF_shift));
}

View file

@ -0,0 +1,61 @@
/*
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 requant.h
/// Requantization function definitions.
#ifndef _MPCDEC_REQUANT_H_
#define _MPCDEC_REQUANT_H_
#ifdef WIN32
#pragma once
#endif
#include "mpc_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* C O N S T A N T S */
extern const mpc_uint8_t Res_bit [18]; ///< Bits per sample for chosen quantizer
extern const MPC_SAMPLE_FORMAT __Cc [1 + 18]; ///< Requantization coefficients
extern const mpc_int16_t __Dc [1 + 18]; ///< Requantization offset
#define Cc (__Cc + 1)
#define Dc (__Dc + 1)
#ifdef __cplusplus
}
#endif
#endif

View file

@ -0,0 +1,255 @@
/*
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 streaminfo.c
/// Implementation of streaminfo reading functions.
#include <math.h>
#include "mpcdec.h"
#include "streaminfo.h"
#include <stdio.h>
#include "internal.h"
#include "huffman.h"
#include "mpc_bits_reader.h"
/* 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 *
mpc_get_version_string(float profile) // profile is 0...15, where 7...13 is used
{
return profile >= sizeof versionNames / sizeof *versionNames ? na : versionNames[(int)profile];
}
*/
/* rockbox: not used
static void
mpc_get_encoder_string(mpc_streaminfo* si)
{
int ver = si->encoder_version;
if (si->stream_version >= 8)
ver = (si->encoder_version >> 24) * 100 + ((si->encoder_version >> 16) & 0xFF);
if (ver <= 116) {
if (ver == 0) {
sprintf(si->encoder, "Buschmann 1.7.0...9, Klemm 0.90...1.05");
} else {
switch (ver % 10) {
case 0:
sprintf(si->encoder, "Release %u.%u", ver / 100,
ver / 10 % 10);
break;
case 2: case 4: case 6: case 8:
sprintf(si->encoder, "Beta %u.%02u", ver / 100,
ver % 100);
break;
default:
sprintf(si->encoder, "--Alpha-- %u.%02u",
ver / 100, ver % 100);
break;
}
}
} else {
int major = si->encoder_version >> 24;
int minor = (si->encoder_version >> 16) & 0xFF;
int build = (si->encoder_version >> 8) & 0xFF;
char * tmp = "--Stable--";
if (minor & 1)
tmp = "--Unstable--";
sprintf(si->encoder, "%s %u.%u.%u", tmp, major, minor, build);
}
}
*/
static mpc_status check_streaminfo(mpc_streaminfo * si)
{
if (si->max_band == 0 || si->max_band >= 32
|| si->channels > 2 || si->channels == 0 || si->sample_freq == 0)
return MPC_STATUS_FAIL;
return MPC_STATUS_OK;
}
/// Reads streaminfo from SV7 header.
mpc_status
streaminfo_read_header_sv7(mpc_streaminfo* si, mpc_bits_reader * r)
{
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)];
mpc_bits_read(r, 16); // Estimatedpeak_title
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 (si->gain_album != 0) {
int tmp = (int)((MPC_OLD_GAIN_REF - (mpc_int16_t)si->gain_album / 100.) * 256. + .5);
if (tmp >= (1 << 16) || tmp < 0) tmp = 0;
si->gain_album = (mpc_int16_t) tmp;
}
if (si->peak_title != 0)
si->peak_title = (mpc_uint16_t) (log10(si->peak_title) * 20 * 256 + .5);
if (si->peak_album != 0)
si->peak_album = (mpc_uint16_t) (log10(si->peak_album) * 20 * 256 + .5);
mpc_get_encoder_string(si);
*/
if (last_frame_samples == 0) last_frame_samples = MPC_FRAME_LENGTH;
else if (last_frame_samples > MPC_FRAME_LENGTH) return MPC_STATUS_FAIL;
si->samples = (mpc_int64_t) frames * MPC_FRAME_LENGTH;
if (si->is_true_gapless)
si->samples -= (MPC_FRAME_LENGTH - last_frame_samples);
else
si->samples -= MPC_DECODER_SYNTH_DELAY;
si->average_bitrate = 8LL * (si->tag_offset - si->header_position)
* si->sample_freq / si->samples;
return check_streaminfo(si);
}
/// Reads replay gain datas
void streaminfo_gain(mpc_streaminfo* si, const mpc_bits_reader * r_in)
{
mpc_bits_reader r = *r_in;
int version = mpc_bits_read(&r, 8); // gain version
if (version != 1) // we only know ver 1
return;
si->gain_title = (mpc_uint16_t) mpc_bits_read(&r, 16);
si->peak_title = (mpc_uint16_t) mpc_bits_read(&r, 16);
si->gain_album = (mpc_uint16_t) mpc_bits_read(&r, 16);
si->peak_album = (mpc_uint16_t) mpc_bits_read(&r, 16);
}
/// Reads streaminfo from SV8 header.
mpc_status
streaminfo_read_header_sv8(mpc_streaminfo* si, const mpc_bits_reader * r_in,
mpc_size_t block_size)
{
mpc_uint32_t CRC;
mpc_bits_reader r = *r_in;
CRC = (mpc_bits_read(&r, 16) << 16) | mpc_bits_read(&r, 16);
if (CRC != mpc_crc32(r.buff + 1 - (r.count >> 3), (int)block_size - 4))
return MPC_STATUS_FAIL;
si->stream_version = mpc_bits_read(&r, 8);
if (si->stream_version != 8)
return MPC_STATUS_FAIL;
mpc_bits_get_size(&r, &si->samples);
mpc_bits_get_size(&r, &si->beg_silence);
si->is_true_gapless = 1;
si->sample_freq = samplefreqs[mpc_bits_read(&r, 3)];
si->max_band = mpc_bits_read(&r, 5) + 1;
si->channels = mpc_bits_read(&r, 4) + 1;
si->ms = mpc_bits_read(&r, 1);
si->block_pwr = mpc_bits_read(&r, 3) * 2;
si->bitrate = 0;
if ((si->samples - si->beg_silence) != 0)
si->average_bitrate = 8LL * (si->tag_offset - si->header_position)
* si->sample_freq / (si->samples - si->beg_silence);
return check_streaminfo(si);
}
/// Reads encoder informations
void streaminfo_encoder_info(mpc_streaminfo* si, const mpc_bits_reader * r_in)
{
mpc_bits_reader r = *r_in;
si->profile = mpc_bits_read(&r, 7); // to be divided by 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
/* rockbox: not used
mpc_get_encoder_string(si);
*/
}
/* rockbox: not used
double
mpc_streaminfo_get_length(mpc_streaminfo * si)
{
return (double) (si->samples - si->beg_silence) / si->sample_freq;
}
mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si)
{
return si->samples - si->beg_silence;
}
*/

View file

@ -0,0 +1,114 @@
/*
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 streaminfo.h
#ifndef _MPCDEC_STREAMINFO_H_
#define _MPCDEC_STREAMINFO_H_
#ifdef WIN32
#pragma once
#endif
#include "mpc_types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef mpc_int32_t mpc_streaminfo_off_t;
/// \brief mpc stream properties structure
///
/// Structure containing all the properties of an mpc stream. Populated
/// by the streaminfo_read function.
typedef struct mpc_streaminfo {
/// @name Core mpc stream properties
//@{
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)
mpc_uint32_t 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 properties
//@{
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 properties
//@{
mpc_uint32_t is_true_gapless; ///< True gapless? (0: no, 1: yes)
mpc_uint64_t samples; ///< Number of samples in the stream
mpc_uint64_t beg_silence; ///< Number of samples that must not be played at the beginning of the stream
//@}
/// @name Encoder informations
//@{
mpc_uint32_t encoder_version; ///< Version of encoder used
/* rockbox: not used
char encoder[256]; ///< Encoder name
*/
mpc_bool_t pns; ///< pns used
mpc_uint32_t 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;
/* 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

View file

@ -0,0 +1,610 @@
/*
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 synth_filter.c
/// Synthesis functions.
/// \todo document me
#include <string.h>
#include <codecs.h>
#include "mpcdec.h"
#include "decoder.h"
#include "mpcdec_math.h"
#include "internal.h"
/* C O N S T A N T S */
#undef _
#if defined(MPC_FIXED_POINT)
#if defined(CPU_ARM)
#if ARM_ARCH >= 6
// on ARMv6 we use 32*32=64>>32 multiplies (smmul/smmla) so we need to scale up the D coefficients
// the ARM11 multiplier doesn't have early termination so the magnitude of the multiplicands does not
// matter for speed.
#define D(value) (value << (14))
#else
// do not up-scale D-values to achieve higher speed in smull/mlal
// operations. saves ~14/8 = 1.75 cycles per multiplication
#define D(value) (value)
#endif
// in this configuration a post-shift by >>16 is needed after synthesis
#else
// saturate to +/- 2^31 (= value << (31-17)), D-values are +/- 2^17
#define D(value) (value << (14))
#endif
#else
// IMPORTANT: internal scaling is somehow strange for floating point, therefore we scale the coefficients Di_opt
// by the correct amount to have proper scaled output
#define D(value) MAKE_MPC_SAMPLE((double)value*(double)(0x1000))
#endif
// Di_opt coefficients are +/- 2^17 (pre-shifted by <<16)
static const MPC_SAMPLE_FORMAT Di_opt [512] ICONST_ATTR MEM_ALIGN_ATTR = {
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
/* 0 */ D( 0), -D( 29), D(213), -D( 459), D(2037), -D(5153), D( 6574), -D(37489), D(75038), D(37489), D(6574), D(5153), D(2037), D(459), D(213), D(29),
/* 1 */ -D( 1), -D( 31), D(218), -D( 519), D(2000), -D(5517), D( 5959), -D(39336), D(74992), D(35640), D(7134), D(4788), D(2063), D(401), D(208), D(26),
/* 2 */ -D( 1), -D( 35), D(222), -D( 581), D(1952), -D(5879), D( 5288), -D(41176), D(74856), D(33791), D(7640), D(4425), D(2080), D(347), D(202), D(24),
/* 3 */ -D( 1), -D( 38), D(225), -D( 645), D(1893), -D(6237), D( 4561), -D(43006), D(74630), D(31947), D(8092), D(4063), D(2087), D(294), D(196), D(21),
/* 4 */ -D( 1), -D( 41), D(227), -D( 711), D(1822), -D(6589), D( 3776), -D(44821), D(74313), D(30112), D(8492), D(3705), D(2085), D(244), D(190), D(19),
/* 5 */ -D( 1), -D( 45), D(228), -D( 779), D(1739), -D(6935), D( 2935), -D(46617), D(73908), D(28289), D(8840), D(3351), D(2075), D(197), D(183), D(17),
/* 6 */ -D( 1), -D( 49), D(228), -D( 848), D(1644), -D(7271), D( 2037), -D(48390), D(73415), D(26482), D(9139), D(3004), D(2057), D(153), D(176), D(16),
/* 7 */ -D( 2), -D( 53), D(227), -D( 919), D(1535), -D(7597), D( 1082), -D(50137), D(72835), D(24694), D(9389), D(2663), D(2032), D(111), D(169), D(14),
/* 8 */ -D( 2), -D( 58), D(224), -D( 991), D(1414), -D(7910), D( 70), -D(51853), D(72169), D(22929), D(9592), D(2330), D(2001), D( 72), D(161), D(13),
/* 9 */ -D( 2), -D( 63), D(221), -D(1064), D(1280), -D(8209), -D( 998), -D(53534), D(71420), D(21189), D(9750), D(2006), D(1962), D( 36), D(154), D(11),
/* 10 */ -D( 2), -D( 68), D(215), -D(1137), D(1131), -D(8491), -D( 2122), -D(55178), D(70590), D(19478), D(9863), D(1692), D(1919), D( 2), D(147), D(10),
/* 11 */ -D( 3), -D( 73), D(208), -D(1210), D( 970), -D(8755), -D( 3300), -D(56778), D(69679), D(17799), D(9935), D(1388), D(1870), -D( 29), D(139), D( 9),
/* 12 */ -D( 3), -D( 79), D(200), -D(1283), D( 794), -D(8998), -D( 4533), -D(58333), D(68692), D(16155), D(9966), D(1095), D(1817), -D( 57), D(132), D( 8),
/* 13 */ -D( 4), -D( 85), D(189), -D(1356), D( 605), -D(9219), -D( 5818), -D(59838), D(67629), D(14548), D(9959), D( 814), D(1759), -D( 83), D(125), D( 7),
/* 14 */ -D( 4), -D( 91), D(177), -D(1428), D( 402), -D(9416), -D( 7154), -D(61289), D(66494), D(12980), D(9916), D( 545), D(1698), -D(106), D(117), D( 7),
/* 15 */ -D( 5), -D( 97), D(163), -D(1498), D( 185), -D(9585), -D( 8540), -D(62684), D(65290), D(11455), D(9838), D( 288), D(1634), -D(127), D(111), D( 6),
/* 16 */ -D( 5), -D(104), D(146), -D(1567), -D( 45), -D(9727), -D( 9975), -D(64019), D(64019), D( 9975), D(9727), D( 45), D(1567), -D(146), D(104), D( 5),
/* 17 */ -D( 6), -D(111), D(127), -D(1634), -D( 288), -D(9838), -D(11455), -D(65290), D(62684), D( 8540), D(9585), -D( 185), D(1498), -D(163), D( 97), D( 5),
/* 18 */ -D( 7), -D(117), D(106), -D(1698), -D( 545), -D(9916), -D(12980), -D(66494), D(61289), D( 7154), D(9416), -D( 402), D(1428), -D(177), D( 91), D( 4),
/* 19 */ -D( 7), -D(125), D( 83), -D(1759), -D( 814), -D(9959), -D(14548), -D(67629), D(59838), D( 5818), D(9219), -D( 605), D(1356), -D(189), D( 85), D( 4),
/* 20 */ -D( 8), -D(132), D( 57), -D(1817), -D(1095), -D(9966), -D(16155), -D(68692), D(58333), D( 4533), D(8998), -D( 794), D(1283), -D(200), D( 79), D( 3),
/* 21 */ -D( 9), -D(139), D( 29), -D(1870), -D(1388), -D(9935), -D(17799), -D(69679), D(56778), D( 3300), D(8755), -D( 970), D(1210), -D(208), D( 73), D( 3),
/* 22 */ -D(10), -D(147), -D( 2), -D(1919), -D(1692), -D(9863), -D(19478), -D(70590), D(55178), D( 2122), D(8491), -D(1131), D(1137), -D(215), D( 68), D( 2),
/* 23 */ -D(11), -D(154), -D( 36), -D(1962), -D(2006), -D(9750), -D(21189), -D(71420), D(53534), D( 998), D(8209), -D(1280), D(1064), -D(221), D( 63), D( 2),
/* 24 */ -D(13), -D(161), -D( 72), -D(2001), -D(2330), -D(9592), -D(22929), -D(72169), D(51853), -D( 70), D(7910), -D(1414), D( 991), -D(224), D( 58), D( 2),
/* 25 */ -D(14), -D(169), -D(111), -D(2032), -D(2663), -D(9389), -D(24694), -D(72835), D(50137), -D( 1082), D(7597), -D(1535), D( 919), -D(227), D( 53), D( 2),
/* 26 */ -D(16), -D(176), -D(153), -D(2057), -D(3004), -D(9139), -D(26482), -D(73415), D(48390), -D( 2037), D(7271), -D(1644), D( 848), -D(228), D( 49), D( 1),
/* 27 */ -D(17), -D(183), -D(197), -D(2075), -D(3351), -D(8840), -D(28289), -D(73908), D(46617), -D( 2935), D(6935), -D(1739), D( 779), -D(228), D( 45), D( 1),
/* 28 */ -D(19), -D(190), -D(244), -D(2085), -D(3705), -D(8492), -D(30112), -D(74313), D(44821), -D( 3776), D(6589), -D(1822), D( 711), -D(227), D( 41), D( 1),
/* 29 */ -D(21), -D(196), -D(294), -D(2087), -D(4063), -D(8092), -D(31947), -D(74630), D(43006), -D( 4561), D(6237), -D(1893), D( 645), -D(225), D( 38), D( 1),
/* 30 */ -D(24), -D(202), -D(347), -D(2080), -D(4425), -D(7640), -D(33791), -D(74856), D(41176), -D( 5288), D(5879), -D(1952), D( 581), -D(222), D( 35), D( 1),
/* 31 */ -D(26), -D(208), -D(401), -D(2063), -D(4788), -D(7134), -D(35640), -D(74992), D(39336), -D( 5959), D(5517), -D(2000), D( 519), -D(218), D( 31), D( 1)
};
#undef D
// DCT32-coefficients were expanded (<<) by DCT32_COEFFICIENT_EXPAND
#define DCT32_COEFFICIENT_EXPAND 31
#if defined(MPC_FIXED_POINT)
// define 64=32x32-multiplication for DCT-coefficients with samples. Via usage of MPC_FRACT highly optimized assembler might be used
// MULTIPLY_FRACT will perform >>32 after multiplication, as coef were expanded by DCT32_COEFFICIENT_EXPAND we'll correct this on the result.
// Will loose 4 bit accuracy on result in fract part without effect on final audio result
#define MPC_DCT32_MUL(sample, coef) (MPC_MULTIPLY_FRACT(sample,coef) << (32-DCT32_COEFFICIENT_EXPAND))
#define MPC_DCT32_SHIFT(sample) (sample)
#else
// for floating point use the standard multiplication macro
#define MPC_DCT32_MUL(sample, coef) (MPC_MULTIPLY(sample, coef) )
#define MPC_DCT32_SHIFT(sample) (sample)
#endif
/******************************************************************************
* mpc_dct32(const int *in, int *out)
*
* mpc_dct32 is a dct32 with in[32]->dct[32] that contains the mirroring from
* dct[32] to the expected out[64]. The symmetry is
* out[16] = 0,
* out[ 0..15] = dct[ 0..15],
* out[32..17] = -dct[ 0..15],
* out[33..48] = -dct[16..31],
* out[63..48] = -dct[16..31].
* The cos-tab has the format s0.31.
*****************************************************************************/
void
mpc_dct32(const MPC_SAMPLE_FORMAT *in, MPC_SAMPLE_FORMAT *v)
ICODE_ATTR_MPC_LARGE_IRAM;
void
mpc_dct32(const MPC_SAMPLE_FORMAT *in, MPC_SAMPLE_FORMAT *v)
{
MPC_SAMPLE_FORMAT t0, t1, t2, t3, t4, t5, t6, t7;
MPC_SAMPLE_FORMAT t8, t9, t10, t11, t12, t13, t14, t15;
MPC_SAMPLE_FORMAT t16, t17, t18, t19, t20, t21, t22, t23;
MPC_SAMPLE_FORMAT t24, t25, t26, t27, t28, t29, t30, t31;
MPC_SAMPLE_FORMAT t32, t33, t34, t35, t36, t37, t38, t39;
MPC_SAMPLE_FORMAT t40, t41, t42, t43, t44, t45, t46, t47;
MPC_SAMPLE_FORMAT t48, t49, t50, t51, t52, t53, t54, t55;
MPC_SAMPLE_FORMAT t56, t57, t58, t59, t60, t61, t62, t63;
MPC_SAMPLE_FORMAT t64, t65, t66, t67, t68, t69, t70, t71;
MPC_SAMPLE_FORMAT t72, t73, t74, t75, t76, t77, t78, t79;
MPC_SAMPLE_FORMAT t80, t81, t82, t83, t84, t85, t86, t87;
MPC_SAMPLE_FORMAT t88, t89, t90, t91, t92, t93, t94, t95;
MPC_SAMPLE_FORMAT t96, t97, t98, t99, t100, t101, t102, t103;
MPC_SAMPLE_FORMAT t104, t105, t106, t107, t108, t109, t110, t111;
MPC_SAMPLE_FORMAT t112, t113, t114, t115, t116, t117, t118, t119;
MPC_SAMPLE_FORMAT t120, t121, t122, t123, t124, t125, t126, t127;
MPC_SAMPLE_FORMAT t128, t129, t130, t131, t132, t133, t134, t135;
MPC_SAMPLE_FORMAT t136, t137, t138, t139, t140, t141, t142, t143;
MPC_SAMPLE_FORMAT t144, t145, t146, t147, t148, t149, t150, t151;
MPC_SAMPLE_FORMAT t152, t153, t154, t155, t156, t157, t158, t159;
MPC_SAMPLE_FORMAT t160, t161, t162, t163, t164, t165, t166, t167;
MPC_SAMPLE_FORMAT t168, t169, t170, t171, t172, t173, t174, t175;
MPC_SAMPLE_FORMAT t176;
/* costab[i] = cos(PI / (2 * 32) * i) */
#define costab01 (0x7fd8878e) /* 0.998795456 */
#define costab02 (0x7f62368f) /* 0.995184727 */
#define costab03 (0x7e9d55fc) /* 0.989176510 */
#define costab04 (0x7d8a5f40) /* 0.980785280 */
#define costab05 (0x7c29fbee) /* 0.970031253 */
#define costab06 (0x7a7d055b) /* 0.956940336 */
#define costab07 (0x78848414) /* 0.941544065 */
#define costab08 (0x7641af3d) /* 0.923879533 */
#define costab09 (0x73b5ebd1) /* 0.903989293 */
#define costab10 (0x70e2cbc6) /* 0.881921264 */
#define costab11 (0x6dca0d14) /* 0.857728610 */
#define costab12 (0x6a6d98a4) /* 0.831469612 */
#define costab13 (0x66cf8120) /* 0.803207531 */
#define costab14 (0x62f201ac) /* 0.773010453 */
#define costab15 (0x5ed77c8a) /* 0.740951125 */
#define costab16 (0x5a82799a) /* 0.707106781 */
#define costab17 (0x55f5a4d2) /* 0.671558955 */
#define costab18 (0x5133cc94) /* 0.634393284 */
#define costab19 (0x4c3fdff4) /* 0.595699304 */
#define costab20 (0x471cece7) /* 0.555570233 */
#define costab21 (0x41ce1e65) /* 0.514102744 */
#define costab22 (0x3c56ba70) /* 0.471396737 */
#define costab23 (0x36ba2014) /* 0.427555093 */
#define costab24 (0x30fbc54d) /* 0.382683432 */
#define costab25 (0x2b1f34eb) /* 0.336889853 */
#define costab26 (0x25280c5e) /* 0.290284677 */
#define costab27 (0x1f19f97b) /* 0.242980180 */
#define costab28 (0x18f8b83c) /* 0.195090322 */
#define costab29 (0x12c8106f) /* 0.146730474 */
#define costab30 (0x0c8bd35e) /* 0.098017140 */
#define costab31 (0x0647d97c) /* 0.049067674 */
t0 = in[ 0] + in[31]; t16 = MPC_DCT32_MUL(in[ 0] - in[31], costab01);
t1 = in[15] + in[16]; t17 = MPC_DCT32_MUL(in[15] - in[16], costab31);
t41 = t16 + t17;
t59 = MPC_DCT32_MUL(t16 - t17, costab02);
t33 = t0 + t1;
t50 = MPC_DCT32_MUL(t0 - t1, costab02);
t2 = in[ 7] + in[24]; t18 = MPC_DCT32_MUL(in[ 7] - in[24], costab15);
t3 = in[ 8] + in[23]; t19 = MPC_DCT32_MUL(in[ 8] - in[23], costab17);
t42 = t18 + t19;
t60 = MPC_DCT32_MUL(t18 - t19, costab30);
t34 = t2 + t3;
t51 = MPC_DCT32_MUL(t2 - t3, costab30);
t4 = in[ 3] + in[28]; t20 = MPC_DCT32_MUL(in[ 3] - in[28], costab07);
t5 = in[12] + in[19]; t21 = MPC_DCT32_MUL(in[12] - in[19], costab25);
t43 = t20 + t21;
t61 = MPC_DCT32_MUL(t20 - t21, costab14);
t35 = t4 + t5;
t52 = MPC_DCT32_MUL(t4 - t5, costab14);
t6 = in[ 4] + in[27]; t22 = MPC_DCT32_MUL(in[ 4] - in[27], costab09);
t7 = in[11] + in[20]; t23 = MPC_DCT32_MUL(in[11] - in[20], costab23);
t44 = t22 + t23;
t62 = MPC_DCT32_MUL(t22 - t23, costab18);
t36 = t6 + t7;
t53 = MPC_DCT32_MUL(t6 - t7, costab18);
t8 = in[ 1] + in[30]; t24 = MPC_DCT32_MUL(in[ 1] - in[30], costab03);
t9 = in[14] + in[17]; t25 = MPC_DCT32_MUL(in[14] - in[17], costab29);
t45 = t24 + t25;
t63 = MPC_DCT32_MUL(t24 - t25, costab06);
t37 = t8 + t9;
t54 = MPC_DCT32_MUL(t8 - t9, costab06);
t10 = in[ 6] + in[25]; t26 = MPC_DCT32_MUL(in[ 6] - in[25], costab13);
t11 = in[ 9] + in[22]; t27 = MPC_DCT32_MUL(in[ 9] - in[22], costab19);
t46 = t26 + t27;
t64 = MPC_DCT32_MUL(t26 - t27, costab26);
t38 = t10 + t11;
t55 = MPC_DCT32_MUL(t10 - t11, costab26);
t12 = in[ 2] + in[29]; t28 = MPC_DCT32_MUL(in[ 2] - in[29], costab05);
t13 = in[13] + in[18]; t29 = MPC_DCT32_MUL(in[13] - in[18], costab27);
t47 = t28 + t29;
t65 = MPC_DCT32_MUL(t28 - t29, costab10);
t39 = t12 + t13;
t56 = MPC_DCT32_MUL(t12 - t13, costab10);
t14 = in[ 5] + in[26]; t30 = MPC_DCT32_MUL(in[ 5] - in[26], costab11);
t15 = in[10] + in[21]; t31 = MPC_DCT32_MUL(in[10] - in[21], costab21);
t48 = t30 + t31;
t66 = MPC_DCT32_MUL(t30 - t31, costab22);
t40 = t14 + t15;
t57 = MPC_DCT32_MUL(t14 - t15, costab22);
t69 = t33 + t34; t89 = MPC_DCT32_MUL(t33 - t34, costab04);
t70 = t35 + t36; t90 = MPC_DCT32_MUL(t35 - t36, costab28);
t71 = t37 + t38; t91 = MPC_DCT32_MUL(t37 - t38, costab12);
t72 = t39 + t40; t92 = MPC_DCT32_MUL(t39 - t40, costab20);
t73 = t41 + t42; t94 = MPC_DCT32_MUL(t41 - t42, costab04);
t74 = t43 + t44; t95 = MPC_DCT32_MUL(t43 - t44, costab28);
t75 = t45 + t46; t96 = MPC_DCT32_MUL(t45 - t46, costab12);
t76 = t47 + t48; t97 = MPC_DCT32_MUL(t47 - t48, costab20);
t78 = t50 + t51; t100 = MPC_DCT32_MUL(t50 - t51, costab04);
t79 = t52 + t53; t101 = MPC_DCT32_MUL(t52 - t53, costab28);
t80 = t54 + t55; t102 = MPC_DCT32_MUL(t54 - t55, costab12);
t81 = t56 + t57; t103 = MPC_DCT32_MUL(t56 - t57, costab20);
t83 = t59 + t60; t106 = MPC_DCT32_MUL(t59 - t60, costab04);
t84 = t61 + t62; t107 = MPC_DCT32_MUL(t61 - t62, costab28);
t85 = t63 + t64; t108 = MPC_DCT32_MUL(t63 - t64, costab12);
t86 = t65 + t66; t109 = MPC_DCT32_MUL(t65 - t66, costab20);
t113 = t69 + t70;
t114 = t71 + t72;
/* 0 */ v[48] = -MPC_DCT32_SHIFT(t113 + t114);
/* 16 */ v[32] = -(v[ 0] = MPC_DCT32_SHIFT(MPC_DCT32_MUL(t113 - t114, costab16)));
t115 = t73 + t74;
t116 = t75 + t76;
t32 = t115 + t116;
/* 1 */ v[49] = v[47] = -MPC_DCT32_SHIFT(t32);
t118 = t78 + t79;
t119 = t80 + t81;
t58 = t118 + t119;
/* 2 */ v[50] = v[46] = -MPC_DCT32_SHIFT(t58);
t121 = t83 + t84;
t122 = t85 + t86;
t67 = t121 + t122;
t49 = (t67 * 2) - t32;
/* 3 */ v[51] = v[45] = -MPC_DCT32_SHIFT(t49);
t125 = t89 + t90;
t126 = t91 + t92;
t93 = t125 + t126;
/* 4 */ v[52] = v[44] = -MPC_DCT32_SHIFT(t93);
t128 = t94 + t95;
t129 = t96 + t97;
t98 = t128 + t129;
t68 = (t98 * 2) - t49;
/* 5 */ v[53] = v[43] = -MPC_DCT32_SHIFT(t68);
t132 = t100 + t101;
t133 = t102 + t103;
t104 = t132 + t133;
t82 = (t104 * 2) - t58;
/* 6 */ v[54] = v[42] = -MPC_DCT32_SHIFT(t82);
t136 = t106 + t107;
t137 = t108 + t109;
t110 = t136 + t137;
t87 = (t110 * 2) - t67;
t77 = (t87 * 2) - t68;
/* 7 */ v[55] = v[41] = -MPC_DCT32_SHIFT(t77);
t141 = MPC_DCT32_MUL(t69 - t70, costab08);
t142 = MPC_DCT32_MUL(t71 - t72, costab24);
t143 = t141 + t142;
/* 8 */ v[56] = v[40] = -MPC_DCT32_SHIFT(t143);
/* 24 */ v[24] = -(v[ 8] = MPC_DCT32_SHIFT((MPC_DCT32_MUL(t141 - t142, costab16) * 2) - t143));
t144 = MPC_DCT32_MUL(t73 - t74, costab08);
t145 = MPC_DCT32_MUL(t75 - t76, costab24);
t146 = t144 + t145;
t88 = (t146 * 2) - t77;
/* 9 */ v[57] = v[39] = -MPC_DCT32_SHIFT(t88);
t148 = MPC_DCT32_MUL(t78 - t79, costab08);
t149 = MPC_DCT32_MUL(t80 - t81, costab24);
t150 = t148 + t149;
t105 = (t150 * 2) - t82;
/* 10 */ v[58] = v[38] = -MPC_DCT32_SHIFT(t105);
t152 = MPC_DCT32_MUL(t83 - t84, costab08);
t153 = MPC_DCT32_MUL(t85 - t86, costab24);
t154 = t152 + t153;
t111 = (t154 * 2) - t87;
t99 = (t111 * 2) - t88;
/* 11 */ v[59] = v[37] = -MPC_DCT32_SHIFT(t99);
t157 = MPC_DCT32_MUL(t89 - t90, costab08);
t158 = MPC_DCT32_MUL(t91 - t92, costab24);
t159 = t157 + t158;
t127 = (t159 * 2) - t93;
/* 12 */ v[60] = v[36] = -MPC_DCT32_SHIFT(t127);
t160 = (MPC_DCT32_MUL(t125 - t126, costab16) * 2) - t127;
/* 20 */ v[28] = -(v[ 4] = MPC_DCT32_SHIFT(t160));
/* 28 */ v[20] = -(v[12] = MPC_DCT32_SHIFT((((MPC_DCT32_MUL(t157 - t158, costab16) * 2) - t159) * 2) - t160));
t161 = MPC_DCT32_MUL(t94 - t95, costab08);
t162 = MPC_DCT32_MUL(t96 - t97, costab24);
t163 = t161 + t162;
t130 = (t163 * 2) - t98;
t112 = (t130 * 2) - t99;
/* 13 */ v[61] = v[35] = -MPC_DCT32_SHIFT(t112);
t164 = (MPC_DCT32_MUL(t128 - t129, costab16) * 2) - t130;
t166 = MPC_DCT32_MUL(t100 - t101, costab08);
t167 = MPC_DCT32_MUL(t102 - t103, costab24);
t168 = t166 + t167;
t134 = (t168 * 2) - t104;
t120 = (t134 * 2) - t105;
/* 14 */ v[62] = v[34] = -MPC_DCT32_SHIFT(t120);
t135 = (MPC_DCT32_MUL(t118 - t119, costab16) * 2) - t120;
/* 18 */ v[30] = -(v[ 2] = MPC_DCT32_SHIFT(t135));
t169 = (MPC_DCT32_MUL(t132 - t133, costab16) * 2) - t134;
t151 = (t169 * 2) - t135;
/* 22 */ v[26] = -(v[ 6] = MPC_DCT32_SHIFT(t151));
t170 = (((MPC_DCT32_MUL(t148 - t149, costab16) * 2) - t150) * 2) - t151;
/* 26 */ v[22] = -(v[10] = MPC_DCT32_SHIFT(t170));
/* 30 */ v[18] = -(v[14] = MPC_DCT32_SHIFT((((((MPC_DCT32_MUL(t166 - t167, costab16) * 2) - t168) * 2) - t169) * 2) - t170));
t171 = MPC_DCT32_MUL(t106 - t107, costab08);
t172 = MPC_DCT32_MUL(t108 - t109, costab24);
t173 = t171 + t172;
t138 = (t173 * 2) - t110;
t123 = (t138 * 2) - t111;
t139 = (MPC_DCT32_MUL(t121 - t122, costab16) * 2) - t123;
t117 = (t123 * 2) - t112;
/* 15 */ v[63] = v[33] =-MPC_DCT32_SHIFT(t117);
t124 = (MPC_DCT32_MUL(t115 - t116, costab16) * 2) - t117;
/* 17 */ v[31] = -(v[ 1] = MPC_DCT32_SHIFT(t124));
t131 = (t139 * 2) - t124;
/* 19 */ v[29] = -(v[ 3] = MPC_DCT32_SHIFT(t131));
t140 = (t164 * 2) - t131;
/* 21 */ v[27] = -(v[ 5] = MPC_DCT32_SHIFT(t140));
t174 = (MPC_DCT32_MUL(t136 - t137, costab16) * 2) - t138;
t155 = (t174 * 2) - t139;
t147 = (t155 * 2) - t140;
/* 23 */ v[25] = -(v[ 7] = MPC_DCT32_SHIFT(t147));
t156 = (((MPC_DCT32_MUL(t144 - t145, costab16) * 2) - t146) * 2) - t147;
/* 25 */ v[23] = -(v[ 9] = MPC_DCT32_SHIFT(t156));
t175 = (((MPC_DCT32_MUL(t152 - t153, costab16) * 2) - t154) * 2) - t155;
t165 = (t175 * 2) - t156;
/* 27 */ v[21] = -(v[11] = MPC_DCT32_SHIFT(t165));
t176 = (((((MPC_DCT32_MUL(t161 - t162, costab16) * 2) - t163) * 2) - t164) * 2) - t165;
/* 29 */ v[19] = -(v[13] = MPC_DCT32_SHIFT(t176));
/* 31 */ v[17] = -(v[15] = MPC_DCT32_SHIFT((((((((MPC_DCT32_MUL(t171 - t172, costab16) * 2) - t173) * 2) - t174) * 2) - t175) * 2) - t176));
}
#if defined(CPU_ARM) || defined(CPU_COLDFIRE)
extern void
mpc_decoder_windowing_D(MPC_SAMPLE_FORMAT * Data,
const MPC_SAMPLE_FORMAT * V,
const MPC_SAMPLE_FORMAT * D);
#else
static void
mpc_decoder_windowing_D(MPC_SAMPLE_FORMAT * Data,
const MPC_SAMPLE_FORMAT * V,
const MPC_SAMPLE_FORMAT * D)
{
mpc_int32_t k;
// 64=64x64-multiply (FIXED_POINT) or float=float*float (!FIXED_POINT) in C
for ( k = 0; k < 32; k++, D += 16, V++ )
{
*Data = MPC_MULTIPLY_EX(V[ 0],D[ 0],30) + MPC_MULTIPLY_EX(V[ 96],D[ 1],30)
+ MPC_MULTIPLY_EX(V[128],D[ 2],30) + MPC_MULTIPLY_EX(V[224],D[ 3],30)
+ MPC_MULTIPLY_EX(V[256],D[ 4],30) + MPC_MULTIPLY_EX(V[352],D[ 5],30)
+ MPC_MULTIPLY_EX(V[384],D[ 6],30) + MPC_MULTIPLY_EX(V[480],D[ 7],30)
+ MPC_MULTIPLY_EX(V[512],D[ 8],30) + MPC_MULTIPLY_EX(V[608],D[ 9],30)
+ MPC_MULTIPLY_EX(V[640],D[10],30) + MPC_MULTIPLY_EX(V[736],D[11],30)
+ MPC_MULTIPLY_EX(V[768],D[12],30) + MPC_MULTIPLY_EX(V[864],D[13],30)
+ MPC_MULTIPLY_EX(V[896],D[14],30) + MPC_MULTIPLY_EX(V[992],D[15],30);
Data += 1;
// total: 16 muls, 15 adds, 16 shifts
}
}
#endif /* CPU_ARM || CPU_COLDFIRE */
static void
mpc_full_synthesis_filter(MPC_SAMPLE_FORMAT *OutData, MPC_SAMPLE_FORMAT *V,
const MPC_SAMPLE_FORMAT *Y) ICODE_ATTR_MPC_LARGE_IRAM;
static void
mpc_full_synthesis_filter(MPC_SAMPLE_FORMAT *OutData, MPC_SAMPLE_FORMAT *V,
const MPC_SAMPLE_FORMAT *Y)
{
mpc_uint32_t n;
if (NULL != OutData)
{
for ( n = 0; n < 36; n++, Y += 32, OutData += 32 )
{
V -= 64;
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,
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));
/******** 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));
}
/*******************************************/
/* */
/* dithered synthesis */
/* */
/*******************************************/
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,
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,
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,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
};
/*
* This is a simple random number generator with good quality for audio purposes.
* It consists of two polycounters with opposite rotation direction and different
* periods. The periods are coprime, so the total period is the product of both.
*
* -------------------------------------------------------------------------------------------------
* +-> |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0|
* | -------------------------------------------------------------------------------------------------
* | | | | | | |
* | +--+--+--+-XOR-+--------+
* | |
* +--------------------------------------------------------------------------------------+
*
* -------------------------------------------------------------------------------------------------
* |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| <-+
* ------------------------------------------------------------------------------------------------- |
* | | | | |
* +--+----XOR----+--+ |
* | |
* +----------------------------------------------------------------------------------------+
*
*
* The first has an period of 3*5*17*257*65537, the second of 7*47*73*178481,
* which gives a period of 18.410.713.077.675.721.215. The result is the
* XORed values of both generators.
*/
mpc_uint32_t
mpc_random_int(mpc_decoder *d)
{
#if 1
mpc_uint32_t t1, t2, t3, t4;
t3 = t1 = d->__r1; t4 = t2 = d->__r2; // Parity calculation is done via table lookup, this is also available
t1 &= 0xF5; t2 >>= 25; // on CPUs without parity, can be implemented in C and avoid unpredictable
t1 = Parity [t1]; t2 &= 0x63; // jumps and slow rotate through the carry flag operations.
t1 <<= 31; t2 = Parity [t2];
return (d->__r1 = (t3 >> 1) | t1 ) ^ (d->__r2 = (t4 + t4) | t2 );
#else
return (d->__r1 = (d->__r1 >> 1) | ((mpc_uint32_t)Parity [d->__r1 & 0xF5] << 31) ) ^
(d->__r2 = (d->__r2 << 1) | (mpc_uint32_t)Parity [(d->__r2 >> 25) & 0x63] );
#endif
}

View file

@ -0,0 +1,693 @@
/***************************************************************************
* __________ __ ___.
* 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.
*
****************************************************************************/
#include "config.h"
#if defined(CPU_S5L870X)
/* Moving this asm routine to iram is (little) faster on S5L870x. */
.section .icode, "ax", %progbits
#else
.section .text, "ax", %progbits
#endif
/****************************************************************************
* void mpc_decoder_windowing_D(...)
*
* 2nd step within synthesis filter. Does the dewindowing.
* 64=32x32 multiplies
* Uses un-shifted D[]-values. D[] will always be the second operand of
* smull/smlal to achieve higher speed as D[] has lower amplitude than V[].
****************************************************************************/
.align 2
.global mpc_decoder_windowing_D
.type mpc_decoder_windowing_D, %function
#if 0
mpc_decoder_windowing_D:
/* r0 = Data[] */
/* r1 = V[] */
/* r2 = D[] */
/* lr = counter */
/************************************************************************
* Reference implementation.
***********************************************************************/
stmfd sp!, {r4-r8, lr}
mov lr, #32
.loop32:
ldmia r2!, { r3-r6 } /* load D[00..03] */
ldr r7, [r1] /* 0 */
smull r8, r12, r7, r3
ldr r7, [r1, #96*4] /* 1 */
smlal r8, r12, r7, r4
ldr r7, [r1, #128*4] /* 2 */
smlal r8, r12, r7, r5
ldr r7, [r1, #224*4] /* 3 */
smlal r8, r12, r7, r6
ldmia r2!, { r3-r6 } /* load D[04..07] */
ldr r7, [r1, #256*4] /* 4 */
smlal r8, r12, r7, r3
ldr r7, [r1, #352*4] /* 5 */
smlal r8, r12, r7, r4
ldr r7, [r1, #384*4] /* 6 */
smlal r8, r12, r7, r5
ldr r7, [r1, #480*4] /* 7 */
smlal r8, r12, r7, r6
ldmia r2!, { r3-r6 } /* load D[08..11] */
ldr r7, [r1, #512*4] /* 8 */
smlal r8, r12, r7, r3
ldr r7, [r1, #608*4] /* 9 */
smlal r8, r12, r7, r4
ldr r7, [r1, #640*4] /* 10 */
smlal r8, r12, r7, r5
ldr r7, [r1, #736*4] /* 11 */
smlal r8, r12, r7, r6
ldmia r2!, { r3-r6 } /* load D[12..15] */
ldr r7, [r1, #768*4] /* 12 */
smlal r8, r12, r7, r3
ldr r7, [r1, #864*4] /* 13 */
smlal r8, r12, r7, r4
ldr r7, [r1, #896*4] /* 14 */
smlal r8, r12, r7, r5
ldr r7, [r1, #992*4] /* 15 */
smlal r8, r12, r7, r6
mov r8, r8, lsr #16
orr r8, r8, r12, lsl #16 /* (lo>>16) || (hi<<16) */
str r8, [r0], #4 /* store Data */
add r1, r1, #4 /* V++ */
subs lr, lr, #1
bgt .loop32
ldmpc regs=r4-r8
#elif defined(CPU_ARM7TDMI) /* arm7 only */
mpc_decoder_windowing_D:
/* r0 = Data[] */
/* r1 = V[] */
/* r2 = D[] */
/* lr = counter */
/************************************************************************
* Further speed up through making use of symmetries within D[]-window.
* The row V[00] can be extracted as it has symmetries within this single
* row. 8 smull/mlal and 8 ldr's can be saved at the cost of 2 add's.
* The rows V[01..15] are symmetric to V[31..17]. 15 x 16 ldr's can be
* saved at the cost of 15 x 4 + 1 add's.
* The row V[16] can be extracted as it has symmetries within this single
* row. 8 smull/mlal and 8 ldr's can be saved.
* Used for arm7 only. For arm9 and above see implementation below.
***********************************************************************/
stmfd sp!, {r4-r11, lr}
/******************************************
* row 0 with internal symmetry
*****************************************/
add r2, r2, #4 /* D+=1, r2 = D[01] as D[00] = 0 */
ldmia r2!, { r3-r6 } /* load D[01..04] */
ldr r7 , [r1, #96*4] /* 1 */
ldr r10, [r1, #992*4] /* 15 */
rsb r10, r10, r7 /* V[01] - V[15] */
smull r8, r9, r10, r3
ldr r7 , [r1, #128*4] /* 2 */
ldr r10, [r1, #896*4] /* 14 */
add r10, r10, r7 /* V[02] + V[14] */
smlal r8, r9, r10, r4
ldr r7 , [r1, #224*4] /* 3 */
ldr r10, [r1, #864*4] /* 13 */
rsb r10, r10, r7 /* V[03] - V[13] */
smlal r8, r9, r10, r5
ldr r7 , [r1, #256*4] /* 4 */
ldr r10, [r1, #768*4] /* 12 */
add r10, r10, r7 /* V[04] + V[12] */
smlal r8, r9, r10, r6
ldmia r2!, { r3-r6 } /* load D[05..08] */
ldr r7 , [r1, #352*4] /* 5 */
ldr r10, [r1, #736*4] /* 11 */
rsb r10, r10, r7 /* V[05] - V[11] */
smlal r8, r9, r10, r3
ldr r7 , [r1, #384*4] /* 6 */
ldr r10, [r1, #640*4] /* 10 */
add r10, r10, r7 /* V[06] + V[10] */
smlal r8, r9, r10, r4
ldr r7 , [r1, #480*4] /* 7 */
ldr r10, [r1, #608*4] /* 9 */
rsb r10, r10, r7 /* V[07] - V[09] */
smlal r8, r9, r10, r5
ldr r10, [r1, #512*4] /* 8 */
smlal r8, r9, r10, r6
mov r8, r8, lsr #16
orr r8, r8, r9, lsl #16 /* (lo>>16) || (hi<<16) */
str r8, [r0], #4 /* store Data */
add r1, r1, #4 /* V+=1, r1 = V[01] */
add r2, r2, #7*4 /* D+=7, r2 = D[16] */
/******************************************
* rows 01..15 are symmetric to rows 31..17
* r8 = lo, r9 = hi of 01..15
* r1 = V[01..15]
* r10 = lo, r11 = hi of 31..17
* r12 = V[31..16]
*****************************************/
mov lr, #15*8
add r12, r1, #30*4 /* r12 = V[31] */
.loop15:
ldmia r2!, { r3-r6 } /* load D[00..03] */
ldr r7, [r12, #768*4] /* 12 */
smull r10, r11, r7, r6
ldr r7, [r12, #864*4] /* 13 */
smlal r10, r11, r7, r5
ldr r7, [r12, #896*4] /* 14 */
smlal r10, r11, r7, r4
ldr r7, [r12, #992*4] /* 15 */
smlal r10, r11, r7, r3
ldr r7, [r1] /* 0 */
smull r8, r9, r7, r3
ldr r7, [r1, #96*4] /* 1 */
smlal r8, r9, r7, r4
ldr r7, [r1, #128*4] /* 2 */
smlal r8, r9, r7, r5
ldr r7, [r1, #224*4] /* 3 */
smlal r8, r9, r7, r6
ldmia r2!, { r3-r6 } /* load D[04..07] */
ldr r7, [r1, #256*4] /* 4 */
smlal r8, r9, r7, r3
ldr r7, [r1, #352*4] /* 5 */
smlal r8, r9, r7, r4
ldr r7, [r1, #384*4] /* 6 */
smlal r8, r9, r7, r5
ldr r7, [r1, #480*4] /* 7 */
smlal r8, r9, r7, r6
ldr r7, [r12, #512*4] /* 8 */
smlal r10, r11, r7, r6
ldr r7, [r12, #608*4] /* 9 */
smlal r10, r11, r7, r5
ldr r7, [r12, #640*4] /* 10 */
smlal r10, r11, r7, r4
ldr r7, [r12, #736*4] /* 11 */
smlal r10, r11, r7, r3
ldmia r2!, { r3-r6 } /* load D[08..11] */
ldr r7, [r12, #256*4] /* 4 */
smlal r10, r11, r7, r6
ldr r7, [r12, #352*4] /* 5 */
smlal r10, r11, r7, r5
ldr r7, [r12, #384*4] /* 6 */
smlal r10, r11, r7, r4
ldr r7, [r12, #480*4] /* 7 */
smlal r10, r11, r7, r3
ldr r7, [r1, #512*4] /* 8 */
smlal r8, r9, r7, r3
ldr r7, [r1, #608*4] /* 9 */
smlal r8, r9, r7, r4
ldr r7, [r1, #640*4] /* 10 */
smlal r8, r9, r7, r5
ldr r7, [r1, #736*4] /* 11 */
smlal r8, r9, r7, r6
ldmia r2!, { r3-r6 } /* load D[12..15] */
ldr r7, [r1, #768*4] /* 12 */
smlal r8, r9, r7, r3
ldr r7, [r1, #864*4] /* 13 */
smlal r8, r9, r7, r4
ldr r7, [r1, #896*4] /* 14 */
smlal r8, r9, r7, r5
ldr r7, [r1, #992*4] /* 15 */
smlal r8, r9, r7, r6
ldr r7, [r12] /* 0 */
smlal r10, r11, r7, r6
ldr r7, [r12, #96*4] /* 1 */
smlal r10, r11, r7, r5
ldr r7, [r12, #128*4] /* 2 */
smlal r10, r11, r7, r4
ldr r7, [r12, #224*4] /* 3 */
smlal r10, r11, r7, r3
/* store Data[01..15] */
mov r8, r8, lsr #16
orr r8, r8, r9, lsl #16 /* (lo>>16) || (hi<<16) */
/* store Data[31..17] */
mov r10, r10, lsr #16
orr r10, r10, r11, lsl #16 /* (lo>>16) || (hi<<16) */
rsb r10, r10, #0 /* r10 = -r10 */
str r10, [r0, lr] /* store Data */
str r8, [r0], #4 /* store Data */
/* correct adresses for next loop */
sub r12, r12, #4 /* r12 = V-- */
add r1, r1, #4 /* r1 = V++ */
/* next loop */
subs lr, lr, #8
bgt .loop15
/******************************************
* V[16] with internal symmetry
*****************************************/
ldmia r2!, { r3-r6 } /* load D[00..03] */
ldr r7 , [r1] /* 0 */
ldr r10, [r1, #992*4] /* 15 */
rsb r10, r10, r7 /* V[00] - V[15] */
smull r8, r9, r10, r3
ldr r7 , [r1, #96*4] /* 1 */
ldr r10, [r1, #896*4] /* 14 */
rsb r10, r10, r7 /* V[01] - V[14] */
smlal r8, r9, r10, r4
ldr r7 , [r1, #128*4] /* 2 */
ldr r10, [r1, #864*4] /* 13 */
rsb r10, r10, r7 /* V[02] - V[13] */
smlal r8, r9, r10, r5
ldr r7 , [r1, #224*4] /* 3 */
ldr r10, [r1, #768*4] /* 12 */
rsb r10, r10, r7 /* V[03] - V[12] */
smlal r8, r9, r10, r6
ldmia r2!, { r3-r6 } /* load D[04..07] */
ldr r7 , [r1, #256*4] /* 4 */
ldr r10, [r1, #736*4] /* 11 */
rsb r10, r10, r7 /* V[04] - V[11] */
smlal r8, r9, r10, r3
ldr r7 , [r1, #352*4] /* 5 */
ldr r10, [r1, #640*4] /* 10 */
rsb r10, r10, r7 /* V[05] - V[10] */
smlal r8, r9, r10, r4
ldr r7 , [r1, #384*4] /* 6 */
ldr r10, [r1, #608*4] /* 9 */
rsb r10, r10, r7 /* V[06] - V[09] */
smlal r8, r9, r10, r5
ldr r7 , [r1, #480*4] /* 7 */
ldr r10, [r1, #512*4] /* 8 */
rsb r10, r10, r7 /* V[07] - V[08] */
smlal r8, r9, r10, r6
mov r8, r8, lsr #16
orr r8, r8, r9, lsl #16 /* (lo>>16) || (hi<<16) */
str r8, [r0], #4 /* store Data */
ldmpc regs=r4-r11
#elif ARM_ARCH < 6 /* arm9 and above */
mpc_decoder_windowing_D:
/* r0 = Data[] */
/* r1 = V[] */
/* r2 = D[] */
/* lr = counter */
/************************************************************************
* Further speed up through making use of symmetries within D[]-window.
* The row V[00] can be extracted as it has symmetries within this single
* row. 8 smull/mlal and 8 ldr's can be saved at the cost of 2 add's.
* The rows V[01..15] are symmetric to V[31..17]. 15 x 16 ldr's can be
* saved at the cost of 15 x 4 + 1 add's.
* The row V[16] can be extracted as it has symmetries within this single
* row. 8 smull/mlal and 8 ldr's can be saved.
* On arm9 (still armv4 architecture) reducing stalls after ldr/ldm speeds
* up decoding even though several ldm-calls are replaced with ldr to free
* 2 registers.
***********************************************************************/
stmfd sp!, {r4-r11, lr}
/******************************************
* row 0 with internal symmetry
*****************************************/
add r2, r2, #4 /* D+=1, r2 = D[01] as D[00] = 0 */
ldmia r2!, { r3-r6 } /* load D[01..04] */
ldr r7 , [r1, #96*4] /* 1 */
ldr r10, [r1, #992*4] /* 15 */
ldr r11, [r1, #128*4] /* 2 */
ldr r12, [r1, #896*4] /* 14 */
rsb r10, r10, r7 /* V[01] - V[15] */
smull r8, r9, r10, r3
ldr r7 , [r1, #224*4] /* 3 */
ldr r10, [r1, #864*4] /* 13 */
add r12, r12, r11 /* V[02] + V[14] */
smlal r8, r9, r12, r4
ldr r11, [r1, #256*4] /* 4 */
ldr r12, [r1, #768*4] /* 12 */
rsb r10, r10, r7 /* V[03] - V[13] */
smlal r8, r9, r10, r5
ldr r7 , [r1, #352*4] /* 5 */
ldr r10, [r1, #736*4] /* 11 */
add r12, r12, r11 /* V[04] + V[12] */
smlal r8, r9, r12, r6
ldmia r2!, { r3-r6 } /* load D[05..08] */
ldr r11, [r1, #384*4] /* 6 */
ldr r12, [r1, #640*4] /* 10 */
rsb r10, r10, r7 /* V[05] - V[11] */
smlal r8, r9, r10, r3
ldr r7 , [r1, #480*4] /* 7 */
ldr r10, [r1, #608*4] /* 9 */
add r12, r12, r11 /* V[06] + V[10] */
smlal r8, r9, r12, r4
ldr r11, [r1, #512*4] /* 8 */
rsb r10, r10, r7 /* V[07] - V[09] */
smlal r8, r9, r10, r5
smlal r8, r9, r11, r6
mov r8, r8, lsr #16
orr r8, r8, r9, lsl #16 /* (lo>>16) || (hi<<16) */
str r8, [r0], #4 /* store Data */
add r1, r1, #4 /* V+=1, r1 = V[01] */
add r2, r2, #7*4 /* D+=7, r2 = D[16] */
/******************************************
* rows 01..15 are symmetric to rows 31..17
* r8 = lo, r9 = hi of 01..15
* r1 = V[01..15]
* r10 = lo, r11 = hi of 31..17
* r12 = V[31..16]
*****************************************/
mov lr, #15*8
add r12, r1, #30*4 /* r12 = V[31] */
.loop15:
ldmia r2!, { r3-r4 } /* load D[00..01] */
ldr r7, [r12, #896*4] /* 14 */
ldr r5, [r12, #992*4] /* 15 */
smull r10, r11, r7, r4
ldr r7, [r1] /* 0 */
smlal r10, r11, r5, r3
ldr r5, [r1, #96*4] /* 1 */
smull r8, r9, r7, r3
ldr r7, [r12, #768*4] /* 12 */
smlal r8, r9, r5, r4
ldmia r2!, { r3-r4 } /* load D[02..03] */
ldr r5, [r12, #864*4] /* 13 */
smlal r10, r11, r7, r4
ldr r7, [r1, #128*4] /* 2 */
smlal r10, r11, r5, r3
ldr r5, [r1, #224*4] /* 3 */
smlal r8, r9, r7, r3
ldr r7, [r1, #256*4] /* 4 */
smlal r8, r9, r5, r4
ldmia r2!, { r3-r4 } /* load D[04..04] */
ldr r5, [r1, #352*4] /* 5 */
smlal r8, r9, r7, r3
ldr r7, [r12, #640*4] /* 10 */
smlal r8, r9, r5, r4
ldr r5, [r12, #736*4] /* 11 */
smlal r10, r11, r7, r4
ldr r7, [r1, #384*4] /* 6 */
smlal r10, r11, r5, r3
ldmia r2!, { r3-r4 } /* load D[06..07] */
ldr r5, [r1, #480*4] /* 7 */
smlal r8, r9, r7, r3
ldr r7, [r12, #512*4] /* 8 */
smlal r8, r9, r5, r4
ldr r5, [r12, #608*4] /* 9 */
smlal r10, r11, r7, r4
ldr r7, [r12, #384*4] /* 6 */
smlal r10, r11, r5, r3
ldmia r2!, { r3-r4 } /* load D[08..09] */
ldr r5, [r12, #480*4] /* 7 */
smlal r10, r11, r7, r4
ldr r7, [r1, #512*4] /* 8 */
smlal r10, r11, r5, r3
ldr r5, [r1, #608*4] /* 9 */
smlal r8, r9, r7, r3
ldr r7, [r1, #640*4] /* 10 */
smlal r8, r9, r5, r4
ldmia r2!, { r3-r4 } /* load D[10..11] */
ldr r5, [r1, #736*4] /* 11 */
smlal r8, r9, r7, r3
ldr r7, [r12, #256*4] /* 4 */
smlal r8, r9, r5, r4
ldr r5, [r12, #352*4] /* 5 */
smlal r10, r11, r7, r4
ldr r7, [r1, #768*4] /* 12 */
smlal r10, r11, r5, r3
ldmia r2!, { r3-r4 } /* load D[12..13] */
ldr r5, [r1, #864*4] /* 13 */
smlal r8, r9, r7, r3
ldr r7, [r12, #128*4] /* 2 */
smlal r8, r9, r5, r4
ldr r5, [r12, #224*4] /* 3 */
smlal r10, r11, r7, r4
ldr r7, [r12] /* 0 */
smlal r10, r11, r5, r3
ldmia r2!, { r3-r4 } /* load D[14..15] */
ldr r5, [r12, #96*4] /* 1 */
smlal r10, r11, r7, r4
ldr r7, [r1, #896*4] /* 14 */
smlal r10, r11, r5, r3
ldr r5, [r1, #992*4] /* 15 */
smlal r8, r9, r7, r3
smlal r8, r9, r5, r4
/* store Data[01..15] */
mov r8, r8, lsr #16
orr r8, r8, r9, lsl #16 /* (lo>>16) || (hi<<16) */
/* store Data[31..17] */
mov r10, r10, lsr #16
orr r10, r10, r11, lsl #16 /* (lo>>16) || (hi<<16) */
rsb r10, r10, #0 /* r10 = -r10 */
str r10, [r0, lr] /* store Data */
str r8, [r0], #4 /* store Data */
/* correct adresses for next loop */
sub r12, r12, #4 /* r12 = V-- */
add r1, r1, #4 /* r1 = V++ */
/* next loop */
subs lr, lr, #8
bgt .loop15
/******************************************
* V[16] with internal symmetry
*****************************************/
ldmia r2!, { r3-r6 } /* load D[00..03] */
ldr r7 , [r1] /* 0 */
ldr r10, [r1, #992*4] /* 15 */
ldr r11, [r1, #96*4] /* 1 */
ldr r12, [r1, #896*4] /* 14 */
rsb r10, r10, r7 /* V[00] - V[15] */
smull r8, r9, r10, r3
ldr r7 , [r1, #128*4] /* 2 */
ldr r10, [r1, #864*4] /* 13 */
rsb r12, r12, r11 /* V[01] - V[14] */
smlal r8, r9, r12, r4
ldr r11, [r1, #224*4] /* 3 */
ldr r12, [r1, #768*4] /* 12 */
rsb r10, r10, r7 /* V[02] - V[13] */
smlal r8, r9, r10, r5
ldr r7 , [r1, #256*4] /* 4 */
ldr r10, [r1, #736*4] /* 11 */
rsb r12, r12, r11 /* V[03] - V[12] */
smlal r8, r9, r12, r6
ldmia r2!, { r3-r6 } /* load D[04..07] */
ldr r11, [r1, #352*4] /* 5 */
ldr r12, [r1, #640*4] /* 10 */
rsb r10, r10, r7 /* V[04] - V[11] */
smlal r8, r9, r10, r3
ldr r7 , [r1, #384*4] /* 6 */
ldr r10, [r1, #608*4] /* 9 */
rsb r12, r12, r11 /* V[05] - V[10] */
smlal r8, r9, r12, r4
ldr r11, [r1, #480*4] /* 7 */
ldr r12, [r1, #512*4] /* 8 */
rsb r10, r10, r7 /* V[06] - V[09] */
smlal r8, r9, r10, r5
rsb r12, r12, r11 /* V[07] - V[08] */
smlal r8, r9, r12, r6
mov r8, r8, lsr #16
orr r8, r8, r9, lsl #16 /* (lo>>16) || (hi<<16) */
str r8, [r0], #4 /* store Data */
ldmpc regs=r4-r11
#else
mpc_decoder_windowing_D:
/* r0 = Data[] */
/* r1 = V[] */
/* r2 = D[] */
/* lr = counter */
/************************************************************************
* Further speed up through making use of symmetries within D[]-window.
* The row V[00] can be extracted as it has symmetries within this single
* row. 8 smull/mlal and 8 ldr's can be saved at the cost of 2 add's.
* The rows V[01..15] are symmetric to V[31..17]. 15 x 16 ldr's can be
* saved at the cost of 15 x 4 + 1 add's.
* The row V[16] can be extracted as it has symmetries within this single
* row. 8 smull/mlal and 8 ldr's can be saved.
* On armv6 use smmulr/smlalr which are faster than smull/smlal and only
* accumulate the top 32 bits of the result so that frees up 2
* registers so we can ldm larger blocks.
***********************************************************************/
stmfd sp!, {r4-r11, lr}
/******************************************
* row 0 with internal symmetry
*****************************************/
add r2, r2, #4 /* D+=1, r2 = D[01] as D[00] = 0 */
ldmia r2!, { r3-r6 } /* load D[01..04] */
ldr r7 , [r1, #96*4] /* 1 */
ldr r10, [r1, #992*4] /* 15 */
ldr r11, [r1, #128*4] /* 2 */
rsb r10, r10, r7 /* V[01] - V[15] */
ldr r12, [r1, #896*4] /* 14 */
smmulr r9, r10, r3
ldr r7 , [r1, #224*4] /* 3 */
add r12, r12, r11 /* V[02] + V[14] */
ldr r10, [r1, #864*4] /* 13 */
smmlar r9, r12, r4, r9
ldr r11, [r1, #256*4] /* 4 */
rsb r10, r10, r7 /* V[03] - V[13] */
ldr r12, [r1, #768*4] /* 12 */
smmlar r9, r10, r5, r9
ldr r7 , [r1, #352*4] /* 5 */
add r12, r12, r11 /* V[04] + V[12] */
ldr r10, [r1, #736*4] /* 11 */
smmlar r9, r12, r6, r9
ldmia r2!, { r3-r6 } /* load D[05..08] */
ldr r11, [r1, #384*4] /* 6 */
rsb r10, r10, r7 /* V[05] - V[11] */
ldr r12, [r1, #640*4] /* 10 */
smmlar r9, r10, r3, r9
ldr r7 , [r1, #480*4] /* 7 */
add r12, r12, r11 /* V[06] + V[10] */
ldr r10, [r1, #608*4] /* 9 */
smmlar r9, r12, r4, r9
rsb r10, r10, r7 /* V[07] - V[09] */
ldr r11, [r1, #512*4] /* 8 */
smmlar r9, r10, r5, r9
add r1, r1, #4 /* V+=1, r1 = V[01] */
smmlar r9, r11, r6, r9
add r2, r2, #7*4 /* D+=7, r2 = D[16] */
mov r9, r9, lsl #2
str r9, [r0], #4 /* store Data */
/******************************************
* rows 01..15 are symmetric to rows 31..17
* r9 = acc of 01..15
* r1 = V[01..15]
* r11 = acc of 31..17
* r12 = V[31..16]
*****************************************/
mov lr, #15*8
add r12, r1, #30*4 /* r12 = V[31] */
.loop15:
ldmia r2!, { r3-r6 } /* load D[00..03] */
ldr r7, [r12, #896*4] /* 14 */
ldr r8, [r12, #992*4] /* 15 */
smmulr r11, r7, r4
ldr r7, [r1] /* 0 */
smmlar r11, r8, r3, r11
ldr r8, [r1, #96*4] /* 1 */
smmulr r9, r7, r3
ldr r7, [r12, #768*4] /* 12 */
smmlar r9, r8, r4, r9
ldr r8, [r12, #864*4] /* 13 */
smmlar r11, r7, r6, r11
ldr r7, [r1, #128*4] /* 2 */
smmlar r11, r8, r5, r11
ldr r8, [r1, #224*4] /* 3 */
smmlar r9, r7, r5, r9
ldr r7, [r1, #256*4] /* 4 */
smmlar r9, r8, r6, r9
ldmia r2!, { r3-r6 } /* load D[04..07] */
ldr r8, [r1, #352*4] /* 5 */
smmlar r9, r7, r3, r9
ldr r7, [r12, #640*4] /* 10 */
smmlar r9, r8, r4, r9
ldr r8, [r12, #736*4] /* 11 */
smmlar r11, r7, r4, r11
ldr r7, [r1, #384*4] /* 6 */
smmlar r11, r8, r3, r11
ldr r8, [r1, #480*4] /* 7 */
smmlar r9, r7, r5, r9
ldr r7, [r12, #512*4] /* 8 */
smmlar r9, r8, r6, r9
ldr r8, [r12, #608*4] /* 9 */
smmlar r11, r7, r6, r11
ldr r7, [r12, #384*4] /* 6 */
smmlar r11, r8, r5, r11
ldmia r2!, { r3-r6 } /* load D[08..11] */
ldr r8, [r12, #480*4] /* 7 */
smmlar r11, r7, r4, r11
ldr r7, [r1, #512*4] /* 8 */
smmlar r11, r8, r3, r11
ldr r8, [r1, #608*4] /* 9 */
smmlar r9, r7, r3, r9
ldr r7, [r1, #640*4] /* 10 */
smmlar r9, r8, r4, r9
ldr r8, [r1, #736*4] /* 11 */
smmlar r9, r7, r5, r9
ldr r7, [r12, #256*4] /* 4 */
smmlar r9, r8, r6, r9
ldr r8, [r12, #352*4] /* 5 */
smmlar r11, r7, r6, r11
ldr r7, [r1, #768*4] /* 12 */
smmlar r11, r8, r5, r11
ldmia r2!, { r3-r6 } /* load D[12..15] */
ldr r8, [r1, #864*4] /* 13 */
smmlar r9, r7, r3, r9
ldr r7, [r12, #128*4] /* 2 */
smmlar r9, r8, r4, r9
ldr r8, [r12, #224*4] /* 3 */
smmlar r11, r7, r4, r11
ldr r7, [r12] /* 0 */
smmlar r11, r8, r3, r11
ldr r8, [r12, #96*4] /* 1 */
smmlar r11, r7, r6, r11
ldr r7, [r1, #896*4] /* 14 */
smmlar r11, r8, r5, r11
ldr r8, [r1, #992*4] /* 15 */
smmlar r9, r7, r5, r9
sub r12, r12, #4 /* r12 = V-- correct adresses for next loop */
smmlar r9, r8, r6, r9
add r1, r1, #4 /* r1 = V++ correct adresses for next loop */
rsb r11, r11, #0 /* r11 = -r11 */
/* store Data[01..15] */
mov r9, r9, lsl #2
/* store Data[31..17] */
mov r11, r11, lsl #2
str r11, [r0, lr] /* store Data */
str r9, [r0], #4 /* store Data */
/* next loop */
subs lr, lr, #8
bgt .loop15
/******************************************
* V[16] with internal symmetry
*****************************************/
ldmia r2!, { r3-r6 } /* load D[00..03] */
ldr r7 , [r1] /* 0 */
ldr r10, [r1, #992*4] /* 15 */
ldr r11, [r1, #96*4] /* 1 */
rsb r10, r10, r7 /* V[00] - V[15] */
ldr r12, [r1, #896*4] /* 14 */
smmulr r9, r10, r3
ldr r7 , [r1, #128*4] /* 2 */
rsb r12, r12, r11 /* V[01] - V[14] */
ldr r10, [r1, #864*4] /* 13 */
smmlar r9, r12, r4, r9
ldr r11, [r1, #224*4] /* 3 */
rsb r10, r10, r7 /* V[02] - V[13] */
ldr r12, [r1, #768*4] /* 12 */
smmlar r9, r10, r5, r9
ldr r7 , [r1, #256*4] /* 4 */
rsb r12, r12, r11 /* V[03] - V[12] */
ldr r10, [r1, #736*4] /* 11 */
smmlar r9, r12, r6, r9
ldmia r2!, { r3-r6 } /* load D[04..07] */
ldr r11, [r1, #352*4] /* 5 */
rsb r10, r10, r7 /* V[04] - V[11] */
ldr r12, [r1, #640*4] /* 10 */
smmlar r9, r10, r3, r9
ldr r7 , [r1, #384*4] /* 6 */
rsb r12, r12, r11 /* V[05] - V[10] */
ldr r10, [r1, #608*4] /* 9 */
smmlar r9, r12, r4, r9
ldr r11, [r1, #480*4] /* 7 */
rsb r10, r10, r7 /* V[06] - V[09] */
ldr r12, [r1, #512*4] /* 8 */
smmlar r9, r10, r5, r9
rsb r12, r12, r11 /* V[07] - V[08] */
smmlar r9, r12, r6, r9
mov r9, r9, lsl #2
str r9, [r0], #4 /* store Data */
ldmpc regs=r4-r11
#endif
.mpc_dewindowing_end:
.size mpc_decoder_windowing_D,.mpc_dewindowing_end-mpc_decoder_windowing_D

View file

@ -0,0 +1,78 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2005 by Thom Johansen
*
* 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.
*
****************************************************************************/
#include "config.h"
/*
* static void
* mpc_decoder_windowing_D(MPC_SAMPLE_FORMAT * Data,
* const MPC_SAMPLE_FORMAT * V,
* const MPC_SAMPLE_FORMAT * D)
*/
#if defined(USE_IRAM)
.section .icode
#else
.text
#endif
.align 2
.global mpc_decoder_windowing_D
.type mpc_decoder_windowing_D, @function
mpc_decoder_windowing_D:
lea.l (-9*4, %sp), %sp
movem.l %d2-%d7/%a2-%a4, (%sp) | save some registers
movem.l (9*4+4, %sp), %a0-%a2 | a0 = Data, a1 = V, a2 = D
moveq.l #32, %d0 | loop counter
move.l (%a1), %a4
0: | loop
movem.l (%a2), %d1-%d7/%a3
mac.l %d1, %a4, ( 96*4, %a1), %a4, %acc0
mac.l %d2, %a4, (128*4, %a1), %a4, %acc0
mac.l %d3, %a4, (224*4, %a1), %a4, %acc0
mac.l %d4, %a4, (256*4, %a1), %a4, %acc0
mac.l %d5, %a4, (352*4, %a1), %a4, %acc0
mac.l %d6, %a4, (384*4, %a1), %a4, %acc0
mac.l %d7, %a4, (480*4, %a1), %a4, %acc0
mac.l %a3, %a4, (512*4, %a1), %a4, %acc0
movem.l (8*4, %a2), %d1-%d7/%a3
mac.l %d1, %a4, (608*4, %a1), %a4, %acc0
mac.l %d2, %a4, (640*4, %a1), %a4, %acc0
mac.l %d3, %a4, (736*4, %a1), %a4, %acc0
mac.l %d4, %a4, (768*4, %a1), %a4, %acc0
mac.l %d5, %a4, (864*4, %a1), %a4, %acc0
mac.l %d6, %a4, (896*4, %a1), %a4, %acc0
mac.l %d7, %a4, (992*4, %a1), %a4, %acc0
mac.l %a3, %a4, ( 4, %a1), %a4, %acc0
lea.l (16*4, %a2), %a2
addq.l #4, %a1
movclr.l %acc0, %d1
lsl.l #1, %d1
move.l %d1, (%a0)+
subq.l #1, %d0
bne 0b
movem.l (%sp), %d2-%d7/%a2-%a4 | restore stacked regs
lea.l (9*4, %sp), %sp
rts