From 61ad5229b66259849f0820fd059160036829cc93 Mon Sep 17 00:00:00 2001 From: Dimitri Diakopoulos Date: Sat, 31 Oct 2015 10:01:50 -0700 Subject: [PATCH] musepack dependencies --- COPYING | 127 +-- third_party/musepack/include/mpc/datatypes.h | 38 + third_party/musepack/include/mpc/minimax.h | 57 ++ third_party/musepack/include/mpc/mpc_types.h | 146 ++++ third_party/musepack/include/mpc/mpcdec.h | 148 ++++ third_party/musepack/include/mpc/mpcmath.h | 155 ++++ third_party/musepack/include/mpc/reader.h | 98 +++ third_party/musepack/include/mpc/streaminfo.h | 109 +++ third_party/musepack/libmpcdec/decoder.h | 101 +++ third_party/musepack/libmpcdec/huffman.c | 358 +++++++++ third_party/musepack/libmpcdec/huffman.h | 83 ++ third_party/musepack/libmpcdec/internal.h | 110 +++ .../musepack/libmpcdec/mpc_bits_reader.c | 181 +++++ .../musepack/libmpcdec/mpc_bits_reader.h | 149 ++++ third_party/musepack/libmpcdec/mpc_decoder.c | 681 ++++++++++++++++ third_party/musepack/libmpcdec/mpc_demux.c | 738 ++++++++++++++++++ third_party/musepack/libmpcdec/mpc_reader.c | 144 ++++ third_party/musepack/libmpcdec/mpcdec_math.h | 135 ++++ third_party/musepack/libmpcdec/requant.c | 124 +++ third_party/musepack/libmpcdec/requant.h | 61 ++ third_party/musepack/libmpcdec/streaminfo.c | 245 ++++++ third_party/musepack/libmpcdec/synth_filter.c | 430 ++++++++++ third_party/musepack/libmpcenc/analy_filter.c | 344 ++++++++ third_party/musepack/libmpcenc/bitstream.c | 271 +++++++ third_party/musepack/libmpcenc/encode_sv7.c | 492 ++++++++++++ third_party/musepack/libmpcenc/huffsv7.c | 112 +++ third_party/musepack/libmpcenc/libmpcenc.h | 122 +++ third_party/musepack/libmpcenc/quant.c | 309 ++++++++ 28 files changed, 6020 insertions(+), 48 deletions(-) create mode 100755 third_party/musepack/include/mpc/datatypes.h create mode 100755 third_party/musepack/include/mpc/minimax.h create mode 100755 third_party/musepack/include/mpc/mpc_types.h create mode 100755 third_party/musepack/include/mpc/mpcdec.h create mode 100755 third_party/musepack/include/mpc/mpcmath.h create mode 100755 third_party/musepack/include/mpc/reader.h create mode 100755 third_party/musepack/include/mpc/streaminfo.h create mode 100755 third_party/musepack/libmpcdec/decoder.h create mode 100755 third_party/musepack/libmpcdec/huffman.c create mode 100755 third_party/musepack/libmpcdec/huffman.h create mode 100755 third_party/musepack/libmpcdec/internal.h create mode 100755 third_party/musepack/libmpcdec/mpc_bits_reader.c create mode 100755 third_party/musepack/libmpcdec/mpc_bits_reader.h create mode 100755 third_party/musepack/libmpcdec/mpc_decoder.c create mode 100755 third_party/musepack/libmpcdec/mpc_demux.c create mode 100755 third_party/musepack/libmpcdec/mpc_reader.c create mode 100755 third_party/musepack/libmpcdec/mpcdec_math.h create mode 100755 third_party/musepack/libmpcdec/requant.c create mode 100755 third_party/musepack/libmpcdec/requant.h create mode 100755 third_party/musepack/libmpcdec/streaminfo.c create mode 100755 third_party/musepack/libmpcdec/synth_filter.c create mode 100755 third_party/musepack/libmpcenc/analy_filter.c create mode 100755 third_party/musepack/libmpcenc/bitstream.c create mode 100755 third_party/musepack/libmpcenc/encode_sv7.c create mode 100755 third_party/musepack/libmpcenc/huffsv7.c create mode 100755 third_party/musepack/libmpcenc/libmpcenc.h create mode 100755 third_party/musepack/libmpcenc/quant.c diff --git a/COPYING b/COPYING index 534517d..dd22359 100644 --- a/COPYING +++ b/COPYING @@ -11,11 +11,11 @@ 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. + * 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. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE @@ -35,14 +35,14 @@ Copyright (c) 1998 - 2015 Conifer Software 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 Conifer Software nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. + * 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 Conifer Software 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 @@ -63,14 +63,14 @@ B. Terriberry, CSIRO, Gregory Maxwell, Mark Borgerding, Erik de Castro Lopo 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 Internet Society, IETF or IETF Trust, nor the names - of specific contributors, may be used to endorse or promote products - derived from this software without specific prior written permission. + * 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 Internet Society, IETF or IETF Trust, nor the names + of specific 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 @@ -84,9 +84,9 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Opus is subject to the royalty-free patent licenses which are specified at: - Xiph.Org Foundation: https://datatracker.ietf.org/ipr/1524/ Microsoft - Corporation: https://datatracker.ietf.org/ipr/1914/ Broadcom Corporation: - https://datatracker.ietf.org/ipr/1526/ + Xiph.Org Foundation: https://datatracker.ietf.org/ipr/1524/ Microsoft + Corporation: https://datatracker.ietf.org/ipr/1914/ Broadcom Corporation: + https://datatracker.ietf.org/ipr/1526/ FLAC Codec (3-Clause BSD) =============================================================================== @@ -96,16 +96,16 @@ Foundation 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 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. + * 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 Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. + * Neither the name of the Xiph.org Foundation 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 @@ -125,16 +125,16 @@ Copyright (c) 2002-2015 Xiph.org Foundation 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 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. + * 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 Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. + * Neither the name of the Xiph.org Foundation 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 @@ -154,16 +154,16 @@ Copyright (c) 2002, Xiph.org Foundation 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 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. + * 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 Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. + * Neither the name of the Xiph.org Foundation 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 @@ -203,6 +203,37 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +Musepack (3-Clause BSD) +=============================================================================== +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 Xiph.org Foundation 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. + Catch (Boost) =============================================================================== Boost Software License - Version 1.0 - August 17th, 2003 diff --git a/third_party/musepack/include/mpc/datatypes.h b/third_party/musepack/include/mpc/datatypes.h new file mode 100755 index 0000000..608ecfa --- /dev/null +++ b/third_party/musepack/include/mpc/datatypes.h @@ -0,0 +1,38 @@ +/* + * Musepack audio compression + * + * 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 + +// mpcenc.h +#define CENTER 448 // offset for centering current data in Main-array +#define BLOCK 1152 // blocksize +#define ANABUFFER (BLOCK + CENTER) // size of PCM-data array for analysis + + +typedef struct { + float L [36]; + float R [36]; +} SubbandFloatTyp; + +typedef struct { + float L [ANABUFFER]; + float R [ANABUFFER]; + float M [ANABUFFER]; + float S [ANABUFFER]; +} PCMDataTyp; + diff --git a/third_party/musepack/include/mpc/minimax.h b/third_party/musepack/include/mpc/minimax.h new file mode 100755 index 0000000..1192626 --- /dev/null +++ b/third_party/musepack/include/mpc/minimax.h @@ -0,0 +1,57 @@ +/* + * Musepack audio compression + * Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#pragma once + +# define clip(x,min,max) ( (x) < (min) ? (min) : (x) > (max) ? (max) : (x) ) + +#ifdef __cplusplus + +# define maxi(A,B) ( (A) >? (B) ) +# define mini(A,B) ( (A) ? (B) ) +# define mind(A,B) ( (A) ? (B) ) +# define minf(A,B) ( (A) (B) ? (A) : (B) ) +# define mini(A,B) ( (A) < (B) ? (A) : (B) ) +# define maxd(A,B) ( (A) > (B) ? (A) : (B) ) +# define mind(A,B) ( (A) < (B) ? (A) : (B) ) +# define maxf(A,B) ( (A) > (B) ? (A) : (B) ) +# define minf(A,B) ( (A) < (B) ? (A) : (B) ) + +#endif + +#ifdef __GNUC__ + +# define absi(A) abs (A) +# define absf(A) fabsf (A) +# define absd(A) fabs (A) + +#else + +# define absi(A) ( (A) >= 0 ? (A) : -(A) ) +# define absf(A) ( (A) >= 0.f ? (A) : -(A) ) +# define absd(A) ( (A) >= 0. ? (A) : -(A) ) + +#endif + diff --git a/third_party/musepack/include/mpc/mpc_types.h b/third_party/musepack/include/mpc/mpc_types.h new file mode 100755 index 0000000..e750dc3 --- /dev/null +++ b/third_party/musepack/include/mpc/mpc_types.h @@ -0,0 +1,146 @@ +/* + Copyright (c) 2005-2009, The Musepack Development Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the The Musepack Development Team nor the + names of its contributors may be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef _MPC_TYPES_H_ +#define _MPC_TYPES_H_ +#ifdef WIN32 +#pragma once +#endif + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MSC_VER +typedef __int8 mpc_int8_t; +typedef unsigned __int8 mpc_uint8_t; +typedef __int16 mpc_int16_t; +typedef unsigned __int16 mpc_uint16_t; +typedef __int32 mpc_int32_t; +typedef unsigned __int32 mpc_uint32_t; +typedef __int64 mpc_int64_t; +typedef unsigned __int64 mpc_uint64_t; +#define mpc_inline __inline +#else +#include +typedef int8_t mpc_int8_t; +typedef uint8_t mpc_uint8_t; +typedef int16_t mpc_int16_t; +typedef uint16_t mpc_uint16_t; +typedef int32_t mpc_int32_t; +typedef uint32_t mpc_uint32_t; +typedef int64_t mpc_int64_t; +typedef uint64_t 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_SHIFT 16 + +#ifdef MPC_FIXED_POINT +# define MPC_FIXED_POINT_FRACTPART 14 +# define MPC_FIXED_POINT_SCALE_SHIFT (MPC_FIXED_POINT_SHIFT + MPC_FIXED_POINT_FRACTPART) +# define MPC_FIXED_POINT_SCALE (1 << (MPC_FIXED_POINT_SCALE_SHIFT - 1)) +typedef mpc_int32_t MPC_SAMPLE_FORMAT; +#else +typedef float MPC_SAMPLE_FORMAT; +#endif + +enum { + MPC_FALSE = 0, + MPC_TRUE = !MPC_FALSE +}; + +//// 'Cdecl' forces the use of standard C/C++ calling convention /////// +#if defined _WIN32 +# define mpc_cdecl __cdecl +#elif defined __ZTC__ +# define mpc_cdecl _cdecl +#elif defined __TURBOC__ +# define mpc_cdecl cdecl +#else +# define mpc_cdecl +#endif + +/* DLL building support on win32 hosts */ +#ifndef MPC_API +# ifdef DLL_EXPORT /* defined by libtool (if required) */ +# define MPC_API __declspec(dllexport) +# endif +# ifdef MPC_DLL_IMPORT /* define if linking with this dll */ +# define MPC_API __declspec(dllimport) +# endif +# ifndef MPC_API /* static linking or !_WIN32 */ +# if defined(__GNUC__) && (__GNUC__ >= 4) +# define MPC_API __attribute__ ((visibility("default"))) +# else +# define MPC_API +# endif +# endif +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/third_party/musepack/include/mpc/mpcdec.h b/third_party/musepack/include/mpc/mpcdec.h new file mode 100755 index 0000000..c723595 --- /dev/null +++ b/third_party/musepack/include/mpc/mpcdec.h @@ -0,0 +1,148 @@ +/* + Copyright (c) 2005-2009, The Musepack Development Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the The Musepack Development Team nor the + names of its contributors may be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/// \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" + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + MPC_FRAME_LENGTH = (36 * 32), ///< Samples per mpc frame + MPC_DECODER_BUFFER_LENGTH = (MPC_FRAME_LENGTH * 4), ///< Required buffer size for decoder + 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_bits_reader; + +typedef struct mpc_frame_info_t { + mpc_uint32_t samples; /// number of samples in the frame (counting once for multiple channels) + mpc_int32_t bits; /// number of bits consumed by this frame (-1) if end of stream + MPC_SAMPLE_FORMAT * buffer; /// frame samples buffer (size = samples * channels * sizeof(MPC_SAMPLE_FORMAT)) + mpc_bool_t is_key_frame; /// 1 if this frame is a key frame (first in block) 0 else. Set by the demuxer. +} mpc_frame_info; + +typedef struct mpc_chap_info_t { + mpc_uint64_t sample; /// sample where the chapter starts + mpc_uint16_t gain; /// replaygain chapter value + mpc_uint16_t peak; /// peak chapter loudness level + mpc_uint_t tag_size; /// size of the tag element (0 if no tag is present for this chapter) + char * tag; /// pointer to an APEv2 tag without the preamble +} mpc_chap_info; + +/// Initializes mpc decoder with the supplied stream info parameters. +/// \param si streaminfo structure indicating format of source stream +/// \return pointer on the initialized decoder structure if successful, 0 if not +MPC_API mpc_decoder * mpc_decoder_init(mpc_streaminfo *si); + +/// Releases input mpc decoder +MPC_API void mpc_decoder_exit(mpc_decoder *p_dec); + +/** + * Sets decoder sample scaling factor. All decoded samples will be multiplied + * by this factor. Useful for applying replay gain. + * @param scale_factor multiplicative scaling factor + */ +MPC_API void mpc_decoder_scale_output(mpc_decoder *p_dec, double scale_factor); + +MPC_API void mpc_decoder_decode_frame(mpc_decoder * d, mpc_bits_reader * r, mpc_frame_info * i); + +// This is the gain reference used in old replaygain +#define MPC_OLD_GAIN_REF 64.82 + +/** + * init demuxer + * @param p_reader initialized mpc_reader pointer + * @return an initialized mpc_demux pointer + */ +MPC_API mpc_demux * mpc_demux_init(mpc_reader * p_reader); +/// free demuxer +MPC_API void mpc_demux_exit(mpc_demux * d); +/** + * Calls mpc_decoder_scale_output to set the scaling factor according to the + * replay gain stream information and the supplied ouput level + * @param d pointer to a musepack demuxer + * @param level the desired ouput level (in db). Must be MPC_OLD_GAIN_REF (64.82 db) if you want to get the old replaygain behavior + * @param use_gain set it to MPC_TRUE if you want to set the scaling factor according to the stream gain + * @param use_title MPC_TRUE : uses the title gain, MPC_FALSE : uses the album gain + * @param clip_prevention MPC_TRUE : uses cliping prevention + */ +MPC_API void mpc_set_replay_level(mpc_demux * d, float level, mpc_bool_t use_gain, + mpc_bool_t use_title, mpc_bool_t clip_prevention); +/// decode frame +MPC_API mpc_status mpc_demux_decode(mpc_demux * d, mpc_frame_info * i); +/// get streaminfo +MPC_API void mpc_demux_get_info(mpc_demux * d, mpc_streaminfo * i); +/// seeks to a given sample +MPC_API mpc_status mpc_demux_seek_sample(mpc_demux * d, mpc_uint64_t destsample); +/// seeks to a given second +MPC_API mpc_status mpc_demux_seek_second(mpc_demux * d, double seconds); + +/// \return the current position in the stream (in bits) from the beginning of the file +MPC_API mpc_seek_t mpc_demux_pos(mpc_demux * d); + +/// chapters : only for sv8 streams +/** + * Gets the number of chapters in the stream + * @param d pointer to a musepack demuxer + * @return the number of chapters found in the stream + */ +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 + */ +MPC_API mpc_chap_info const * mpc_demux_chap(mpc_demux * d, int chap_nb); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/third_party/musepack/include/mpc/mpcmath.h b/third_party/musepack/include/mpc/mpcmath.h new file mode 100755 index 0000000..3b42a45 --- /dev/null +++ b/third_party/musepack/include/mpc/mpcmath.h @@ -0,0 +1,155 @@ +/* + * Musepack audio compression + * + * 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 + */ + +#include + +#include + +typedef union mpc_floatint +{ + float f; + mpc_int32_t n; +} mpc_floatint; + +typedef union mpc_doubleint +{ + double d; + mpc_int32_t n[2]; +} mpc_doubleint; + +static mpc_inline mpc_int32_t mpc_lrintf(float fVal) +{ + mpc_floatint tmp; + tmp.f = fVal + 0x00FF8000; + return tmp.n - 0x4B7F8000; +} + +#define mpc_round32 mpc_lrintf +#define mpc_nearbyintf mpc_lrintf + + +#ifndef M_PI +# define M_PI 3.1415926535897932384626433832795029 // 4*atan(1) +# define M_PIl 3.1415926535897932384626433832795029L +# define M_LN2 0.6931471805599453094172321214581766 // ln(2) +# define M_LN2l 0.6931471805599453094172321214581766L +# define M_LN10 2.3025850929940456840179914546843642 // ln 10 */ +# define M_LN10l 2.3025850929940456840179914546843642L +#endif + +// fast but maybe more inaccurate, use if you need speed +#if defined(__GNUC__) && !defined(__APPLE__) +# define SIN(x) sinf ((float)(x)) +# define COS(x) cosf ((float)(x)) +# define ATAN2(x,y) atan2f ((float)(x), (float)(y)) +# define SQRT(x) sqrtf ((float)(x)) +# define LOG(x) logf ((float)(x)) +# define LOG10(x) log10f ((float)(x)) +# define POW(x,y) expf (logf(x) * (y)) +# define POW10(x) expf (M_LN10 * (x)) +# define FLOOR(x) floorf ((float)(x)) +# define IFLOOR(x) (int) floorf ((float)(x)) +# define FABS(x) fabsf ((float)(x)) +#else +# define SIN(x) (float) sin (x) +# define COS(x) (float) cos (x) +# define ATAN2(x,y) (float) atan2 (x, y) +# define SQRT(x) (float) sqrt (x) +# define LOG(x) (float) log (x) +# define LOG10(x) (float) log10 (x) +# define POW(x,y) (float) pow (x,y) +# define POW10(x) (float) pow (10., (x)) +# define FLOOR(x) (float) floor (x) +# define IFLOOR(x) (int) floor (x) +# define FABS(x) (float) fabs (x) +#endif + +#define SQRTF(x) SQRT (x) +#ifdef FAST_MATH +# define TABSTEP 64 +# define COSF(x) my_cos ((float)(x)) +# define ATAN2F(x,y) my_atan2 ((float)(x), (float)(y)) +# define IFLOORF(x) my_ifloor ((float)(x)) + +void Init_FastMath ( void ); +extern const float tabatan2 [] [2]; +extern const float tabcos [] [2]; +extern const float tabsqrt_ex []; +extern const float tabsqrt_m [] [2]; + +static mpc_inline float my_atan2 ( float x, float y ) +{ + float t, ret; int i; mpc_floatint mx, my; + + mx.f = x; + my.f = y; + if ( (mx.n & 0x7FFFFFFF) < (my.n & 0x7FFFFFFF) ) { + i = mpc_round32 (t = TABSTEP * (mx.f / my.f)); + ret = tabatan2 [1*TABSTEP+i][0] + tabatan2 [1*TABSTEP+i][1] * (t-i); + if ( my.n < 0 ) + ret = (float)(ret - M_PI); + } + else if ( mx.n < 0 ) { + i = mpc_round32 (t = TABSTEP * (my.f / mx.f)); + ret = - M_PI/2 - tabatan2 [1*TABSTEP+i][0] + tabatan2 [1*TABSTEP+i][1] * (i-t); + } + else if ( mx.n > 0 ) { + i = mpc_round32 (t = TABSTEP * (my.f / mx.f)); + ret = + M_PI/2 - tabatan2 [1*TABSTEP+i][0] + tabatan2 [1*TABSTEP+i][1] * (i-t); + } + else { + ret = 0.; + } + return ret; +} + + +static mpc_inline float my_cos ( float x ) +{ + float t, ret; int i; + i = mpc_round32 (t = TABSTEP * x); + ret = tabcos [13*TABSTEP+i][0] + tabcos [13*TABSTEP+i][1] * (t-i); + return ret; +} + + +static mpc_inline int my_ifloor ( float x ) +{ + mpc_floatint mx; + mx.f = (float) (x + (0x0C00000L + 0.500000001)); + return mx.n - 1262485505; +} + + +static mpc_inline float my_sqrt ( float x ) +{ + float ret; int i, ex; mpc_floatint mx; + mx.f = x; + ex = mx.n >> 23; // get the exponent + mx.n = (mx.n & 0x7FFFFF) | 0x42800000; // delete the exponent + i = mpc_round32 (mx.f); // Integer-part of the mantissa (round ????????????) + ret = tabsqrt_m [i-TABSTEP][0] + tabsqrt_m [i-TABSTEP][1] * (mx.f-i); // calculate value + ret *= tabsqrt_ex [ex]; + return ret; +} +#else +# define COSF(x) COS (x) +# define ATAN2F(x,y) ATAN2 (x,y) +# define IFLOORF(x) IFLOOR (x) +#endif + diff --git a/third_party/musepack/include/mpc/reader.h b/third_party/musepack/include/mpc/reader.h new file mode 100755 index 0000000..1a93e06 --- /dev/null +++ b/third_party/musepack/include/mpc/reader.h @@ -0,0 +1,98 @@ +/* + 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 +#include + +#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); + + /// 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; +}; + +/// 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 diff --git a/third_party/musepack/include/mpc/streaminfo.h b/third_party/musepack/include/mpc/streaminfo.h new file mode 100755 index 0000000..a0a9470 --- /dev/null +++ b/third_party/musepack/include/mpc/streaminfo.h @@ -0,0 +1,109 @@ +/* + 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 + +#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) + double average_bitrate; ///< Average bitrate of stream (in bits/sec) + mpc_uint32_t max_band; ///< Maximum band-index used in stream (0...31) + mpc_uint32_t ms; ///< Mid/side stereo (0: off, 1: on) + mpc_uint32_t fast_seek; ///< True if stream supports fast-seeking (sv7) + mpc_uint32_t block_pwr; ///< Number of frames in a block = 2^block_pwr (sv8) + //@} + + /// @name Replaygain 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 + char encoder[256]; ///< Encoder name + mpc_bool_t pns; ///< pns used + float profile; ///< Quality profile of stream + 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; + +/// Gets length of stream si, in seconds. +/// \return length of stream in seconds +MPC_API double mpc_streaminfo_get_length(mpc_streaminfo *si); + +/// Returns length of stream si, in samples. +/// \return length of stream in samples +MPC_API mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/third_party/musepack/libmpcdec/decoder.h b/third_party/musepack/libmpcdec/decoder.h new file mode 100755 index 0000000..3813fc0 --- /dev/null +++ b/third_party/musepack/libmpcdec/decoder.h @@ -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 + +#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_V_MEM + 960]; + MPC_SAMPLE_FORMAT V_R[MPC_V_MEM + 960]; + MPC_SAMPLE_FORMAT Y_L[36][32]; + MPC_SAMPLE_FORMAT Y_R[36][32]; + MPC_SAMPLE_FORMAT SCF[256]; ///< holds adapted scalefactors (for clipping prevention) + //@} +}; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/third_party/musepack/libmpcdec/huffman.c b/third_party/musepack/libmpcdec/huffman.c new file mode 100755 index 0000000..52cdfd9 --- /dev/null +++ b/third_party/musepack/libmpcdec/huffman.c @@ -0,0 +1,358 @@ +/* + 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 "huffman.h" + + +// sv7 huffman tables +static const mpc_huffman mpc_table_HuffHdr [10] = { +{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}, {0x0, 2, -1} +}; +mpc_lut_data mpc_HuffHdr = {mpc_table_HuffHdr}; + +const mpc_huffman mpc_table_HuffSCFI [4] = { + {0x8000, 1, 1}, {0x6000, 3, 2}, {0x4000, 3, 0}, {0x0, 2, 3} +}; + +static const mpc_huffman mpc_table_HuffDSCF [16] = { + {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}, {0x0, 3, -2} +}; +mpc_lut_data mpc_HuffDSCF = {mpc_table_HuffDSCF}; + +static const mpc_huffman mpc_table_HuffQ1 [2] [27] = { + { + {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}, {0x800, 5, 19}, {0x0, 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}, {0x0, 4, 10} + } +}; + +static const mpc_huffman mpc_table_HuffQ2 [2] [25] = { + { + {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}, {0x800, 5, 19}, {0x0, 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}, {0x0, 3, 7} + } +}; + +static const mpc_huffman mpc_table_HuffQ3 [2] [7] = { + { + {0xe000, 3, 1}, {0xd000, 4, 3}, {0xc000, 4, -3}, {0xa000, 3, 2}, {0x8000, 3, -2}, {0x4000, 2, 0}, {0x0, 2, -1} + }, { + {0xc000, 2, 0}, {0x8000, 2, -1}, {0x4000, 2, 1}, {0x3000, 4, -2}, {0x2800, 5, 3}, {0x2000, 5, -3}, {0x0, 3, 2} + } +}; + +static const mpc_huffman mpc_table_HuffQ4 [2] [9] = { + { + {0xe000, 3, 0}, {0xc000, 3, -1}, {0xa000, 3, 1}, {0x8000, 3, -2}, {0x6000, 3, 2}, {0x5000, 4, -4}, {0x4000, 4, 4}, {0x2000, 3, 3}, {0x0, 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}, {0x0, 2, -1} + } +}; + +static const mpc_huffman mpc_table_HuffQ5 [2] [15] = { + { + {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}, {0x0, 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}, {0x0, 3, -3} + } +}; + +static const mpc_huffman mpc_table_HuffQ6 [2] [31] = { + { + {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}, {0x0, 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}, {0x0, 3, 0} + } +}; + +static const mpc_huffman mpc_table_HuffQ7 [2] [63] = { + { + {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}, {0x800, 5, 6}, {0x0, 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}, {0x0, 4, 1} + } +}; + +mpc_lut_data mpc_HuffQ [7] [2] = { + {{mpc_table_HuffQ1[0]}, {mpc_table_HuffQ1[1]}}, + {{mpc_table_HuffQ2[0]}, {mpc_table_HuffQ2[1]}}, + {{mpc_table_HuffQ3[0]}, {mpc_table_HuffQ3[1]}}, + {{mpc_table_HuffQ4[0]}, {mpc_table_HuffQ4[1]}}, + {{mpc_table_HuffQ5[0]}, {mpc_table_HuffQ5[1]}}, + {{mpc_table_HuffQ6[0]}, {mpc_table_HuffQ6[1]}}, + {{mpc_table_HuffQ7[0]}, {mpc_table_HuffQ7[1]}} +}; + + +// sv8 huffman tables +static const mpc_huffman mpc_huff_SCFI_1 [3] = { + {0x8000, 1, 1}, {0x4000, 2, 2}, {0x0, 3, 3} +}; // 3 +static const mpc_int8_t mpc_sym_SCFI_1 [4] = { + 2, 3, 1, 0 +}; +static const mpc_huffman mpc_huff_SCFI_2 [5] = { + {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] = { + 15, 10, 14, 11, 13, 9, 7, 6, 5, 12, 8, 3, 2, 0, 4, 1 +}; +mpc_can_data mpc_can_SCFI[2] = {{mpc_huff_SCFI_1, mpc_sym_SCFI_1}, {mpc_huff_SCFI_2, mpc_sym_SCFI_2}}; + +static const mpc_huffman mpc_huff_DSCF_1 [12] = { + {0xa000, 3, 7}, {0x4000, 4, 12}, {0x2800, 5, 16}, {0x1800, 6, 21}, {0xe00, 7, 27}, {0x700, 8, 34}, {0x380, 9, 41}, {0x140, 10, 48}, {0x80, 11, 53}, {0x30, 12, 57}, {0x18, 13, 60}, {0x0, 14, 63} +}; // 12 +static const mpc_int8_t mpc_sym_DSCF_1 [64] = { + 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] = { + {0x6000, 3, 7}, {0x3000, 4, 10}, {0x1800, 5, 13}, {0x1000, 6, 16}, {0xa00, 7, 20}, {0x600, 8, 25}, {0x380, 9, 31}, {0x1c0, 10, 38}, {0xe0, 11, 45}, {0x50, 12, 52}, {0x20, 13, 57}, {0xc, 14, 61}, {0x0, 15, 64} +}; // 13 +static const mpc_int8_t mpc_sym_DSCF_2 [65] = { + 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 +}; +mpc_can_data mpc_can_DSCF[2] = {{mpc_huff_DSCF_1, mpc_sym_DSCF_1}, {mpc_huff_DSCF_2, mpc_sym_DSCF_2}}; + +static const mpc_huffman mpc_huff_Bands [12] = { + {0x8000, 1, 1}, {0x4000, 2, 2}, {0x2000, 3, 3}, {0x1000, 5, 6}, {0x800, 6, 8}, {0x600, 7, 10}, {0x300, 8, 13}, {0x200, 9, 16}, {0x140, 10, 20}, {0xc0, 11, 25}, {0x10, 12, 31}, {0x0, 13, 32} +}; // 12 +static const mpc_int8_t mpc_sym_Bands [33] = { + 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 +}; +mpc_can_data mpc_can_Bands = {mpc_huff_Bands, mpc_sym_Bands}; + +static const mpc_huffman mpc_huff_Res_1 [16] = { + {0x8000, 1, 1}, {0x4000, 2, 2}, {0x2000, 3, 3}, {0x1000, 4, 4}, {0x800, 5, 5}, {0x400, 6, 6}, {0x200, 7, 7}, {0x100, 8, 8}, {0x80, 9, 9}, {0x40, 10, 10}, {0x20, 11, 11}, {0x10, 12, 12}, {0x8, 13, 13}, {0x4, 14, 14}, {0x2, 15, 15}, {0x0, 16, 16} +}; // 16 +static const mpc_int8_t mpc_sym_Res_1 [17] = { + 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] = { + {0x4000, 2, 3}, {0x2000, 3, 4}, {0x1000, 4, 5}, {0x800, 5, 6}, {0x400, 6, 7}, {0x200, 7, 8}, {0x100, 8, 9}, {0x80, 9, 10}, {0x40, 10, 11}, {0x20, 11, 12}, {0x10, 12, 13}, {0x0, 14, 16} +}; // 12 +static const mpc_int8_t mpc_sym_Res_2 [17] = { + 16, 1, 0, 2, 15, 3, 14, 4, 5, 13, 6, 12, 7, 11, 10, 9, 8 +}; +mpc_can_data mpc_can_Res[2] = {{mpc_huff_Res_1, mpc_sym_Res_1}, {mpc_huff_Res_2, mpc_sym_Res_2}}; + +static const mpc_huffman mpc_huff_Q1 [10] = { + {0x6000, 3, 7}, {0x1000, 4, 10}, {0x800, 5, 11}, {0x400, 6, 12}, {0x200, 7, 13}, {0x100, 8, 14}, {0x80, 9, 15}, {0x40, 10, 16}, {0x20, 11, 17}, {0x0, 12, 18} +}; // 10 +static const mpc_int8_t mpc_sym_Q1 [19] = { + 7, 6, 5, 4, 3, 10, 9, 8, 2, 1, 11, 0, 12, 13, 14, 15, 16, 18, 17 +}; +mpc_can_data mpc_can_Q1 = {mpc_huff_Q1, mpc_sym_Q1}; + +static const mpc_huffman mpc_huff_Q2_1 [10] = { + {0xe000, 3, 7}, {0x8000, 4, 14}, {0x3c00, 6, 38}, {0x2a00, 7, 53}, {0x1200, 8, 74}, {0x600, 9, 92}, {0x3c0, 10, 104}, {0x60, 11, 119}, {0x20, 12, 122}, {0x0, 13, 124} +}; // 10 +static const mpc_int8_t mpc_sym_Q2_1 [125] = { + 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] = { + {0xf000, 4, 15}, {0x7000, 5, 30}, {0x4800, 6, 44}, {0x3c00, 7, 62}, {0xc00, 8, 92}, {0x780, 9, 104}, {0xc0, 10, 119}, {0x40, 11, 122}, {0x0, 12, 124} +}; // 9 +static const mpc_int8_t mpc_sym_Q2_2 [125] = { + 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] = { + {0xe000, 3, 7}, {0x8000, 4, 14}, {0x5000, 5, 22}, {0x2400, 6, 32}, {0xa00, 7, 41}, {0x200, 8, 46}, {0x0, 9, 48} +}; // 7 +static const mpc_int8_t mpc_sym_Q3 [49] = { + 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] = { + {0xf000, 4, 15}, {0x9000, 5, 30}, {0x3400, 6, 48}, {0x1800, 7, 61}, {0x500, 8, 73}, {0x100, 9, 78}, {0x0, 10, 80}, {0x0, 0, 90} +}; // 8 +static const mpc_int8_t mpc_sym_Q4 [91] = { + 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] = { + {0xc000, 2, 3}, {0x4000, 3, 6}, {0x2000, 4, 8}, {0x1000, 5, 10}, {0x800, 6, 12}, {0x0, 7, 14} +}; // 6 +static const mpc_int8_t mpc_sym_Q5_1 [15] = { + 0, 2, 1, -1, -2, 3, -3, 4, -4, 5, -5, 7, 6, -6, -7 +}; +static const mpc_huffman mpc_huff_Q5_2 [4] = { + {0x6000, 3, 7}, {0x2000, 4, 10}, {0x1000, 5, 12}, {0x0, 6, 14} +}; // 4 +static const mpc_int8_t mpc_sym_Q5_2 [15] = { + 2, 1, 0, -1, -2, 4, 3, -3, -4, 5, -5, 7, 6, -6, -7 +}; + +static const mpc_huffman mpc_huff_Q6_1 [8] = { + {0xc000, 2, 3}, {0x8000, 3, 6}, {0x4000, 4, 10}, {0x2800, 5, 14}, {0xc00, 6, 19}, {0x800, 7, 22}, {0x400, 8, 26}, {0x0, 9, 30} +}; // 8 +static const mpc_int8_t mpc_sym_Q6_1 [31] = { + 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] = { + {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] = { + 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] = { + {0xc000, 2, 3}, {0x8000, 3, 6}, {0x6000, 4, 10}, {0x4000, 5, 16}, {0x2800, 6, 24}, {0x1400, 7, 34}, {0xa00, 8, 44}, {0x400, 9, 54}, {0x0, 10, 62} +}; // 9 +static const mpc_int8_t mpc_sym_Q7_1 [63] = { + 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] = { + {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] = { + 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] = { + {0xc000, 2, 3}, {0x8000, 3, 6}, {0x7000, 4, 10}, {0x5800, 5, 17}, {0x3800, 6, 28}, {0x2800, 7, 42}, {0x1900, 8, 62}, {0xd00, 9, 87}, {0x280, 10, 113}, {0x60, 11, 123}, {0x0, 12, 126} +}; // 11 +static const mpc_int8_t mpc_sym_Q8_1 [127] = { + 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] = { + {0x9800, 6, 63}, {0x2a00, 7, 101}, {0x400, 8, 122}, {0x0, 9, 126} +}; // 4 +static const mpc_int8_t mpc_sym_Q8_2 [127] = { + 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] = { + {0xf800, 6, 63}, {0xac00, 7, 125}, {0x2600, 8, -45}, {0x280, 9, -7}, {0x40, 10, -2}, {0x0, 11, -1} +}; // 6 +static const mpc_int8_t mpc_sym_Q9up [256] = { + -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 +}; +mpc_can_data mpc_can_Q9up = {mpc_huff_Q9up, mpc_sym_Q9up}; + + +mpc_can_data mpc_can_Q [6][2] = { + {{mpc_huff_Q2_1, mpc_sym_Q2_1}, {mpc_huff_Q2_2, mpc_sym_Q2_2}}, + {{mpc_huff_Q3, mpc_sym_Q3}, {mpc_huff_Q4, mpc_sym_Q4}}, + {{mpc_huff_Q5_1, mpc_sym_Q5_1}, {mpc_huff_Q5_2, mpc_sym_Q5_2}}, + {{mpc_huff_Q6_1, mpc_sym_Q6_1}, {mpc_huff_Q6_2, mpc_sym_Q6_2}}, + {{mpc_huff_Q7_1, mpc_sym_Q7_1}, {mpc_huff_Q7_2, mpc_sym_Q7_2}}, + {{mpc_huff_Q8_1, mpc_sym_Q8_1}, {mpc_huff_Q8_2, mpc_sym_Q8_2}} +}; + +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) +{ + int i, j; + + huff_fill_lut(mpc_HuffDSCF.table, mpc_HuffDSCF.lut, bits); + huff_fill_lut(mpc_HuffHdr.table, mpc_HuffHdr.lut, bits); + + can_fill_lut(&mpc_can_SCFI[0], bits); + can_fill_lut(&mpc_can_SCFI[1], bits); + can_fill_lut(&mpc_can_DSCF[0], bits); + can_fill_lut(&mpc_can_DSCF[1], bits); + can_fill_lut(&mpc_can_Res[0], bits); + can_fill_lut(&mpc_can_Res[1], bits); + can_fill_lut(&mpc_can_Q1, bits); + can_fill_lut(&mpc_can_Q9up, bits); + + + for( i = 0; i < 7; i++){ + for( j = 0; j < 2; j++){ + if (i != 6) can_fill_lut(&mpc_can_Q[i][j], bits); + huff_fill_lut(mpc_HuffQ[i][j].table, mpc_HuffQ[i][j].lut, bits); + } + } +} + + diff --git a/third_party/musepack/libmpcdec/huffman.h b/third_party/musepack/libmpcdec/huffman.h new file mode 100755 index 0000000..5b12bff --- /dev/null +++ b/third_party/musepack/libmpcdec/huffman.h @@ -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 + +#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 * 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 * const table; + mpc_int8_t const * const sym; + mpc_huff_lut lut[1 << LUT_DEPTH]; +} mpc_can_data; + +void huff_init_lut(const int bits); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/third_party/musepack/libmpcdec/internal.h b/third_party/musepack/libmpcdec/internal.h new file mode 100755 index 0000000..48d78c1 --- /dev/null +++ b/third_party/musepack/libmpcdec/internal.h @@ -0,0 +1,110 @@ +/* + 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 + +/// Big/little endian 32 bit byte swapping routine. +static mpc_inline +mpc_uint32_t mpc_swap32(mpc_uint32_t val) { + return (((val & 0xFF000000) >> 24) | ((val & 0x00FF0000) >> 8) + | ((val & 0x0000FF00) << 8) | ((val & 0x000000FF) << 24)); +} + +typedef struct mpc_block_t { + char key[2]; // block key + mpc_uint64_t size; // block size minus the block header size +} mpc_block; + +#define MAX_FRAME_SIZE 4352 +#define DEMUX_BUFFER_SIZE (65536 - MAX_FRAME_SIZE) // need some space as sand box + +struct mpc_demux_t { + mpc_reader * r; + mpc_decoder * d; + mpc_streaminfo si; + + // buffer + mpc_uint8_t buffer[DEMUX_BUFFER_SIZE + MAX_FRAME_SIZE]; + mpc_size_t bytes_total; + mpc_bits_reader bits_reader; + mpc_int32_t block_bits; /// bits remaining in current audio block + mpc_uint_t block_frames; /// frames remaining in current audio block + + // seeking + mpc_seek_t * seek_table; + mpc_uint_t seek_pwr; /// distance between 2 frames in seek_table = 2^seek_pwr + mpc_uint32_t seek_table_size; /// used size in seek_table + + // chapters + mpc_seek_t chap_pos; /// supposed position of the first chapter block + mpc_int_t chap_nb; /// number of chapters (-1 if unknown, 0 if no chapter) + mpc_chap_info * chap; /// chapters position and tag + +}; + +/** + * checks if a block key is valid + * @param key the two caracters key to check + * @return MPC_STATUS_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, double scale_factor); +void mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT* OutData, mpc_int_t channels); + +#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 diff --git a/third_party/musepack/libmpcdec/mpc_bits_reader.c b/third_party/musepack/libmpcdec/mpc_bits_reader.c new file mode 100755 index 0000000..392aede --- /dev/null +++ b/third_party/musepack/libmpcdec/mpc_bits_reader.c @@ -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 +#include "internal.h" +#include "huffman.h" +#include "mpc_bits_reader.h" + +const mpc_uint32_t Cnk[MAX_ENUM / 2][MAX_ENUM] = +{ + {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] = +{ + {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] = +{ + {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] = +{ 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] = +{ 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 >= size) // check if the block size doesn't conflict with the header size + p_block->size -= size; + + return size; +} + + + diff --git a/third_party/musepack/libmpcdec/mpc_bits_reader.h b/third_party/musepack/libmpcdec/mpc_bits_reader.h new file mode 100755 index 0000000..a7d8d66 --- /dev/null +++ b/third_party/musepack/libmpcdec/mpc_bits_reader.h @@ -0,0 +1,149 @@ +/* + 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); +} + +// 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) +{ + mpc_uint16_t code; + code = (mpc_uint16_t)((((r->buff[0] << 16) | (r->buff[1] << 8) | r->buff[2]) >> r->count) & 0xFFFF); + + 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) +{ + mpc_uint16_t code; + mpc_huff_lut tmp; + const mpc_huffman * Table; + code = (mpc_uint16_t)((((r->buff[0] << 16) | (r->buff[1] << 8) | r->buff[2]) >> r->count) & 0xFFFF); + + tmp = can->lut[code >> (16 - LUT_DEPTH)]; + 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) +{ + mpc_uint16_t code; + mpc_huff_lut tmp; + const mpc_huffman * Table; + code = (mpc_uint16_t)((((r->buff[0] << 16) | (r->buff[1] << 8) | r->buff[2]) >> r->count) & 0xFFFF); + + tmp = lut->lut[code >> (16 - LUT_DEPTH)]; + if (tmp.Length != 0) { + r->buff -= (int)(r->count - tmp.Length) >> 3; + r->count = (r->count - tmp.Length) & 0x07; + return tmp.Value; + } + + Table = lut->table + (unsigned char)tmp.Value; + while (code < Table->Code) Table++; + + r->buff -= (int)(r->count - Table->Length) >> 3; + r->count = (r->count - Table->Length) & 0x07; + + return Table->Value; +} + +static mpc_inline mpc_uint32_t mpc_bits_enum_dec(mpc_bits_reader * r, mpc_uint_t k, mpc_uint_t n) +{ + mpc_uint32_t bits = 0; + mpc_uint32_t code; + const mpc_uint32_t * C = Cnk[k-1]; + + code = mpc_bits_read(r, Cnk_len[k-1][n-1] - 1); + + if (code >= Cnk_lost[k-1][n-1]) + code = ((code << 1) | mpc_bits_read(r, 1)) - Cnk_lost[k-1][n-1]; + + do { + n--; + if (code >= C[n]) { + bits |= 1 << n; + code -= C[n]; + C -= MAX_ENUM; + k--; + } + } while(k > 0); + + return bits; +} diff --git a/third_party/musepack/libmpcdec/mpc_decoder.c b/third_party/musepack/libmpcdec/mpc_decoder.c new file mode 100755 index 0000000..5f56c00 --- /dev/null +++ b/third_party/musepack/libmpcdec/mpc_decoder.c @@ -0,0 +1,681 @@ +/* + 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 +#include +#include +#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; + +//------------------------------------------------------------------------------ +// types +//------------------------------------------------------------------------------ +enum +{ + MEMSIZE = MPC_DECODER_MEMSIZE, // overall buffer size + MEMSIZE2 = (MEMSIZE/2), // size of one buffer + MEMMASK = (MEMSIZE-1) +}; + +//------------------------------------------------------------------------------ +// forward declarations +//------------------------------------------------------------------------------ +void mpc_decoder_read_bitstream_sv7(mpc_decoder * d, mpc_bits_reader * r); +void mpc_decoder_read_bitstream_sv8(mpc_decoder * d, mpc_bits_reader * r, + mpc_bool_t is_key_frame); +static void mpc_decoder_requantisierung(mpc_decoder *d); + +/** + * set the scf indexes for seeking use + * needed only for sv7 seeking + * @param d + */ +void mpc_decoder_reset_scf(mpc_decoder * d, int value) +{ + memset(d->SCF_Index_L, value, sizeof d->SCF_Index_L ); + memset(d->SCF_Index_R, value, sizeof d->SCF_Index_R ); +} + + +void mpc_decoder_setup(mpc_decoder *d) +{ + memset(d, 0, sizeof *d); + + d->__r1 = 1; + d->__r2 = 1; + + mpc_decoder_init_quant(d, 1.0f); +} + +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 = malloc(sizeof(mpc_decoder)); + + if (p_tmp != 0) { + mpc_decoder_setup(p_tmp); + mpc_decoder_set_streaminfo(p_tmp, si); + huff_init_lut(LUT_DEPTH); // FIXME : this needs to be called only once when the library is loaded + } + + return p_tmp; +} + +void mpc_decoder_exit(mpc_decoder *d) +{ + free(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; + memmove(i->buffer, i->buffer + d->samples_to_skip * d->channels, + i->samples * d->channels * sizeof (MPC_SAMPLE_FORMAT)); + d->samples_to_skip = 0; + } + } +} + +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[0] + Band; + YR = d->Y_R[0] + Band; + L = d->Q[Band].L; + R = d->Q[Band].R; + /************************** MS-coded **************************/ + if ( d->MS_Flag [Band] ) { + if ( d->Res_L [Band] ) { + if ( d->Res_R [Band] ) { // M!=0, S!=0 + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][0] & 0xFF); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][0] & 0xFF); + for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { + *YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); + *YR = templ - tempr; + } + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][1] & 0xFF); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][1] & 0xFF); + for ( ; n < 24; n++, YL += 32, YR += 32 ) { + *YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); + *YR = templ - tempr; + } + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][2] & 0xFF); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][2] & 0xFF); + for ( ; n < 36; n++, YL += 32, YR += 32 ) { + *YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); + *YR = templ - tempr; + } + } else { // M!=0, S==0 + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][0] & 0xFF); + for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { + *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); + } + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][1] & 0xFF); + for ( ; n < 24; n++, YL += 32, YR += 32 ) { + *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); + } + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][2] & 0xFF); + for ( ; n < 36; n++, YL += 32, YR += 32 ) { + *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); + } + } + } else { + if (d->Res_R[Band]) // M==0, S!=0 + { + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][0] & 0xFF); + for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { + *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); + } + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][1] & 0xFF); + for ( ; n < 24; n++, YL += 32, YR += 32 ) { + *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); + } + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][2] & 0xFF); + for ( ; n < 36; n++, YL += 32, YR += 32 ) { + *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); + } + } else { // M==0, S==0 + for ( n = 0; n < 36; n++, YL += 32, YR += 32 ) { + *YR = *YL = 0; + } + } + } + } + /************************** LR-coded **************************/ + else { + if ( d->Res_L [Band] ) { + if ( d->Res_R [Band] ) { // L!=0, R!=0 + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][0] & 0xFF); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][0] & 0xFF); + for (n = 0; n < 12; n++, YL += 32, YR += 32 ) { + *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); + *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); + } + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][1] & 0xFF); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][1] & 0xFF); + for (; n < 24; n++, YL += 32, YR += 32 ) { + *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); + *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); + } + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][2] & 0xFF); + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][2] & 0xFF); + for (; n < 36; n++, YL += 32, YR += 32 ) { + *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); + *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); + } + } else { // L!=0, R==0 + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][0] & 0xFF); + for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { + *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); + *YR = 0; + } + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][1] & 0xFF); + for ( ; n < 24; n++, YL += 32, YR += 32 ) { + *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); + *YR = 0; + } + facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , d->SCF_Index_L[Band][2] & 0xFF); + for ( ; n < 36; n++, YL += 32, YR += 32 ) { + *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); + *YR = 0; + } + } + } + else { + if ( d->Res_R [Band] ) { // L==0, R!=0 + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][0] & 0xFF); + for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { + *YL = 0; + *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); + } + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][1] & 0xFF); + for ( ; n < 24; n++, YL += 32, YR += 32 ) { + *YL = 0; + *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); + } + facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , d->SCF_Index_R[Band][2] & 0xFF); + for ( ; n < 36; n++, YL += 32, YR += 32 ) { + *YL = 0; + *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); + } + } else { // L==0, R==0 + for ( n = 0; n < 36; n++, YL += 32, YR += 32 ) { + *YR = *YL = 0; + } + } + } + } + } +} + +void mpc_decoder_read_bitstream_sv7(mpc_decoder * d, mpc_bits_reader * r) +{ + // these arrays hold decoding results for bundled quantizers (3- and 5-step) + static const mpc_int32_t idx30[] = { -1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1}; + static const mpc_int32_t idx31[] = { -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 idx32[] = { -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 idx50[] = { -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 idx51[] = { -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}; + + 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_int32_t k; + const mpc_lut_data *Table; + switch (Res) { + case -2: case -3: case -4: case -5: case -6: case -7: case -8: case -9: + case -10: case -11: case -12: case -13: case -14: case -15: case -16: case -17: case 0: + break; + case -1: + for (k=0; k<36; k++ ) { + mpc_uint32_t tmp = mpc_random_int(d); + q[k] = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510; + } + break; + case 1: + Table = & mpc_HuffQ[0][mpc_bits_read(r, 1)]; + for ( k = 0; k < 36; k += 3) { + idx = mpc_bits_huff_lut(r, Table); + q[k] = idx30[idx]; + q[k + 1] = idx31[idx]; + q[k + 2] = 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] = idx50[idx]; + q[k + 1] = idx51[idx]; + } + break; + case 3: + case 4: + case 5: + case 6: + case 7: + Table = & mpc_HuffQ[Res - 1][mpc_bits_read(r, 1)]; + for ( k = 0; k < 36; k++ ) + q[k] = mpc_bits_huff_lut(r, Table); + break; + case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: + for ( k = 0; k < 36; k++ ) + q[k] = (mpc_int32_t)mpc_bits_read(r, Res_bit[Res]) - Dc[Res]; + break; + default: + return; + } + + Res = d->Res_R[n]; + } while (q == d->Q[n].L && (q = d->Q[n].R)); + } +} + +void mpc_decoder_read_bitstream_sv8(mpc_decoder * d, mpc_bits_reader * r, mpc_bool_t is_key_frame) +{ + // these arrays hold decoding results for bundled quantizers (3- and 5-step) + static const mpc_int8_t idx50[125] = {-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 idx51[125] = {-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 idx52[125] = {-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}; + + 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 unsigned int thres[] = {0, 0, 3, 0, 0, 1, 3, 4, 8}; + static const mpc_int8_t HuffQ2_var[5*5*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, 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}; + + do { + mpc_uint32_t k = 0, idx = 1; + if (Res != 0) { + if (Res == 2) { + Tables[0] = & mpc_can_Q [0][0]; + Tables[1] = & mpc_can_Q [0][1]; + idx = 2 * thres[Res]; + for ( ; k < 36; k += 3) { + int tmp = mpc_bits_can_dec(r, Tables[idx > thres[Res]]); + q[k] = idx50[tmp]; + q[k + 1] = idx51[tmp]; + q[k + 2] = idx52[tmp]; + idx = (idx >> 1) + 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 { + for ( ; k < 36; k++ ) { + q[k] = (unsigned char) mpc_bits_can_dec(r, & mpc_can_Q9up); + if (Res != 9) + q[k] = (q[k] << (Res - 9)) | mpc_bits_read(r, Res - 9); + q[k] -= Dc[Res]; + } + } + } + + Res = d->Res_R[n]; + } while (q == d->Q[n].L && (q = d->Q[n].R)); + } +} + diff --git a/third_party/musepack/libmpcdec/mpc_demux.c b/third_party/musepack/libmpcdec/mpc_demux.c new file mode 100755 index 0000000..63e58e6 --- /dev/null +++ b/third_party/musepack/libmpcdec/mpc_demux.c @@ -0,0 +1,738 @@ +/* + Copyright (c) 2005-2009, The Musepack Development Team + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the The Musepack Development Team nor the + names of its contributors may be used to endorse or promote + products derived from this software without specific prior + written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include +#include +#include +#include "internal.h" +#include "decoder.h" +#include "huffman.h" +#include "mpc_bits_reader.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 65536 + +// streaminfo.c +mpc_status streaminfo_read_header_sv8(mpc_streaminfo* si, + const mpc_bits_reader * r_in, + mpc_size_t block_size); +mpc_status streaminfo_read_header_sv7(mpc_streaminfo* si, mpc_bits_reader * r_in); +void streaminfo_encoder_info(mpc_streaminfo* si, const mpc_bits_reader * r_in); +void streaminfo_gain(mpc_streaminfo* si, const mpc_bits_reader * r_in); + +// mpc_decoder.c +void mpc_decoder_reset_scf(mpc_decoder * d, int value); + +enum { + MPC_BUFFER_SWAP = 1, + MPC_BUFFER_FULL = 2, +}; + +static void mpc_demux_clear_buff(mpc_demux * d) +{ + d->bytes_total = 0; + d->bits_reader.buff = d->buffer; + d->bits_reader.count = 8; + d->block_bits = 0; + d->block_frames = 0; +} + +// Returns the amount of unread bytes in the demux buffer. +// Unchecked version - may return a negative value when we've been reading +// past the end of the valid data as a result of some problem with the file. +static mpc_int32_t mpc_unread_bytes_unchecked(mpc_demux * d) { + return d->bytes_total + d->buffer - d->bits_reader.buff - ((8 - d->bits_reader.count) >> 3); +} + +// Returns the amount of unread bytes in the demux buffer. +static mpc_uint32_t mpc_unread_bytes(mpc_demux * d) { + mpc_int32_t unread_bytes = mpc_unread_bytes_unchecked(d); + + if (unread_bytes < 0) return 0; + + return (mpc_uint32_t) unread_bytes; +} + + + +// Returns the number of bytes available in the buffer. +static mpc_uint32_t +mpc_demux_fill(mpc_demux * d, mpc_uint32_t min_bytes, int flags) +{ + mpc_uint32_t unread_bytes = (mpc_uint32_t) mpc_unread_bytes_unchecked(d); + int offset = 0; + + if ((mpc_int32_t) + unread_bytes < 0) return 0; // Error - we've been reading past the end of the buffer - abort + + if (min_bytes == 0 || min_bytes > DEMUX_BUFFER_SIZE || + (unread_bytes < min_bytes && (flags & MPC_BUFFER_FULL) != 0 )) + min_bytes = DEMUX_BUFFER_SIZE; + + if (unread_bytes < min_bytes) { + mpc_uint32_t bytes2read = min_bytes - unread_bytes; + mpc_uint32_t bytes_free = DEMUX_BUFFER_SIZE - d->bytes_total; + mpc_uint32_t bytesread; + + 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; + } + bytesread = d->r->read(d->r, d->buffer + d->bytes_total, bytes2read); + if (bytesread < bytes2read) { + memset(d->buffer + d->bytes_total + bytesread, 0, bytes2read - bytesread); // FIXME : why ? + } + 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] = mpc_swap32(tmp[i]); + } + d->bytes_total += bytesread; + unread_bytes += bytesread; + } + + return unread_bytes; +} + +/** + * 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) { + mpc_seek_t start_pos, end_pos; + mpc_int_t bit_offset; + + // get current buffer position + end_pos = ((mpc_seek_t)(d->r->tell(d->r))) << 3; + start_pos = end_pos - (d->bytes_total << 3); + + if (fpos >= start_pos && fpos < end_pos) { + d->bits_reader.buff = d->buffer + ((fpos - start_pos) >> 3); + bit_offset = fpos & 7; + d->block_bits = 0; + d->block_frames = 0; + } else { + mpc_seek_t next_pos = fpos >> 3; + if (d->si.stream_version == 7) + next_pos = ((next_pos - d->si.header_position) & (-1 << 2)) + d->si.header_position; + bit_offset = (int) (fpos - (next_pos << 3)); + + mpc_demux_clear_buff(d); + if (!d->r->seek(d->r, (mpc_int32_t) next_pos)) + return MPC_STATUS_FAIL; + } + + if (d->si.stream_version == 7) + mpc_demux_fill(d, (min_bytes + ((bit_offset + 7) >> 3) + 3) & (~3), MPC_BUFFER_SWAP); + else + mpc_demux_fill(d, min_bytes + ((bit_offset + 7) >> 3), 0); + d->bits_reader.buff += bit_offset >> 3; + d->bits_reader.count = 8 - (bit_offset & 7); + + return 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 + */ +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 = malloc((size_t)(seek_table_size * sizeof(mpc_seek_t))); + 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; +} + +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 = malloc((size_t) (tmp * sizeof(mpc_seek_t))); + 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); +} + +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; +} + +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; +} + +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 + */ +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 + */ +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; + 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) DEMUX_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); + } 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 = malloc(sizeof(mpc_demux)); + + if (p_tmp != 0) { + memset(p_tmp, 0, sizeof(mpc_demux)); + p_tmp->r = p_reader; + p_tmp->chap_nb = -1; + mpc_demux_clear_buff(p_tmp); + if (mpc_demux_header(p_tmp) == MPC_STATUS_OK && + mpc_demux_seek_init(p_tmp) == MPC_STATUS_OK) { + p_tmp->d = mpc_decoder_init(&p_tmp->si); + } else { + if (p_tmp->seek_table) + free(p_tmp->seek_table); + free(p_tmp); + p_tmp = 0; + } + } + + return p_tmp; +} + +void mpc_demux_exit(mpc_demux * d) +{ + mpc_decoder_exit(d->d); + free(d->seek_table); + free(d->chap); + free(d); +} + +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; + } + if (d->buffer + d->bytes_total - d->bits_reader.buff <= MAX_FRAME_SIZE) + mpc_demux_fill(d, (d->block_bits >> 3) + 1, 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 != ((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; +} + +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; +} + +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); +} diff --git a/third_party/musepack/libmpcdec/mpc_reader.c b/third_party/musepack/libmpcdec/mpc_reader.c new file mode 100755 index 0000000..06aa49e --- /dev/null +++ b/third_party/musepack/libmpcdec/mpc_reader.c @@ -0,0 +1,144 @@ +/* + 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_reader.c +/// Contains implementations for simple file-based mpc_reader +#include +#include "internal.h" +#include + +#define STDIO_MAGIC 0xF34B963C ///< Just a random safe-check value... +typedef struct mpc_reader_stdio_t { + FILE *p_file; + int file_size; + mpc_bool_t is_seekable; + mpc_int32_t magic; +} mpc_reader_stdio; + +/// mpc_reader callback implementations +static mpc_int32_t +read_stdio(mpc_reader *p_reader, void *ptr, mpc_int32_t size) +{ + mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; + if(p_stdio->magic != STDIO_MAGIC) return MPC_STATUS_FAIL; + return (mpc_int32_t) fread(ptr, 1, size, p_stdio->p_file); +} + +static mpc_bool_t +seek_stdio(mpc_reader *p_reader, mpc_int32_t offset) +{ + mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; + if(p_stdio->magic != STDIO_MAGIC) return MPC_FALSE; + return p_stdio->is_seekable ? fseek(p_stdio->p_file, offset, SEEK_SET) == 0 : MPC_FALSE; +} + +static mpc_int32_t +tell_stdio(mpc_reader *p_reader) +{ + mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; + if(p_stdio->magic != STDIO_MAGIC) return MPC_STATUS_FAIL; + return ftell(p_stdio->p_file); +} + +static mpc_int32_t +get_size_stdio(mpc_reader *p_reader) +{ + mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; + if(p_stdio->magic != STDIO_MAGIC) return MPC_STATUS_FAIL; + return p_stdio->file_size; +} + +static mpc_bool_t +canseek_stdio(mpc_reader *p_reader) +{ + mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; + if(p_stdio->magic != STDIO_MAGIC) return MPC_FALSE; + return p_stdio->is_seekable; +} + +mpc_status +mpc_reader_init_stdio_stream(mpc_reader * p_reader, FILE * p_file) +{ + mpc_reader tmp_reader; mpc_reader_stdio *p_stdio; int err; + + p_stdio = NULL; + memset(&tmp_reader, 0, sizeof tmp_reader); + p_stdio = malloc(sizeof *p_stdio); + if(!p_stdio) return MPC_STATUS_FAIL; + memset(p_stdio, 0, sizeof *p_stdio); + + p_stdio->magic = STDIO_MAGIC; + p_stdio->p_file = p_file; + p_stdio->is_seekable = MPC_TRUE; + err = fseek(p_stdio->p_file, 0, SEEK_END); + if(err < 0) goto clean; + err = ftell(p_stdio->p_file); + if(err < 0) goto clean; + p_stdio->file_size = err; + err = fseek(p_stdio->p_file, 0, SEEK_SET); + if(err < 0) goto clean; + + tmp_reader.data = p_stdio; + tmp_reader.canseek = canseek_stdio; + tmp_reader.get_size = get_size_stdio; + tmp_reader.read = read_stdio; + tmp_reader.seek = seek_stdio; + tmp_reader.tell = tell_stdio; + + *p_reader = tmp_reader; + return MPC_STATUS_OK; +clean: + if(p_stdio && p_stdio->p_file) + fclose(p_stdio->p_file); + free(p_stdio); + return MPC_STATUS_FAIL; +} + +mpc_status +mpc_reader_init_stdio(mpc_reader *p_reader, const char *filename) +{ + FILE * stream = fopen(filename, "rb"); + if (stream == NULL) return MPC_STATUS_FAIL; + return mpc_reader_init_stdio_stream(p_reader,stream); +} + +void +mpc_reader_exit_stdio(mpc_reader *p_reader) +{ + mpc_reader_stdio *p_stdio = (mpc_reader_stdio*) p_reader->data; + if(p_stdio->magic != STDIO_MAGIC) return; + fclose(p_stdio->p_file); + free(p_stdio); + p_reader->data = NULL; +} + diff --git a/third_party/musepack/libmpcdec/mpcdec_math.h b/third_party/musepack/libmpcdec/mpcdec_math.h new file mode 100755 index 0000000..59a77a4 --- /dev/null +++ b/third_party/musepack/libmpcdec/mpcdec_math.h @@ -0,0 +1,135 @@ +/* + 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_math.h +/// Libmpcdec internal math routines. +#ifndef _MPCDEC_MATH_H_ +#define _MPCDEC_MATH_H_ +#ifdef WIN32 +#pragma once +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef MPC_FIXED_POINT + +#ifdef _WIN32_WCE +#include +#define MPC_HAVE_MULHIGH +#endif + +//in fixedpoint mode, results in decode output buffer are in -MPC_FIXED_POINT_SCALE ... MPC_FIXED_POINT_SCALE range + +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 MPC_MULTIPLY_EX_NOTRUNCATE(X,Y,Z) \ + (((MPC_SAMPLE_FORMAT_MULTIPLY)(X) * (MPC_SAMPLE_FORMAT_MULTIPLY)(Y)) >> (Z)) + +#ifdef _DEBUG +static mpc_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 mpc_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 + +#ifdef MPC_HAVE_MULHIGH +#define MPC_MULTIPLY_FRACT(X,Y) _MulHigh(X,Y) +#else +#define MPC_MULTIPLY_FRACT(X,Y) MPC_MULTIPLY_EX(X,Y,32) +#endif + +#define MPC_MAKE_FRACT_CONST(X) (MPC_SAMPLE_FORMAT)((X) * (double)(((mpc_int64_t)1)<<32) ) +#define MPC_MULTIPLY_FRACT_CONST(X,Y) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST(Y)) +#define MPC_MULTIPLY_FRACT_CONST_FIX(X,Y,Z) ( MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y / (1<<(Z)) )) << (Z) ) +#define MPC_MULTIPLY_FRACT_CONST_SHR(X,Y,Z) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y / (1<<(Z)) )) + +#define MPC_MULTIPLY_FLOAT_INT(X,Y) ((X)*(Y)) +#define MPC_SCALE_CONST(X,Y,Z) MPC_MULTIPLY_EX(X,MAKE_MPC_SAMPLE_EX(Y,Z),(Z)) +#define MPC_SCALE_CONST_SHL(X,Y,Z,S) MPC_MULTIPLY_EX(X,MAKE_MPC_SAMPLE_EX(Y,Z),(Z)-(S)) +#define MPC_SCALE_CONST_SHR(X,Y,Z,S) MPC_MULTIPLY_EX(X,MAKE_MPC_SAMPLE_EX(Y,Z),(Z)+(S)) +#define MPC_SHR(X,Y) ((X)>>(Y)) +#define MPC_SHL(X,Y) ((X)<<(Y)) + +#else + +//in floating-point mode, decoded samples are in -1...1 range + +#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_FRACT_CONST(X,Y) MPC_MULTPLY_FRACT(X,MPC_MAKE_FRACT_CONST(Y)) +#define MPC_MULTIPLY_FRACT_CONST_SHR(X,Y,Z) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y )) +#define MPC_MULTIPLY_FRACT_CONST_FIX(X,Y,Z) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y )) + +#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_SCALE_CONST(X,Y,Z) ((X)*(Y)) +#define MPC_SCALE_CONST_SHL(X,Y,Z,S) ((X)*(Y)) +#define MPC_SCALE_CONST_SHR(X,Y,Z,S) ((X)*(Y)) +#define MPC_SHR(X,Y) (X) +#define MPC_SHL(X,Y) (X) + +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/third_party/musepack/libmpcdec/requant.c b/third_party/musepack/libmpcdec/requant.c new file mode 100755 index 0000000..c74d145 --- /dev/null +++ b/third_party/musepack/libmpcdec/requant.c @@ -0,0 +1,124 @@ +/* + 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 + +#include "requant.h" +#include "mpcdec_math.h" +#include "decoder.h" + +/* C O N S T A N T S */ +// Bits per sample for chosen quantizer +const mpc_uint8_t Res_bit [18] = { + 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] = { + _(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] = { + 2, + 0, 1, 2, 3, 4, 7, 15, 31, 63, + 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767 +}; + +#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 + +/* F U N C T I O N S */ + +#define SET_SCF(N,X) d->SCF[N] = MAKE_MPC_SAMPLE_EX(X,d->SCF_shift[N] = (mpc_uint8_t) find_shift(X)); + +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, double scale_factor) +{ + mpc_decoder_scale_output(d, scale_factor); +} diff --git a/third_party/musepack/libmpcdec/requant.h b/third_party/musepack/libmpcdec/requant.h new file mode 100755 index 0000000..eb3124d --- /dev/null +++ b/third_party/musepack/libmpcdec/requant.h @@ -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 + +#ifdef __cplusplus +extern "C" { +#endif + + +/* C O N S T A N T S */ +const mpc_uint8_t Res_bit [18]; ///< Bits per sample for chosen quantizer +const MPC_SAMPLE_FORMAT __Cc [1 + 18]; ///< Requantization coefficients +const mpc_int16_t __Dc [1 + 18]; ///< Requantization offset + +#define Cc (__Cc + 1) +#define Dc (__Dc + 1) + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/third_party/musepack/libmpcdec/streaminfo.c b/third_party/musepack/libmpcdec/streaminfo.c new file mode 100755 index 0000000..0e2e844 --- /dev/null +++ b/third_party/musepack/libmpcdec/streaminfo.c @@ -0,0 +1,245 @@ +/* + 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 +#include +#include +#include +#include "internal.h" +#include "huffman.h" +#include "mpc_bits_reader.h" + +unsigned long mpc_crc32(unsigned char *buf, int len); + +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 }; + +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]; +} + +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_uint16_t Estimatedpeak_title = 0; + mpc_uint32_t frames, last_frame_samples; + + si->bitrate = 0; + frames = (mpc_bits_read(r, 16) << 16) | mpc_bits_read(r, 16); + mpc_bits_read(r, 1); // intensity stereo : should be 0 + si->ms = mpc_bits_read(r, 1); + si->max_band = mpc_bits_read(r, 6); + si->profile = mpc_bits_read(r, 4); + si->profile_name = mpc_get_version_string(si->profile); + mpc_bits_read(r, 2); // Link ? + si->sample_freq = samplefreqs[mpc_bits_read(r, 2)]; + Estimatedpeak_title = (mpc_uint16_t) mpc_bits_read(r, 16); // read the ReplayGain data + si->gain_title = (mpc_uint16_t) mpc_bits_read(r, 16); + si->peak_title = (mpc_uint16_t) mpc_bits_read(r, 16); + si->gain_album = (mpc_uint16_t) mpc_bits_read(r, 16); + si->peak_album = (mpc_uint16_t) mpc_bits_read(r, 16); + si->is_true_gapless = mpc_bits_read(r, 1); // true gapless: used? + last_frame_samples = mpc_bits_read(r, 11); // true gapless: valid samples for last frame + si->fast_seek = mpc_bits_read(r, 1); // fast seeking + mpc_bits_read(r, 19); // unused + si->encoder_version = mpc_bits_read(r, 8); + si->channels = 2; + si->block_pwr = 0; + + // 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 = (si->tag_offset - si->header_position) * 8.0 + * si->sample_freq / si->samples; + + return check_streaminfo(si); +} + +/// Reads replay gain datas +void streaminfo_gain(mpc_streaminfo* si, const mpc_bits_reader * r_in) +{ + mpc_bits_reader r = *r_in; + + int version = mpc_bits_read(&r, 8); // gain version + if (version != 1) // we only know ver 1 + return; + si->gain_title = (mpc_uint16_t) mpc_bits_read(&r, 16); + si->peak_title = (mpc_uint16_t) mpc_bits_read(&r, 16); + si->gain_album = (mpc_uint16_t) mpc_bits_read(&r, 16); + si->peak_album = (mpc_uint16_t) mpc_bits_read(&r, 16); +} + +/// Reads streaminfo from SV8 header. +mpc_status +streaminfo_read_header_sv8(mpc_streaminfo* si, const mpc_bits_reader * r_in, + mpc_size_t block_size) +{ + mpc_uint32_t CRC; + mpc_bits_reader r = *r_in; + + CRC = (mpc_bits_read(&r, 16) << 16) | mpc_bits_read(&r, 16); + if (CRC != mpc_crc32(r.buff + 1 - (r.count >> 3), (int)block_size - 4)) + return MPC_STATUS_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 = (si->tag_offset - si->header_position) * 8.0 + * 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) / 8.; + 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 + + + mpc_get_encoder_string(si); +} + +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; +} diff --git a/third_party/musepack/libmpcdec/synth_filter.c b/third_party/musepack/libmpcdec/synth_filter.c new file mode 100755 index 0000000..0d0c345 --- /dev/null +++ b/third_party/musepack/libmpcdec/synth_filter.c @@ -0,0 +1,430 @@ +/* + 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 synth_filter.c +/// Synthesis functions. +/// \todo document me +#include +#include +#include "decoder.h" +#include "mpcdec_math.h" + +/* C O N S T A N T S */ +#define MPC_FIXED_POINT_SYNTH_FIX 2 + +#undef _ +#ifdef MPC_FIXED_POINT +#define _(value) MPC_MAKE_FRACT_CONST((double)value/(double)(0x40000)) +#else +#define _(value) MAKE_MPC_SAMPLE((double)value/(double)(0x10000)) +#endif + + +static const MPC_SAMPLE_FORMAT Di_opt [32] [16] = { + { _( 0), _( -29), _( 213), _( -459), _( 2037), _(-5153), _( 6574), _(-37489), _(75038), _(37489), _(6574), _( 5153), _(2037), _( 459), _(213), _(29) }, + { _( -1), _( -31), _( 218), _( -519), _( 2000), _(-5517), _( 5959), _(-39336), _(74992), _(35640), _(7134), _( 4788), _(2063), _( 401), _(208), _(26) }, + { _( -1), _( -35), _( 222), _( -581), _( 1952), _(-5879), _( 5288), _(-41176), _(74856), _(33791), _(7640), _( 4425), _(2080), _( 347), _(202), _(24) }, + { _( -1), _( -38), _( 225), _( -645), _( 1893), _(-6237), _( 4561), _(-43006), _(74630), _(31947), _(8092), _( 4063), _(2087), _( 294), _(196), _(21) }, + { _( -1), _( -41), _( 227), _( -711), _( 1822), _(-6589), _( 3776), _(-44821), _(74313), _(30112), _(8492), _( 3705), _(2085), _( 244), _(190), _(19) }, + { _( -1), _( -45), _( 228), _( -779), _( 1739), _(-6935), _( 2935), _(-46617), _(73908), _(28289), _(8840), _( 3351), _(2075), _( 197), _(183), _(17) }, + { _( -1), _( -49), _( 228), _( -848), _( 1644), _(-7271), _( 2037), _(-48390), _(73415), _(26482), _(9139), _( 3004), _(2057), _( 153), _(176), _(16) }, + { _( -2), _( -53), _( 227), _( -919), _( 1535), _(-7597), _( 1082), _(-50137), _(72835), _(24694), _(9389), _( 2663), _(2032), _( 111), _(169), _(14) }, + { _( -2), _( -58), _( 224), _( -991), _( 1414), _(-7910), _( 70), _(-51853), _(72169), _(22929), _(9592), _( 2330), _(2001), _( 72), _(161), _(13) }, + { _( -2), _( -63), _( 221), _(-1064), _( 1280), _(-8209), _( -998), _(-53534), _(71420), _(21189), _(9750), _( 2006), _(1962), _( 36), _(154), _(11) }, + { _( -2), _( -68), _( 215), _(-1137), _( 1131), _(-8491), _( -2122), _(-55178), _(70590), _(19478), _(9863), _( 1692), _(1919), _( 2), _(147), _(10) }, + { _( -3), _( -73), _( 208), _(-1210), _( 970), _(-8755), _( -3300), _(-56778), _(69679), _(17799), _(9935), _( 1388), _(1870), _( -29), _(139), _( 9) }, + { _( -3), _( -79), _( 200), _(-1283), _( 794), _(-8998), _( -4533), _(-58333), _(68692), _(16155), _(9966), _( 1095), _(1817), _( -57), _(132), _( 8) }, + { _( -4), _( -85), _( 189), _(-1356), _( 605), _(-9219), _( -5818), _(-59838), _(67629), _(14548), _(9959), _( 814), _(1759), _( -83), _(125), _( 7) }, + { _( -4), _( -91), _( 177), _(-1428), _( 402), _(-9416), _( -7154), _(-61289), _(66494), _(12980), _(9916), _( 545), _(1698), _(-106), _(117), _( 7) }, + { _( -5), _( -97), _( 163), _(-1498), _( 185), _(-9585), _( -8540), _(-62684), _(65290), _(11455), _(9838), _( 288), _(1634), _(-127), _(111), _( 6) }, + { _( -5), _(-104), _( 146), _(-1567), _( -45), _(-9727), _( -9975), _(-64019), _(64019), _( 9975), _(9727), _( 45), _(1567), _(-146), _(104), _( 5) }, + { _( -6), _(-111), _( 127), _(-1634), _( -288), _(-9838), _(-11455), _(-65290), _(62684), _( 8540), _(9585), _( -185), _(1498), _(-163), _( 97), _( 5) }, + { _( -7), _(-117), _( 106), _(-1698), _( -545), _(-9916), _(-12980), _(-66494), _(61289), _( 7154), _(9416), _( -402), _(1428), _(-177), _( 91), _( 4) }, + { _( -7), _(-125), _( 83), _(-1759), _( -814), _(-9959), _(-14548), _(-67629), _(59838), _( 5818), _(9219), _( -605), _(1356), _(-189), _( 85), _( 4) }, + { _( -8), _(-132), _( 57), _(-1817), _(-1095), _(-9966), _(-16155), _(-68692), _(58333), _( 4533), _(8998), _( -794), _(1283), _(-200), _( 79), _( 3) }, + { _( -9), _(-139), _( 29), _(-1870), _(-1388), _(-9935), _(-17799), _(-69679), _(56778), _( 3300), _(8755), _( -970), _(1210), _(-208), _( 73), _( 3) }, + { _(-10), _(-147), _( -2), _(-1919), _(-1692), _(-9863), _(-19478), _(-70590), _(55178), _( 2122), _(8491), _(-1131), _(1137), _(-215), _( 68), _( 2) }, + { _(-11), _(-154), _( -36), _(-1962), _(-2006), _(-9750), _(-21189), _(-71420), _(53534), _( 998), _(8209), _(-1280), _(1064), _(-221), _( 63), _( 2) }, + { _(-13), _(-161), _( -72), _(-2001), _(-2330), _(-9592), _(-22929), _(-72169), _(51853), _( -70), _(7910), _(-1414), _( 991), _(-224), _( 58), _( 2) }, + { _(-14), _(-169), _(-111), _(-2032), _(-2663), _(-9389), _(-24694), _(-72835), _(50137), _(-1082), _(7597), _(-1535), _( 919), _(-227), _( 53), _( 2) }, + { _(-16), _(-176), _(-153), _(-2057), _(-3004), _(-9139), _(-26482), _(-73415), _(48390), _(-2037), _(7271), _(-1644), _( 848), _(-228), _( 49), _( 1) }, + { _(-17), _(-183), _(-197), _(-2075), _(-3351), _(-8840), _(-28289), _(-73908), _(46617), _(-2935), _(6935), _(-1739), _( 779), _(-228), _( 45), _( 1) }, + { _(-19), _(-190), _(-244), _(-2085), _(-3705), _(-8492), _(-30112), _(-74313), _(44821), _(-3776), _(6589), _(-1822), _( 711), _(-227), _( 41), _( 1) }, + { _(-21), _(-196), _(-294), _(-2087), _(-4063), _(-8092), _(-31947), _(-74630), _(43006), _(-4561), _(6237), _(-1893), _( 645), _(-225), _( 38), _( 1) }, + { _(-24), _(-202), _(-347), _(-2080), _(-4425), _(-7640), _(-33791), _(-74856), _(41176), _(-5288), _(5879), _(-1952), _( 581), _(-222), _( 35), _( 1) }, + { _(-26), _(-208), _(-401), _(-2063), _(-4788), _(-7134), _(-35640), _(-74992), _(39336), _(-5959), _(5517), _(-2000), _( 519), _(-218), _( 31), _( 1) } +}; + +#undef _ + +static void +mpc_compute_new_V(const MPC_SAMPLE_FORMAT* p_sample, MPC_SAMPLE_FORMAT* pV) +{ + // Calculating new V-buffer values for left channel + // calculate new V-values (ISO-11172-3, p. 39) + // based upon fast-MDCT algorithm by Byeong Gi Lee + MPC_SAMPLE_FORMAT A00, A01, A02, A03, A04, A05, A06, A07, A08, A09, A10, A11, A12, A13, A14, A15; + MPC_SAMPLE_FORMAT B00, B01, B02, B03, B04, B05, B06, B07, B08, B09, B10, B11, B12, B13, B14, B15; + MPC_SAMPLE_FORMAT tmp; + + A00 = p_sample[ 0] + p_sample[31]; + A01 = p_sample[ 1] + p_sample[30]; + A02 = p_sample[ 2] + p_sample[29]; + A03 = p_sample[ 3] + p_sample[28]; + A04 = p_sample[ 4] + p_sample[27]; + A05 = p_sample[ 5] + p_sample[26]; + A06 = p_sample[ 6] + p_sample[25]; + A07 = p_sample[ 7] + p_sample[24]; + A08 = p_sample[ 8] + p_sample[23]; + A09 = p_sample[ 9] + p_sample[22]; + A10 = p_sample[10] + p_sample[21]; + A11 = p_sample[11] + p_sample[20]; + A12 = p_sample[12] + p_sample[19]; + A13 = p_sample[13] + p_sample[18]; + A14 = p_sample[14] + p_sample[17]; + A15 = p_sample[15] + p_sample[16]; + + B00 = A00 + A15; + B01 = A01 + A14; + B02 = A02 + A13; + B03 = A03 + A12; + B04 = A04 + A11; + B05 = A05 + A10; + B06 = A06 + A09; + B07 = A07 + A08;; + B08 = MPC_SCALE_CONST((A00 - A15) , 0.5024192929f , 31); + B09 = MPC_SCALE_CONST((A01 - A14) , 0.5224986076f , 31); + B10 = MPC_SCALE_CONST((A02 - A13) , 0.5669440627f , 31); + B11 = MPC_SCALE_CONST((A03 - A12) , 0.6468217969f , 31); + B12 = MPC_SCALE_CONST((A04 - A11) , 0.7881546021f , 31); + B13 = MPC_SCALE_CONST((A05 - A10) , 1.0606776476f , 30); + B14 = MPC_SCALE_CONST((A06 - A09) , 1.7224471569f , 30); + B15 = MPC_SCALE_CONST((A07 - A08) , 5.1011486053f , 28); + + A00 = B00 + B07; + A01 = B01 + B06; + A02 = B02 + B05; + A03 = B03 + B04; + A04 = MPC_SCALE_CONST((B00 - B07) , 0.5097956061f , 31); + A05 = MPC_SCALE_CONST((B01 - B06) , 0.6013448834f , 31); + A06 = MPC_SCALE_CONST((B02 - B05) , 0.8999761939f , 31); + A07 = MPC_SCALE_CONST((B03 - B04) , 2.5629155636f , 29); + A08 = B08 + B15; + A09 = B09 + B14; + A10 = B10 + B13; + A11 = B11 + B12; + A12 = MPC_SCALE_CONST((B08 - B15) , 0.5097956061f , 31); + A13 = MPC_SCALE_CONST((B09 - B14) , 0.6013448834f , 31); + A14 = MPC_SCALE_CONST((B10 - B13) , 0.8999761939f , 31); + A15 = MPC_SCALE_CONST((B11 - B12) , 2.5629155636f , 29); + + B00 = A00 + A03; + B01 = A01 + A02; + B02 = MPC_MULTIPLY_FRACT_CONST_FIX((A00 - A03) , 0.5411961079f , 1); + B03 = MPC_MULTIPLY_FRACT_CONST_FIX((A01 - A02) , 1.3065630198f , 2); + B04 = A04 + A07; + B05 = A05 + A06; + B06 = MPC_MULTIPLY_FRACT_CONST_FIX((A04 - A07) , 0.5411961079f , 1); + B07 = MPC_MULTIPLY_FRACT_CONST_FIX((A05 - A06) , 1.3065630198f , 2); + B08 = A08 + A11; + B09 = A09 + A10; + B10 = MPC_MULTIPLY_FRACT_CONST_FIX((A08 - A11) , 0.5411961079f , 1); + B11 = MPC_MULTIPLY_FRACT_CONST_FIX((A09 - A10) , 1.3065630198f , 2); + B12 = A12 + A15; + B13 = A13 + A14; + B14 = MPC_MULTIPLY_FRACT_CONST_FIX((A12 - A15) , 0.5411961079f , 1); + B15 = MPC_MULTIPLY_FRACT_CONST_FIX((A13 - A14) , 1.3065630198f , 2); + + A00 = B00 + B01; + A01 = MPC_MULTIPLY_FRACT_CONST_FIX((B00 - B01) , 0.7071067691f , 1); + A02 = B02 + B03; + A03 = MPC_MULTIPLY_FRACT_CONST_FIX((B02 - B03) , 0.7071067691f , 1); + A04 = B04 + B05; + A05 = MPC_MULTIPLY_FRACT_CONST_FIX((B04 - B05) , 0.7071067691f , 1); + A06 = B06 + B07; + A07 = MPC_MULTIPLY_FRACT_CONST_FIX((B06 - B07) , 0.7071067691f , 1); + A08 = B08 + B09; + A09 = MPC_MULTIPLY_FRACT_CONST_FIX((B08 - B09) , 0.7071067691f , 1); + A10 = B10 + B11; + A11 = MPC_MULTIPLY_FRACT_CONST_FIX((B10 - B11) , 0.7071067691f , 1); + A12 = B12 + B13; + A13 = MPC_MULTIPLY_FRACT_CONST_FIX((B12 - B13) , 0.7071067691f , 1); + A14 = B14 + B15; + A15 = MPC_MULTIPLY_FRACT_CONST_FIX((B14 - B15) , 0.7071067691f , 1); + + pV[48] = -A00; + pV[ 0] = A01; + pV[40] = -A02 - (pV[ 8] = A03); + pV[36] = -((pV[ 4] = A05 + (pV[12] = A07)) + A06); + pV[44] = - A04 - A06 - A07; + pV[ 6] = (pV[10] = A11 + (pV[14] = A15)) + A13; + pV[38] = (pV[34] = -(pV[ 2] = A09 + A13 + A15) - A14) + A09 - A10 - A11; + pV[46] = (tmp = -(A12 + A14 + A15)) - A08; + pV[42] = tmp - A10 - A11; + + A00 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 0] - p_sample[31]) , 0.5006030202f , MPC_FIXED_POINT_SYNTH_FIX); + A01 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 1] - p_sample[30]) , 0.5054709315f , MPC_FIXED_POINT_SYNTH_FIX); + A02 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 2] - p_sample[29]) , 0.5154473186f , MPC_FIXED_POINT_SYNTH_FIX); + A03 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 3] - p_sample[28]) , 0.5310425758f , MPC_FIXED_POINT_SYNTH_FIX); + A04 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 4] - p_sample[27]) , 0.5531039238f , MPC_FIXED_POINT_SYNTH_FIX); + A05 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 5] - p_sample[26]) , 0.5829349756f , MPC_FIXED_POINT_SYNTH_FIX); + A06 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 6] - p_sample[25]) , 0.6225041151f , MPC_FIXED_POINT_SYNTH_FIX); + A07 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 7] - p_sample[24]) , 0.6748083234f , MPC_FIXED_POINT_SYNTH_FIX); + A08 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 8] - p_sample[23]) , 0.7445362806f , MPC_FIXED_POINT_SYNTH_FIX); + A09 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[ 9] - p_sample[22]) , 0.8393496275f , MPC_FIXED_POINT_SYNTH_FIX); + A10 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[10] - p_sample[21]) , 0.9725682139f , MPC_FIXED_POINT_SYNTH_FIX); +#if MPC_FIXED_POINT_SYNTH_FIX>=2 + A11 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[11] - p_sample[20]) , 1.1694399118f , MPC_FIXED_POINT_SYNTH_FIX); + A12 = MPC_MULTIPLY_FRACT_CONST_SHR((p_sample[12] - p_sample[19]) , 1.4841645956f , MPC_FIXED_POINT_SYNTH_FIX); +#else + A11 = MPC_SCALE_CONST_SHR ((p_sample[11] - p_sample[20]) , 1.1694399118f , 30, MPC_FIXED_POINT_SYNTH_FIX); + A12 = MPC_SCALE_CONST_SHR ((p_sample[12] - p_sample[19]) , 1.4841645956f , 30, MPC_FIXED_POINT_SYNTH_FIX); +#endif + A13 = MPC_SCALE_CONST_SHR ((p_sample[13] - p_sample[18]) , 2.0577809811f , 29, MPC_FIXED_POINT_SYNTH_FIX); + A14 = MPC_SCALE_CONST_SHR ((p_sample[14] - p_sample[17]) , 3.4076085091f , 29, MPC_FIXED_POINT_SYNTH_FIX); + A15 = MPC_SCALE_CONST_SHR ((p_sample[15] - p_sample[16]) , 10.1900081635f, 27 ,MPC_FIXED_POINT_SYNTH_FIX); + + B00 = A00 + A15; + B01 = A01 + A14; + B02 = A02 + A13; + B03 = A03 + A12; + B04 = A04 + A11; + B05 = A05 + A10; + B06 = A06 + A09; + B07 = A07 + A08; + B08 = MPC_SCALE_CONST((A00 - A15) , 0.5024192929f , 31); + B09 = MPC_SCALE_CONST((A01 - A14) , 0.5224986076f , 31); + B10 = MPC_SCALE_CONST((A02 - A13) , 0.5669440627f , 31); + B11 = MPC_SCALE_CONST((A03 - A12) , 0.6468217969f , 31); + B12 = MPC_SCALE_CONST((A04 - A11) , 0.7881546021f , 31); + B13 = MPC_SCALE_CONST((A05 - A10) , 1.0606776476f , 30); + B14 = MPC_SCALE_CONST((A06 - A09) , 1.7224471569f , 30); + B15 = MPC_SCALE_CONST((A07 - A08) , 5.1011486053f , 28); + + A00 = B00 + B07; + A01 = B01 + B06; + A02 = B02 + B05; + A03 = B03 + B04; + A04 = MPC_SCALE_CONST((B00 - B07) , 0.5097956061f , 31); + A05 = MPC_SCALE_CONST((B01 - B06) , 0.6013448834f , 31); + A06 = MPC_SCALE_CONST((B02 - B05) , 0.8999761939f , 31); + A07 = MPC_SCALE_CONST((B03 - B04) , 2.5629155636f , 29); + A08 = B08 + B15; + A09 = B09 + B14; + A10 = B10 + B13; + A11 = B11 + B12; + A12 = MPC_SCALE_CONST((B08 - B15) , 0.5097956061f , 31); + A13 = MPC_SCALE_CONST((B09 - B14) , 0.6013448834f , 31); + A14 = MPC_SCALE_CONST((B10 - B13) , 0.8999761939f , 31); + A15 = MPC_SCALE_CONST((B11 - B12) , 2.5629155636f , 29); + + B00 = A00 + A03; + B01 = A01 + A02; + B02 = MPC_SCALE_CONST((A00 - A03) , 0.5411961079f , 31); + B03 = MPC_SCALE_CONST((A01 - A02) , 1.3065630198f , 30); + B04 = A04 + A07; + B05 = A05 + A06; + B06 = MPC_SCALE_CONST((A04 - A07) , 0.5411961079f , 31); + B07 = MPC_SCALE_CONST((A05 - A06) , 1.3065630198f , 30); + B08 = A08 + A11; + B09 = A09 + A10; + B10 = MPC_SCALE_CONST((A08 - A11) , 0.5411961079f , 31); + B11 = MPC_SCALE_CONST((A09 - A10) , 1.3065630198f , 30); + B12 = A12 + A15; + B13 = A13 + A14; + B14 = MPC_SCALE_CONST((A12 - A15) , 0.5411961079f , 31); + B15 = MPC_SCALE_CONST((A13 - A14) , 1.3065630198f , 30); + + A00 = MPC_SHL(B00 + B01, MPC_FIXED_POINT_SYNTH_FIX); + A01 = MPC_SCALE_CONST_SHL((B00 - B01) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); + A02 = MPC_SHL(B02 + B03, MPC_FIXED_POINT_SYNTH_FIX); + A03 = MPC_SCALE_CONST_SHL((B02 - B03) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); + A04 = MPC_SHL(B04 + B05, MPC_FIXED_POINT_SYNTH_FIX); + A05 = MPC_SCALE_CONST_SHL((B04 - B05) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); + A06 = MPC_SHL(B06 + B07, MPC_FIXED_POINT_SYNTH_FIX); + A07 = MPC_SCALE_CONST_SHL((B06 - B07) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); + A08 = MPC_SHL(B08 + B09, MPC_FIXED_POINT_SYNTH_FIX); + A09 = MPC_SCALE_CONST_SHL((B08 - B09) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); + A10 = MPC_SHL(B10 + B11, MPC_FIXED_POINT_SYNTH_FIX); + A11 = MPC_SCALE_CONST_SHL((B10 - B11) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); + A12 = MPC_SHL(B12 + B13, MPC_FIXED_POINT_SYNTH_FIX); + A13 = MPC_SCALE_CONST_SHL((B12 - B13) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); + A14 = MPC_SHL(B14 + B15, MPC_FIXED_POINT_SYNTH_FIX); + A15 = MPC_SCALE_CONST_SHL((B14 - B15) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); + + // mehrfach verwendete Ausdrcke: A04+A06+A07, A09+A13+A15 + pV[ 5] = (pV[11] = (pV[13] = A07 + (pV[15] = A15)) + A11) + A05 + A13; + pV[ 7] = (pV[ 9] = A03 + A11 + A15) + A13; + pV[33] = -(pV[ 1] = A01 + A09 + A13 + A15) - A14; + pV[35] = -(pV[ 3] = A05 + A07 + A09 + A13 + A15) - A06 - A14; + pV[37] = (tmp = -(A10 + A11 + A13 + A14 + A15)) - A05 - A06 - A07; + pV[39] = tmp - A02 - A03; // abh�gig vom Befehl drber + pV[41] = (tmp += A13 - A12) - A02 - A03; // abh�gig vom Befehl 2 drber + pV[43] = tmp - A04 - A06 - A07; // abh�gig von Befehlen 1 und 3 drber + pV[47] = (tmp = -(A08 + A12 + A14 + A15)) - A00; + pV[45] = tmp - A04 - A06 - A07; // abh�gig vom Befehl drber + + pV[32] = -pV[ 0]; + pV[31] = -pV[ 1]; + pV[30] = -pV[ 2]; + pV[29] = -pV[ 3]; + pV[28] = -pV[ 4]; + pV[27] = -pV[ 5]; + pV[26] = -pV[ 6]; + pV[25] = -pV[ 7]; + pV[24] = -pV[ 8]; + pV[23] = -pV[ 9]; + pV[22] = -pV[10]; + pV[21] = -pV[11]; + pV[20] = -pV[12]; + pV[19] = -pV[13]; + pV[18] = -pV[14]; + pV[17] = -pV[15]; + + pV[63] = pV[33]; + pV[62] = pV[34]; + pV[61] = pV[35]; + pV[60] = pV[36]; + pV[59] = pV[37]; + pV[58] = pV[38]; + pV[57] = pV[39]; + pV[56] = pV[40]; + pV[55] = pV[41]; + pV[54] = pV[42]; + pV[53] = pV[43]; + pV[52] = pV[44]; + pV[51] = pV[45]; + pV[50] = pV[46]; + pV[49] = pV[47]; +} + +static void +mpc_synthese_filter_float_internal(MPC_SAMPLE_FORMAT* p_out, MPC_SAMPLE_FORMAT* pV, const MPC_SAMPLE_FORMAT* pY, mpc_int_t channels) +{ + mpc_uint32_t n; + for ( n = 0; n < 36; n++, pY += 32 ) + { + MPC_SAMPLE_FORMAT* pData = p_out; + const MPC_SAMPLE_FORMAT* pD = (const MPC_SAMPLE_FORMAT*) &Di_opt; + mpc_int32_t k; + pV -= 64; + mpc_compute_new_V( pY, pV ); + for ( k = 0; k < 32; k++, pD += 16, pV++ ) + { + *pData = MPC_SHL( + MPC_MULTIPLY_FRACT(pV[ 0], pD[ 0]) + MPC_MULTIPLY_FRACT(pV[ 96], pD[ 1]) + MPC_MULTIPLY_FRACT(pV[128], pD[ 2]) + MPC_MULTIPLY_FRACT(pV[224], pD[ 3]) + + MPC_MULTIPLY_FRACT(pV[256], pD[ 4]) + MPC_MULTIPLY_FRACT(pV[352], pD[ 5]) + MPC_MULTIPLY_FRACT(pV[384], pD[ 6]) + MPC_MULTIPLY_FRACT(pV[480], pD[ 7]) + + MPC_MULTIPLY_FRACT(pV[512], pD[ 8]) + MPC_MULTIPLY_FRACT(pV[608], pD[ 9]) + MPC_MULTIPLY_FRACT(pV[640], pD[10]) + MPC_MULTIPLY_FRACT(pV[736], pD[11]) + + MPC_MULTIPLY_FRACT(pV[768], pD[12]) + MPC_MULTIPLY_FRACT(pV[864], pD[13]) + MPC_MULTIPLY_FRACT(pV[896], pD[14]) + MPC_MULTIPLY_FRACT(pV[992], pD[15]) + , 2); + pData += channels; + } + pV -= 32; //bleh + p_out += 32 * channels; + } +} + +void +mpc_decoder_synthese_filter_float(mpc_decoder* p_dec, MPC_SAMPLE_FORMAT* p_out, mpc_int_t channels) +{ + /********* left channel ********/ + memmove(&p_dec->V_L[MPC_V_MEM], p_dec->V_L, 960 * sizeof *p_dec->V_L); + mpc_synthese_filter_float_internal(p_out, &p_dec->V_L[MPC_V_MEM], p_dec->Y_L[0], channels); + + /******** right channel ********/ + if (channels > 1) { + memmove(&p_dec->V_R[MPC_V_MEM], p_dec->V_R, 960 * sizeof *p_dec->V_R); + mpc_synthese_filter_float_internal(p_out + 1, &p_dec->V_R[MPC_V_MEM], p_dec->Y_R[0], channels); + } +} + +/*******************************************/ +/* */ +/* dithered synthesis */ +/* */ +/*******************************************/ + +static const mpc_uint8_t 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* p_dec) +{ +#if 1 + mpc_uint32_t t1, t2, t3, t4; + + t3 = t1 = p_dec->__r1; t4 = t2 = p_dec->__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 (p_dec->__r1 = (t3 >> 1) | t1 ) ^ (p_dec->__r2 = (t4 + t4) | t2 ); +#else + return (p_dec->__r1 = (p_dec->__r1 >> 1) | ((mpc_uint32_t) Parity[ p_dec->__r1 & 0xF5] << 31)) + ^ (p_dec->__r2 = (p_dec->__r2 << 1) | (mpc_uint32_t) Parity[(p_dec->__r2 >> 25) & 0x63]); +#endif +} diff --git a/third_party/musepack/libmpcenc/analy_filter.c b/third_party/musepack/libmpcenc/analy_filter.c new file mode 100755 index 0000000..fa8e0ff --- /dev/null +++ b/third_party/musepack/libmpcenc/analy_filter.c @@ -0,0 +1,344 @@ +/* + * Musepack audio compression + * Copyright (c) 2005-2009, The Musepack Development Team + * 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 + */ + +#include + +#include +#include + +#define FASTER + +/* C O N S T A N T S */ + +#undef _ +#define _(value) (float)(value##.##L / 0x200000) + +static float Ci_opt [512] = { + _( 0), _( 213), _( 2037), _( 6574), _(75038), _( 6574), _(2037), _(213), + _( -1), _( 218), _( 2000), _( 5959), _(74992), _( 7134), _(2063), _(208), + _( -1), _( 222), _( 1952), _( 5288), _(74856), _( 7640), _(2080), _(202), + _( -1), _( 225), _( 1893), _( 4561), _(74630), _( 8092), _(2087), _(196), + _( -1), _( 227), _( 1822), _( 3776), _(74313), _( 8492), _(2085), _(190), + _( -1), _( 228), _( 1739), _( 2935), _(73908), _( 8840), _(2075), _(183), + _( -1), _( 228), _( 1644), _( 2037), _(73415), _( 9139), _(2057), _(176), + _( -2), _( 227), _( 1535), _( 1082), _(72835), _( 9389), _(2032), _(169), + _( -2), _( 224), _( 1414), _( 70), _(72169), _( 9592), _(2001), _(161), + _( -2), _( 221), _( 1280), _( -998), _(71420), _( 9750), _(1962), _(154), + _( -2), _( 215), _( 1131), _( -2122), _(70590), _( 9863), _(1919), _(147), + _( -3), _( 208), _( 970), _( -3300), _(69679), _( 9935), _(1870), _(139), + _( -3), _( 200), _( 794), _( -4533), _(68692), _( 9966), _(1817), _(132), + _( -4), _( 189), _( 605), _( -5818), _(67629), _( 9959), _(1759), _(125), + _( -4), _( 177), _( 402), _( -7154), _(66494), _( 9916), _(1698), _(117), + _( -5), _( 163), _( 185), _( -8540), _(65290), _( 9838), _(1634), _(111), + _( -5), _( 146), _( -45), _( -9975), _(64019), _( 9727), _(1567), _(104), + _( -6), _( 127), _( -288), _(-11455), _(62684), _( 9585), _(1498), _( 97), + _( -7), _( 106), _( -545), _(-12980), _(61289), _( 9416), _(1428), _( 91), + _( -7), _( 83), _( -814), _(-14548), _(59838), _( 9219), _(1356), _( 85), + _( -8), _( 57), _(-1095), _(-16155), _(58333), _( 8998), _(1283), _( 79), + _( -9), _( 29), _(-1388), _(-17799), _(56778), _( 8755), _(1210), _( 73), + _( -10), _( -2), _(-1692), _(-19478), _(55178), _( 8491), _(1137), _( 68), + _( -11), _( -36), _(-2006), _(-21189), _(53534), _( 8209), _(1064), _( 63), + _( -13), _( -72), _(-2330), _(-22929), _(51853), _( 7910), _( 991), _( 58), + _( -14), _( -111), _(-2663), _(-24694), _(50137), _( 7597), _( 919), _( 53), + _( -16), _( -153), _(-3004), _(-26482), _(48390), _( 7271), _( 848), _( 49), + _( -17), _( -197), _(-3351), _(-28289), _(46617), _( 6935), _( 779), _( 45), + _( -19), _( -244), _(-3705), _(-30112), _(44821), _( 6589), _( 711), _( 41), + _( -21), _( -294), _(-4063), _(-31947), _(43006), _( 6237), _( 645), _( 38), + _( -24), _( -347), _(-4425), _(-33791), _(41176), _( 5879), _( 581), _( 35), + _( -26), _( -401), _(-4788), _(-35640), _(39336), _( 5517), _( 519), _( 31), + _( -29), _( -459), _(-5153), _(-37489), _(37489), _( 5153), _( 459), _( 29), + _( -31), _( -519), _(-5517), _(-39336), _(35640), _( 4788), _( 401), _( 26), + _( -35), _( -581), _(-5879), _(-41176), _(33791), _( 4425), _( 347), _( 24), + _( -38), _( -645), _(-6237), _(-43006), _(31947), _( 4063), _( 294), _( 21), + _( -41), _( -711), _(-6589), _(-44821), _(30112), _( 3705), _( 244), _( 19), + _( -45), _( -779), _(-6935), _(-46617), _(28289), _( 3351), _( 197), _( 17), + _( -49), _( -848), _(-7271), _(-48390), _(26482), _( 3004), _( 153), _( 16), + _( -53), _( -919), _(-7597), _(-50137), _(24694), _( 2663), _( 111), _( 14), + _( -58), _( -991), _(-7910), _(-51853), _(22929), _( 2330), _( 72), _( 13), + _( -63), _(-1064), _(-8209), _(-53534), _(21189), _( 2006), _( 36), _( 11), + _( -68), _(-1137), _(-8491), _(-55178), _(19478), _( 1692), _( 2), _( 10), + _( -73), _(-1210), _(-8755), _(-56778), _(17799), _( 1388), _( -29), _( 9), + _( -79), _(-1283), _(-8998), _(-58333), _(16155), _( 1095), _( -57), _( 8), + _( -85), _(-1356), _(-9219), _(-59838), _(14548), _( 814), _( -83), _( 7), + _( -91), _(-1428), _(-9416), _(-61289), _(12980), _( 545), _(-106), _( 7), + _( -97), _(-1498), _(-9585), _(-62684), _(11455), _( 288), _(-127), _( 6), + _(-104), _(-1567), _(-9727), _(-64019), _( 9975), _( 45), _(-146), _( 5), + _(-111), _(-1634), _(-9838), _(-65290), _( 8540), _( -185), _(-163), _( 5), + _(-117), _(-1698), _(-9916), _(-66494), _( 7154), _( -402), _(-177), _( 4), + _(-125), _(-1759), _(-9959), _(-67629), _( 5818), _( -605), _(-189), _( 4), + _(-132), _(-1817), _(-9966), _(-68692), _( 4533), _( -794), _(-200), _( 3), + _(-139), _(-1870), _(-9935), _(-69679), _( 3300), _( -970), _(-208), _( 3), + _(-147), _(-1919), _(-9863), _(-70590), _( 2122), _(-1131), _(-215), _( 2), + _(-154), _(-1962), _(-9750), _(-71420), _( 998), _(-1280), _(-221), _( 2), + _(-161), _(-2001), _(-9592), _(-72169), _( -70), _(-1414), _(-224), _( 2), + _(-169), _(-2032), _(-9389), _(-72835), _(-1082), _(-1535), _(-227), _( 2), + _(-176), _(-2057), _(-9139), _(-73415), _(-2037), _(-1644), _(-228), _( 1), + _(-183), _(-2075), _(-8840), _(-73908), _(-2935), _(-1739), _(-228), _( 1), + _(-190), _(-2085), _(-8492), _(-74313), _(-3776), _(-1822), _(-227), _( 1), + _(-196), _(-2087), _(-8092), _(-74630), _(-4561), _(-1893), _(-225), _( 1), + _(-202), _(-2080), _(-7640), _(-74856), _(-5288), _(-1952), _(-222), _( 1), + _(-208), _(-2063), _(-7134), _(-74992), _(-5959), _(-2000), _(-218), _( 1), +}; +#undef _ + + +static float M [1024]; + +void +Klemm ( void ) +{ + int i; + int k; + float S [512]; + + for ( i=0; i<32; i++ ) { + for ( k=0; k<32; k++ ) { + M [i*32 + k] = (float) cos ( ((2*i+1)*k & 127) * M_PI/64 ); + } + } + +#ifdef FASTER + for ( i = 0; i < 384; i++ ) + S[i] = Ci_opt[i]; + for ( i = 384; i < 392; i++ ) + S[i] = 0; + for ( i = 392; i < 512; i++ ) + S[i] = -Ci_opt[i]; + for ( i = 0; i < 512; i++ ) + Ci_opt[i] = S[i]; + for ( i = 0; i < 128; i++ ) + Ci_opt[i] = S[(i&7) + 120 - (i&120)]; + for ( i = 128; i < 384; i++ ) + Ci_opt[i] = S[i]; + for ( i = 384; i < 512; i++ ) + Ci_opt[i] = S[ 384 + (i&7) + 120 - (i&120)]; +#endif +} + + /* D E F I N E S */ +#define X_MEM 1152 + +/* V A R I A B L E S */ +float X_L [ X_MEM + 480 ]; +float X_R [ X_MEM + 480 ]; + + +/* F U N C T I O N S */ +// vectoring & partial calculation + +static void +Vectoring ( const float* x, float* y ) +{ +#ifdef FASTER + int i = 0; + const float* c1; + const float* c2; + const float* x1; + const float* x2; + +# define EXPR(c,x) (c[0]*x[0] + c[1]*x[64] + c[2]*x[128] + c[3]*x[192] + c[4]*x[256] + c[5]*x[320] + c[6]*x[384] + c[7]*x[448]) + + i++; + *y++ = EXPR ((Ci_opt+128),(x+31)); + + c1 = Ci_opt - 8; + c2 = Ci_opt + 128; + x1 = x + 16; + x2 = x + 31; + do { + x1--, x2--, i++; + c1 += 8, c2 += 8; + *y++ = EXPR (c1,x1) + EXPR (c2,x2); + } while ( i < 16 ); + + i++; + *y++ = EXPR ((Ci_opt+120),(x+0)) + EXPR ((Ci_opt+256),(x+32)); + + c1 = Ci_opt + 384 - 8; + c2 = Ci_opt + 256; + x1 = x + 47; + x2 = x + 32; + + do { + x1++, x2++, i++; + c1 += 8, c2 += 8; + *y++ = EXPR (c1,x1) + EXPR (c2,x2); + } while ( i < 32 ); +#else + int i; + const float* c = Ci_opt; + + for ( i = 0; i < 16; i++, c += 32, x += 4, y += 4 ) { + y[0] = c[ 0] * x[ 0] + c[ 1] * x[ 64] + c[ 2] * x[128] + c[ 3] * x[192] + c[ 4] * x[256] + c[ 5] * x[320] + c[ 6] * x[384] + c[ 7] * x[448]; + y[1] = c[ 8] * x[ 1] + c[ 9] * x[ 65] + c[10] * x[129] + c[11] * x[193] + c[12] * x[257] + c[13] * x[321] + c[14] * x[385] + c[15] * x[449]; + y[2] = c[16] * x[ 2] + c[17] * x[ 66] + c[18] * x[130] + c[19] * x[194] + c[20] * x[258] + c[21] * x[322] + c[22] * x[386] + c[23] * x[450]; + y[3] = c[24] * x[ 3] + c[25] * x[ 67] + c[26] * x[131] + c[27] * x[195] + c[28] * x[259] + c[29] * x[323] + c[30] * x[387] + c[31] * x[451]; + } +#endif +} + +// matrixing with Mi[32][32] = Mi[1024] + +static void +Matrixing ( const int MaxBand, const float* mi, const float* y, float* samples ) +{ + int i; +#ifdef FASTER + for ( i = 0; i <= MaxBand; i++, mi += 32, samples += 72 ) { // 144 = sizeof(SubbandFloatTyp)/sizeof(float) + samples[0] = y[ 0] + mi[ 1] * y[ 1] + mi[ 2] * y[ 2] + mi[ 3] * y[ 3] + + mi[ 4] * y[ 4] + mi[ 5] * y[ 5] + mi[ 6] * y[ 6] + mi[ 7] * y[ 7] + + mi[ 8] * y[ 8] + mi[ 9] * y[ 9] + mi[10] * y[10] + mi[11] * y[11] + + mi[12] * y[12] + mi[13] * y[13] + mi[14] * y[14] + mi[15] * y[15] + + mi[16] * y[16] + mi[17] * y[17] + mi[18] * y[18] + mi[19] * y[19] + + mi[20] * y[20] + mi[21] * y[21] + mi[22] * y[22] + mi[23] * y[23] + + mi[24] * y[24] + mi[25] * y[25] + mi[26] * y[26] + mi[27] * y[27] + + mi[28] * y[28] + mi[29] * y[29] + mi[30] * y[30] + mi[31] * y[31]; + } +#else + for ( i = 0; i <= MaxBand; i++, mi += 32, samples += 72 ) { // 144 = sizeof(SubbandFloatTyp)/sizeof(float) + samples[0] = y[16] + mi[ 1] * (y[15]+y[17]) + + mi[ 2] * (y[14]+y[18]) + mi[ 3] * (y[13]+y[19]) + + mi[ 4] * (y[12]+y[20]) + mi[ 5] * (y[11]+y[21]) + + mi[ 6] * (y[10]+y[22]) + mi[ 7] * (y[ 9]+y[23]) + + mi[ 8] * (y[ 8]+y[24]) + mi[ 9] * (y[ 7]+y[25]) + + mi[10] * (y[ 6]+y[26]) + mi[11] * (y[ 5]+y[27]) + + mi[12] * (y[ 4]+y[28]) + mi[13] * (y[ 3]+y[29]) + + mi[14] * (y[ 2]+y[30]) + mi[15] * (y[ 1]+y[31]) + + mi[16] * (y[ 0]+y[32]) + + mi[31] * (y[47]-y[49]) + mi[30] * (y[46]-y[50]) + + mi[29] * (y[45]-y[51]) + mi[28] * (y[44]-y[52]) + + mi[27] * (y[43]-y[53]) + mi[26] * (y[42]-y[54]) + + mi[25] * (y[41]-y[55]) + mi[24] * (y[40]-y[56]) + + mi[23] * (y[39]-y[57]) + mi[22] * (y[38]-y[58]) + + mi[21] * (y[37]-y[59]) + mi[20] * (y[36]-y[60]) + + mi[19] * (y[35]-y[61]) + mi[18] * (y[34]-y[62]) + + mi[17] * (y[33]-y[63]); + } +#endif +} + +// Analysis-Filterbank +void +Analyse_Filter ( const PCMDataTyp* in, SubbandFloatTyp* out, const int MaxBand ) +{ +#ifdef FASTER + float Y_L [32]; + float Y_R [32]; +#else + float Y_L [64]; + float Y_R [64]; +#endif + float* x; + const float* pcm; + int n; + int i; + + /************************* calculate L-signal ***************************/ + memcpy ( X_L + X_MEM, X_L, 480*sizeof(*X_L) ); + x = X_L + X_MEM; + pcm = in->L + 479; // 479 = CENTER + 31 + for ( n = 0; n < 36; n++, pcm += 64 ) { + x -= 32; // updating vector x +#ifdef FASTER + for ( i = 0; i < 16; i++ ) + x[i] = *pcm--; + for ( i = 31; i >= 16; i-- ) + x[i] = *pcm--; +#else + for ( i = 0; i < 32; i++ ) + x[i] = *pcm--; +#endif + Vectoring ( x, Y_L ); // vectoring & partial calculation + Matrixing ( MaxBand, M, Y_L, &out[0].L[n] ); // matrixing + } + + /************************* calculate R-signal ***************************/ + memcpy ( X_R + X_MEM, X_R, 480*sizeof(*X_R) ); + x = X_R + X_MEM; + pcm = in->R + 479; // 479 = CENTER + 31 + for ( n = 0; n < 36; n++, pcm += 64 ) { + x -= 32; // updating vector x +#ifdef FASTER + for ( i = 0; i < 16; i++ ) + x[i] = *pcm--; + for ( i = 31; i >= 16; i-- ) + x[i] = *pcm--; +#else + for ( i = 0; i < 32; i++ ) + x[i] = *pcm--; +#endif + Vectoring ( x, Y_R ); // vectoring & partial calculation + Matrixing ( MaxBand, M, Y_R, &out[0].R[n] ); // matrixing + } +} + +void +Analyse_Init ( float Left, float Right, SubbandFloatTyp* out, const int MaxBand ) +{ +#ifdef FASTER + float Y_L [32]; + float Y_R [32]; +#else + float Y_L [64]; + float Y_R [64]; +#endif + float* x; + int n; + int i; + + /************************* calculate L-signal ***************************/ + memcpy ( X_L + X_MEM, X_L, 480*sizeof(*X_L) ); + x = X_L + X_MEM; + + for ( n = 0; n < 36; n++ ) { + x -= 32; // updating vector x +#ifdef FASTER + for ( i = 0; i < 16; i++ ) + x[i] = Left; + for ( i = 31; i >= 16; i-- ) + x[i] = Left; +#else + for ( i = 0; i < 32; i++ ) + x[i] = Left; +#endif + Vectoring ( x, Y_L ); // vectoring & partial calculation + Matrixing ( MaxBand, M, Y_L, &out[0].L[n] ); // matrixing + } + + /************************* calculate R-signal ***************************/ + memcpy ( X_R + X_MEM, X_R, 480*sizeof(*X_R) ); + x = X_R + X_MEM; + for ( n = 0; n < 36; n++ ) { + x -= 32; // updating vector x +#ifdef FASTER + for ( i = 0; i < 16; i++ ) + x[i] = Right; + for ( i = 31; i >= 16; i-- ) + x[i] = Right; +#else + for ( i = 0; i < 32; i++ ) + x[i] = Right; +#endif + Vectoring ( x, Y_R ); // vectoring & partial calculation + Matrixing ( MaxBand, M, Y_R, &out[0].R[n] ); // matrixing + } +} + +/* end of analy_filter.c */ diff --git a/third_party/musepack/libmpcenc/bitstream.c b/third_party/musepack/libmpcenc/bitstream.c new file mode 100755 index 0000000..0650ee2 --- /dev/null +++ b/third_party/musepack/libmpcenc/bitstream.c @@ -0,0 +1,271 @@ +/* + * Musepack audio compression + * Copyright (c) 2005-2009, The Musepack Development Team + * 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 + */ + +#ifdef _WIN32 +#include +#define sleep(t) Sleep((t) * 1000) +#else +#include +#endif + +#include "libmpcenc.h" +#include "stdio.h" + +unsigned long mpc_crc32(unsigned char *buf, int len); + +#define MAX_ENUM 32 + +static const mpc_uint32_t Cnk[MAX_ENUM / 2][MAX_ENUM] = +{ + {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} +}; + +static const mpc_uint8_t Cnk_len[MAX_ENUM / 2][MAX_ENUM] = +{ + {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} + +}; + +static const mpc_uint32_t Cnk_lost[MAX_ENUM / 2][MAX_ENUM] = +{ + {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] = +{ 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] = +{ 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}; + +void emptyBits(mpc_encoder_t * e) +{ + while( e->bitsCount >= 8 ){ + e->bitsCount -= 8; + e->buffer[e->pos] = (mpc_uint8_t) (e->bitsBuff >> e->bitsCount); + e->pos++; + } +} + +unsigned int encodeSize(mpc_uint64_t size, char * buff, mpc_bool_t addCodeSize) +{ + unsigned int i = 1; + int j; + + if (addCodeSize) { + while ((1ull << (7 * i)) - i <= size) i++; + size += i; + } else + while ((1ull << (7 * i)) <= size) i++; + + for( j = i - 1; j >= 0; j--){ + buff[j] = (char) (size | 0x80); + size >>= 7; + } + buff[i - 1] &= 0x7F; + + return i; +} + +static void encodeGolomb(mpc_encoder_t * e, mpc_uint32_t nb, mpc_uint_t k) +{ + unsigned int l = (nb >> k) + 1; + nb &= (1 << k) - 1; + + while( l > 31 ){ + writeBits(e, 0, 31); + l -= 31; + } + writeBits(e, 1, l); + writeBits(e, nb, k); +} + +void encodeEnum(mpc_encoder_t * e, const mpc_uint32_t bits, const mpc_uint_t N) +{ + mpc_uint32_t code = 0; + const mpc_uint32_t * C = Cnk[0]; + unsigned int n = 0, k = 0; + + for( ; n < N; n++){ + if ((bits >> n) & 1) { + code += C[n]; + C += MAX_ENUM; + k++; + } + } + + if (k == 0) return; + + if (code < Cnk_lost[k-1][n-1]) + writeBits(e, code, Cnk_len[k-1][n-1] - 1); + else + writeBits(e, code + Cnk_lost[k-1][n-1], Cnk_len[k-1][n-1]); +} + +void encodeLog(mpc_encoder_t * e, mpc_uint32_t value, mpc_uint32_t max) +{ + if (value < log2_lost[max - 1]) + writeBits(e, value, log2[max - 1] - 1); + else + writeBits(e, value + log2_lost[max - 1], log2[max - 1]); +} + +void writeMagic(mpc_encoder_t * e) +{ + fwrite("MPCK", sizeof(char), 4, e->outputFile); + e->outputBits += 32; + e->framesInBlock = 0; +} + +mpc_uint32_t writeBlock ( mpc_encoder_t * e, const char * key, const mpc_bool_t addCRC, mpc_uint32_t min_size) +{ + FILE * fp = e->outputFile; + mpc_uint32_t written = 0; + mpc_uint8_t * datas = e->buffer; + char blockSize[10]; + mpc_uint32_t len; + + writeBits(e, 0, (8 - e->bitsCount) % 8); + emptyBits(e); + + // write block header (key / length) + len = e->pos + (addCRC > 0) * 4; + if (min_size <= len) + min_size = len; + else { + mpc_uint32_t pad = min_size - len, i; + for(i = 0; i < pad; i++) + writeBits(e, 0, 8); + emptyBits(e); + } + len = encodeSize(min_size + 2, blockSize, MPC_TRUE); + fwrite(key, sizeof(char), 2, fp); + fwrite(blockSize, sizeof(char), len, fp); + e->outputBits += (len + 2) * 8; + + if (addCRC) { + char tmp[4]; + unsigned long CRC32 = mpc_crc32((unsigned char *) e->buffer, e->pos); + tmp[0] = (char) (CRC32 >> 24); + tmp[1] = (char) (CRC32 >> 16); + tmp[2] = (char) (CRC32 >> 8); + tmp[3] = (char) CRC32; + fwrite(tmp, sizeof(char), 4, fp); + e->outputBits += 32; + } + + // write datas + while ( e->pos != 0 ) { + written = fwrite ( datas, sizeof(*e->buffer), e->pos, fp ); + if ( written == 0 ) { + fprintf(stderr, "\b\n WARNING: Disk full?, retry after 10 sec ...\a"); + sleep (10); + } + if ( written > 0 ) { + datas += written; + e->pos -= written; + } + } + e->framesInBlock = 0; + + return min_size; +} + +void writeSeekTable (mpc_encoder_t * e) +{ + mpc_uint32_t i, len; + mpc_uint32_t * table = e->seek_table; + mpc_uint8_t tmp[10]; + + // write the position to header + i = ftell(e->outputFile); // get the seek table position + len = encodeSize(i - e->seek_ptr, (char*)tmp, MPC_FALSE); + fseek(e->outputFile, e->seek_ptr + 3, SEEK_SET); + fwrite(tmp, sizeof(mpc_uint8_t), len, e->outputFile); + fseek(e->outputFile, i, SEEK_SET); + + // write the seek table datas + len = encodeSize(e->seek_pos, (char*)tmp, MPC_FALSE); + for( i = 0; i < len; i++) + writeBits ( e, tmp[i], 8 ); + writeBits ( e, e->seek_pwr, 4 ); + + len = encodeSize(table[0] - e->seek_ref, (char*)tmp, MPC_FALSE); + for( i = 0; i < len; i++) + writeBits ( e, tmp[i], 8 ); + if (e->seek_pos > 1) { + len = encodeSize(table[1] - e->seek_ref, (char*)tmp, MPC_FALSE); + for( i = 0; i < len; i++) + writeBits ( e, tmp[i], 8 ); + } + + for( i = 2; i < e->seek_pos; i++){ + int code = (table[i] - 2 * table[i-1] + table[i-2]) << 1; + if (code < 0) + code = -code | 1; + encodeGolomb(e, code, 12); + } +} + +/* end of bitstream.c */ diff --git a/third_party/musepack/libmpcenc/encode_sv7.c b/third_party/musepack/libmpcenc/encode_sv7.c new file mode 100755 index 0000000..68de5ae --- /dev/null +++ b/third_party/musepack/libmpcenc/encode_sv7.c @@ -0,0 +1,492 @@ +/* + * Musepack audio compression + * Copyright (c) 2005-2009, The Musepack Development Team + * 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 + */ + +#include +#include + +#include "libmpcenc.h" +#include + +void Klemm ( void ); +void Init_Skalenfaktoren ( void ); + +// huffsv7.c +extern Huffman_t const HuffBands [33]; +extern Huffman_t const HuffRes [2][17]; +extern Huffman_t const HuffSCFI_1 [4]; // contains tables for SV7-scalefactor select +extern Huffman_t const HuffSCFI_2 [16]; // contains tables for SV7-scalefactor select +extern Huffman_t const HuffDSCF_1 [64]; // contains tables for SV7-scalefactor coding +extern Huffman_t const HuffDSCF_2 [65]; // contains tables for SV7-scalefactor coding +extern Huffman_t const * const HuffQ [2][8]; // points to tables for SV7-sample coding +extern Huffman_t const HuffQ9up [256]; + +/* + * SV1: DATE 13.12.1998 + * SV2: DATE 12.06.1999 + * SV3: DATE 19.10.1999 + * SV4: DATE 20.10.1999 + * SV5: DATE 18.06.2000 + * SV6: DATE 10.08.2000 + * SV7: DATE 23.08.2000 + * SV7.f: DATE 20.07.2002 + */ + +// initialize SV8 +void +mpc_encoder_init ( mpc_encoder_t * e, + mpc_uint64_t SamplesInWAVE, + unsigned int FramesBlockPwr, + unsigned int SeekDistance ) +{ + Init_Skalenfaktoren (); + Klemm (); + + memset(e, 0, sizeof(*e)); + + if (SeekDistance > 15) + SeekDistance = 1; + if (FramesBlockPwr > 14) + FramesBlockPwr = 6; + + e->seek_pwr = SeekDistance; + e->frames_per_block_pwr = FramesBlockPwr; + + if (SamplesInWAVE == 0) + e->seek_table = malloc((1 << 16) * sizeof(mpc_uint32_t)); + else + e->seek_table = malloc((size_t)(2 + SamplesInWAVE / (MPC_FRAME_LENGTH << (e->seek_pwr + e->frames_per_block_pwr))) * sizeof(mpc_uint32_t)); + + e->buffer = malloc(MAX_FRAME_SIZE * (1 << e->frames_per_block_pwr) * sizeof(mpc_uint8_t)); +} + +void +mpc_encoder_exit ( mpc_encoder_t * e ) +{ + free(e->seek_table); + free(e->buffer); +} + +// writes replay gain info +void writeGainInfo ( mpc_encoder_t * e, + unsigned short t_gain, + unsigned short t_peak, + unsigned short a_gain, + unsigned short a_peak) +{ + writeBits ( e, 1, 8 ); // version + writeBits ( e, t_gain, 16 ); // Title gain + writeBits ( e, t_peak, 16 ); // Title peak + writeBits ( e, a_gain, 16 ); // Album gain + writeBits ( e, a_peak, 16 ); // Album peak +} + +// writes SV8-header +void +writeStreamInfo ( mpc_encoder_t*e, + const unsigned int MaxBand, + const unsigned int MS_on, + const unsigned int SamplesCount, + const unsigned int SamplesSkip, + const unsigned int SampleFreq, + const unsigned int ChannelCount) +{ + unsigned char tmp[10]; + int i, len; + + writeBits ( e, 8, 8 ); // StreamVersion + + len = encodeSize(SamplesCount, (char *)tmp, MPC_FALSE); + for( i = 0; i < len; i++) // nb of samples + writeBits ( e, tmp[i], 8 ); + len = encodeSize(SamplesSkip, (char *)tmp, MPC_FALSE); + for( i = 0; i < len; i++) // nb of samples to skip at beginning + writeBits ( e, tmp[i], 8 ); + + switch ( SampleFreq ) { + case 44100: writeBits ( e, 0, 3 ); break; + case 48000: writeBits ( e, 1, 3 ); break; + case 37800: writeBits ( e, 2, 3 ); break; + case 32000: writeBits ( e, 3, 3 ); break; + default : fprintf(stderr, "Internal error\n");// FIXME : stderr_printf ( "Internal error\n"); + exit (1); + } + + writeBits ( e, MaxBand - 1 , 5 ); // Bandwidth + writeBits ( e, ChannelCount - 1 , 4 ); // Channels + writeBits ( e, MS_on , 1 ); // MS-Coding Flag + writeBits ( e, e->frames_per_block_pwr >> 1, 3 ); // frames per block (log4 unit) +} + +// writes encoder signature +void writeEncoderInfo ( mpc_encoder_t * e, + const float profile, + const int PNS_on, + const int version_major, + const int version_minor, + const int version_build ) +{ + writeBits ( e, (mpc_uint32_t)(profile * 8 + .5), 7 ); + writeBits ( e, PNS_on, 1 ); + writeBits ( e, version_major, 8 ); + writeBits ( e, version_minor, 8 ); + writeBits ( e, version_build, 8 ); +} + +// formatting and writing SV8-bitstream for one frame +void +writeBitstream_SV8 ( mpc_encoder_t* e, int MaxBand) +{ + int n; + const Huffman_t * Table, * Tables[2]; + mpc_int32_t * Res_L = e->Res_L; + mpc_int32_t * Res_R = e->Res_R; + mpc_bool_t * DSCF_Flag_L = e->DSCF_Flag_L; + mpc_bool_t * DSCF_Flag_R = e->DSCF_Flag_R; + mpc_int32_t * SCF_Last_L = e->SCF_Last_L; + mpc_int32_t * SCF_Last_R = e->SCF_Last_R; + + for( n = MaxBand; n >= 0; n--) + if (Res_L[n] != 0 || Res_R[n] != 0) break; + + n++; + if (e->framesInBlock == 0) { + encodeLog(e, n, MaxBand + 1); + MaxBand = e->MaxBand = n; + } else { + n = n - e->MaxBand; + MaxBand = e->MaxBand = n + e->MaxBand; + if (n < 0) n += 33; + writeBits(e, HuffBands[n].Code, HuffBands[n].Length); + } + + /************************************ Resolution *********************************/ + + if (MaxBand) { + { + int tmp = Res_L[MaxBand - 1]; + if (tmp < 0) tmp += 17; + writeBits(e, HuffRes[0][tmp].Code, HuffRes[0][tmp].Length); + tmp = Res_R[MaxBand - 1]; + if (tmp < 0) tmp += 17; + writeBits(e, HuffRes[0][tmp].Code, HuffRes[0][tmp].Length); + } + for ( n = MaxBand - 2; n >= 0; n--) { + int tmp = Res_L[n] - Res_L[n + 1]; + if (tmp < 0) tmp += 17; + writeBits(e, HuffRes[Res_L[n + 1] > 2][tmp].Code, HuffRes[Res_L[n + 1] > 2][tmp].Length); + + tmp = Res_R[n] - Res_R[n + 1]; + if (tmp < 0) tmp += 17; + writeBits(e, HuffRes[Res_R[n + 1] > 2][tmp].Code, HuffRes[Res_R[n + 1] > 2][tmp].Length); + } + + if (e->MS_Channelmode > 0) { + mpc_uint32_t tmp = 0; + int cnt = 0, tot = 0; + mpc_bool_t * MS_Flag = e->MS_Flag; + for( n = 0; n < MaxBand; n++) { + if ( Res_L[n] != 0 || Res_R[n] != 0 ) { + tmp = (tmp << 1) | MS_Flag[n]; + cnt += MS_Flag[n]; + tot++; + } + } + encodeLog(e, cnt, tot); + if (cnt * 2 > tot) tmp = ~tmp; + encodeEnum(e, tmp, tot); + } + } + + /************************************ SCF encoding type ***********************************/ + + if (e->framesInBlock == 0){ + for( n = 0; n < 32; n++) + DSCF_Flag_L[n] = DSCF_Flag_R[n] = 1; // new block -> force key frame + } + + Tables[0] = HuffSCFI_1; + Tables[1] = HuffSCFI_2; + for ( n = 0; n < MaxBand; n++ ) { + int tmp = 0, cnt = -1; + if (Res_L[n]) { + tmp = (e->SCF_Index_L[n][1] == e->SCF_Index_L[n][0]) * 2 + (e->SCF_Index_L[n][2] == e->SCF_Index_L[n][1]); + cnt++; + } + if (Res_R[n]) { + tmp = (tmp << 2) | ((e->SCF_Index_R[n][1] == e->SCF_Index_R[n][0]) * 2 + (e->SCF_Index_R[n][2] == e->SCF_Index_R[n][1])); + cnt++; + } + if (cnt >= 0) + writeBits(e, Tables[cnt][tmp].Code, Tables[cnt][tmp].Length); + } + + /************************************* SCF **********************************/ + + for ( n = 0; n < MaxBand; n++ ) { + if ( Res_L[n] ) { + int m; + mpc_int32_t * SCFI_L_n = e->SCF_Index_L[n]; + if (DSCF_Flag_L[n] == 1) { + writeBits(e, SCFI_L_n[0] + 6, 7); + DSCF_Flag_L[n] = 0; + } else { + unsigned int tmp = (SCFI_L_n[0] - SCF_Last_L[n] + 31) & 127; + if (tmp < 64) + writeBits(e, HuffDSCF_2[tmp].Code, HuffDSCF_2[tmp].Length); + else { + writeBits(e, HuffDSCF_2[64].Code, HuffDSCF_2[64].Length); + writeBits(e, tmp - 64, 6); + } + } + for( m = 0; m < 2; m++){ + if (SCFI_L_n[m+1] != SCFI_L_n[m]) { + unsigned int tmp = (SCFI_L_n[m+1] - SCFI_L_n[m] + 31) & 127; + if (tmp < 64) + writeBits(e, HuffDSCF_1[tmp].Code, HuffDSCF_1[tmp].Length); + else { + writeBits(e, HuffDSCF_1[31].Code, HuffDSCF_1[31].Length); + writeBits(e, tmp - 64, 6); + } + } + } + SCF_Last_L[n] = SCFI_L_n[2]; + } + if ( Res_R[n] ) { + int m; + mpc_int32_t * SCFI_R_n = e->SCF_Index_R[n]; + if (DSCF_Flag_R[n] == 1) { + writeBits(e, SCFI_R_n[0] + 6, 7); + DSCF_Flag_R[n] = 0; + } else { + unsigned int tmp = (SCFI_R_n[0] - SCF_Last_R[n] + 31) & 127; + if (tmp < 64) + writeBits(e, HuffDSCF_2[tmp].Code, HuffDSCF_2[tmp].Length); + else { + writeBits(e, HuffDSCF_2[64].Code, HuffDSCF_2[64].Length); + writeBits(e, tmp - 64, 6); + } + } + for( m = 0; m < 2; m++){ + if (SCFI_R_n[m+1] != SCFI_R_n[m]) { + unsigned int tmp = (SCFI_R_n[m+1] - SCFI_R_n[m] + 31) & 127; + if (tmp < 64) + writeBits(e, HuffDSCF_1[tmp].Code, HuffDSCF_1[tmp].Length); + else { + writeBits(e, HuffDSCF_1[31].Code, HuffDSCF_1[31].Length); + writeBits(e, tmp - 64, 6); + } + } + } + SCF_Last_R[n] = SCFI_R_n[2]; + } + } + + /*********************************** Samples *********************************/ + for ( n = 0; n < MaxBand; n++ ) { + int Res = Res_L[n]; + const mpc_int16_t * q = e->Q[n].L; + static const unsigned int thres[] = {0, 0, 3, 7, 9, 1, 3, 4, 8}; + static const int HuffQ2_var[5*5*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, 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}; + + do { + int k = 0, idx = 1, cnt = 0, sng; + switch ( Res ) { + case -1: + case 0: + break; + case 1: + Table = HuffQ [0][0]; + for( ; k < 36; ){ + int kmax = k + 18; + cnt = 0, sng = 0; + for ( ; k < kmax; k++) { + idx <<= 1; + if (q[k] != 1) { + cnt++; + idx |= 1; + sng = (sng << 1) | (q[k] >> 1); + } + } + writeBits(e, Table[cnt].Code, Table[cnt].Length); + if (cnt > 0) { + if (cnt > 9) idx = ~idx; + encodeEnum(e, idx, 18); + writeBits(e, sng, cnt); + } + } + break; + case 2: + Tables[0] = HuffQ [0][1]; + Tables[1] = HuffQ [1][1]; + idx = 2 * thres[Res]; + for ( ; k < 36; k += 3) { + int tmp = q[k] + 5*q[k+1] + 25*q[k+2]; + writeBits ( e, Tables[idx > thres[Res]][tmp].Code, + Tables[idx > thres[Res]][tmp].Length ); + idx = (idx >> 1) + HuffQ2_var[tmp]; + } + break; + case 3: + case 4: + Table = HuffQ [0][Res - 1]; + for ( ; k < 36; k += 2 ) { + int tmp = q[k] + thres[Res]*q[k+1]; + writeBits ( e, Table[tmp].Code, Table[tmp].Length ); + } + break; + case 5: + case 6: + case 7: + case 8: + Tables[0] = HuffQ [0][Res - 1]; + Tables[1] = HuffQ [1][Res - 1]; + idx = 2 * thres[Res]; + for ( ; k < 36; k++ ) { + int tmp = q[k] - (1 << (Res - 2)) + 1; + writeBits ( e, Tables[idx > thres[Res]][q[k]].Code, + Tables[idx > thres[Res]][q[k]].Length ); + if (tmp < 0) tmp = -tmp; + idx = (idx >> 1) + tmp; + } + break; + default: + for ( ; k < 36; k++ ) { + writeBits ( e, HuffQ9up[q[k] >> (Res - 9)].Code, + HuffQ9up[q[k] >> (Res - 9)].Length ); + if (Res != 9) + writeBits ( e, q[k] & ((1 << (Res - 9)) - 1), Res - 9); + } + break; + } + + Res = Res_R[n]; + } while (q == e->Q[n].L && (q = e->Q[n].R)); + } + + e->framesInBlock++; + if (e->framesInBlock == (1 << e->frames_per_block_pwr)) { + if ((e->block_cnt & ((1 << e->seek_pwr) - 1)) == 0) { + e->seek_table[e->seek_pos] = ftell(e->outputFile); + e->seek_pos++; + } + e->block_cnt++; + writeBlock(e, "AP", MPC_FALSE, 0); + } +} + +#if 0 + +typedef struct { + int Symbol; + unsigned int Count; + unsigned int Code; + unsigned int Bits; +} huff_sym_t; + +void _Huffman_MakeTree( huff_sym_t *sym, unsigned int num_symbols); +void _Huffman_PrintCodes(huff_sym_t * sym, unsigned int num_symbols, int print_type, int offset); + +void print_histo(void) +{ + int i, j; + huff_sym_t sym[HISTO_NB][HISTO_LEN]; + unsigned int dist[HISTO_NB]; + unsigned int size[HISTO_NB]; + unsigned int cnt[HISTO_NB]; + unsigned int total_cnt, total_size, full_count = 0, full_size = 0; + double optim_size, full_optim = 0; + + return; + + memset(dist, 1, sizeof dist); + memset(sym, 0, sizeof(huff_sym_t) * HISTO_LEN * HISTO_NB); + + for(j = 0 ; j < HISTO_NB ; j++) { + for(i = 0 ; i < HISTO_LEN; i++) { + sym[j][i].Symbol = i; + sym[j][i].Count = histo[j][i]; + if (sym[j][i].Count == 0) + sym[j][i].Count = 1; + } + _Huffman_MakeTree(sym[j], HISTO_LEN); + _Huffman_PrintCodes(sym[j], HISTO_LEN, 3, 0); + _Huffman_PrintCodes(sym[j], HISTO_LEN, 0, 0); + _Huffman_PrintCodes(sym[j], HISTO_LEN, 1, 0); + total_cnt = 0; + total_size = 0; + optim_size = 0; + for( i = 0; i < HISTO_LEN; i++) { + total_cnt += sym[j][i].Count; + total_size += sym[j][i].Count * sym[j][i].Bits; + if (sym[j][i].Count != 0) + optim_size += sym[j][i].Count * __builtin_log2(sym[j][i].Count); + } + full_count += total_cnt; + full_size += total_size; + optim_size = total_cnt * __builtin_log2(total_cnt) - optim_size; + full_optim += optim_size; + size[j] = total_size; + cnt[j] = total_cnt; + printf("%u count : %u huff : %f bps ", j, total_cnt, (float)total_size / total_cnt); + printf("opt : %f bps ", (float)optim_size / total_cnt); + printf("loss : %f bps (%f %%)\n", (float)(total_size - optim_size) / total_cnt, (float)(total_size - optim_size) * 100 / optim_size); + for( i = 0; i < HISTO_LEN; i++){ + printf("%u ", sym[j][i].Bits); + } + + printf("\n\n"); + } + printf("cnt : %u size %f optim %f\n", full_count, (float)full_size / full_count, (float)full_optim / full_count); + printf("loss : %f bps (%f %%)\n", (float)(full_size - full_optim) / full_count, (float)(full_size - full_optim) * 100 / full_optim); + + + printf("\n"); +} + +void +Dump ( const unsigned int* q, const int Res ) +{ + switch ( Res ) { + case 1: + for ( k = 0; k < 36; k++, q++ ) + printf ("%2d%c", *q-1, k==35?'\n':' '); + break; + case 2: + for ( k = 0; k < 36; k++, q++ ) + printf ("%2d%c", *q-2, k==35?'\n':' '); + break; + case 3: case 4: case 5: case 6: case 7: + if ( Res == 5 ) + for ( k = 0; k < 36; k++, q++ ) + printf ("%2d%c", *q-7, k==35?'\n':' '); + break; + case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: + printf ("%2u: ", Res-1 ); + for ( k = 0; k < 36; k++, q++ ) { + printf ("%6d", *q - (1 << (Res-2)) ); + } + printf ("\n"); + break; + } +} +#endif + +/* end of encode_sv7.c */ diff --git a/third_party/musepack/libmpcenc/huffsv7.c b/third_party/musepack/libmpcenc/huffsv7.c new file mode 100755 index 0000000..dd13f8e --- /dev/null +++ b/third_party/musepack/libmpcenc/huffsv7.c @@ -0,0 +1,112 @@ +/* + * Musepack audio compression + * Copyright (c) 2005-2009, The Musepack Development Team + * 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 + */ + +#include "libmpcenc.h" + +const Huffman_t HuffBands [33] = { + {1, 1}, {1, 3}, {2, 5}, {2, 6}, {3, 7}, {3, 8}, {4, 8}, {4, 9}, {5, 10}, {6, 11}, {1, 12}, {2, 12}, {3, 12}, {0, 13}, {4, 12}, {5, 12}, {6, 12}, {7, 12}, {8, 12}, {1, 13}, {9, 12}, {10, 12}, {11, 12}, {7, 11}, {8, 11}, {9, 11}, {6, 10}, {7, 10}, {5, 9}, {5, 8}, {3, 6}, {3, 5}, {1, 2} +}; + +const Huffman_t HuffRes [2] [17] = { + { + {1, 1}, {1, 2}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 9}, {1, 10}, {1, 11}, {1, 12}, {1, 13}, {1, 14}, {1, 15}, {0, 16}, {1, 16}, {1, 8}, {1, 3} + }, { + {1, 2}, {2, 2}, {1, 3}, {1, 5}, {1, 7}, {1, 8}, {1, 10}, {1, 12}, {0, 14}, {1, 14}, {2, 14}, {3, 14}, {1, 11}, {1, 9}, {1, 6}, {1, 4}, {3, 2} + } +}; + +const Huffman_t HuffSCFI_1 [4] = { + {0, 3}, {1, 3}, {1, 1}, {1, 2} +}; + +const Huffman_t HuffSCFI_2 [16] = { + {1, 6}, {0, 7}, {2, 6}, {3, 6}, {1, 7}, {3, 5}, {4, 5}, {5, 5}, {4, 6}, {6, 5}, {2, 2}, {2, 3}, {5, 6}, {7, 5}, {3, 3}, {3, 2} +}; + +const Huffman_t HuffDSCF_1 [64] = { + {3, 12}, {4, 12}, {5, 12}, {4, 11}, {5, 11}, {6, 11}, {5, 10}, {6, 10}, {7, 10}, {8, 10}, {9, 10}, {7, 9}, {8, 9}, {9, 9}, {10, 9}, {7, 8}, {8, 8}, {9, 8}, {10, 8}, {7, 7}, {8, 7}, {9, 7}, {10, 7}, {6, 6}, {7, 6}, {5, 5}, {4, 4}, {5, 4}, {6, 5}, {6, 4}, {7, 4}, {10, 10}, {8, 4}, {5, 3}, {6, 3}, {7, 3}, {9, 4}, {7, 5}, {8, 6}, {9, 6}, {11, 7}, {11, 8}, {12, 8}, {13, 8}, {11, 9}, {12, 9}, {13, 9}, {11, 10}, {12, 10}, {13, 10}, {7, 11}, {8, 11}, {9, 11}, {6, 12}, {7, 12}, {3, 13}, {4, 13}, {5, 13}, {0, 14}, {1, 14}, {2, 14}, {3, 14}, {4, 14}, {5, 14} +}; + +const Huffman_t HuffDSCF_2 [65] = { + {0, 15}, {3, 14}, {4, 14}, {4, 13}, {5, 13}, {6, 13}, {5, 12}, {6, 12}, {7, 12}, {8, 12}, {7, 11}, {8, 11}, {9, 11}, {10, 11}, {7, 10}, {8, 10}, {9, 10}, {10, 10}, {7, 9}, {8, 9}, {9, 9}, {6, 8}, {7, 8}, {5, 7}, {6, 7}, {4, 6}, {3, 5}, {3, 4}, {4, 4}, {3, 3}, {4, 3}, {5, 3}, {6, 3}, {7, 3}, {5, 4}, {4, 5}, {5, 5}, {5, 6}, {7, 7}, {8, 8}, {9, 8}, {10, 9}, {11, 9}, {11, 10}, {12, 10}, {13, 10}, {11, 11}, {12, 11}, {13, 11}, {9, 12}, {10, 12}, {11, 12}, {12, 12}, {7, 13}, {8, 13}, {9, 13}, {5, 14}, {6, 14}, {7, 14}, {1, 15}, {2, 15}, {3, 15}, {4, 15}, {5, 15}, {13, 12} +}; + +static const Huffman_t HuffQ1 [19] = { + {1, 6}, {1, 4}, {2, 4}, {3, 3}, {4, 3}, {5, 3}, {6, 3}, {7, 3}, {3, 4}, {4, 4}, {5, 4}, {1, 5}, {1, 7}, {1, 8}, {1, 9}, {1, 10}, {1, 11}, {0, 12}, {1, 12} +}; + +static const Huffman_t HuffQ2 [2] [5*5*5] = { + { + {2, 12}, {3, 11}, {15, 10}, {4, 11}, {0, 13}, {5, 11}, {12, 9}, {18, 8}, {13, 9}, {6, 11}, {7, 11}, {19, 8}, {21, 7}, {20, 8}, {8, 11}, {9, 11}, {14, 9}, {21, 8}, {15, 9}, {10, 11}, {3, 12}, {11, 11}, {16, 10}, {12, 11}, {1, 13}, {13, 11}, {16, 9}, {22, 8}, {17, 9}, {14, 11}, {18, 9}, {15, 6}, {16, 6}, {22, 7}, {19, 9}, {23, 8}, {17, 6}, {8, 4}, {18, 6}, {24, 8}, {20, 9}, {19, 6}, {20, 6}, {23, 7}, {21, 9}, {15, 11}, {22, 9}, {25, 8}, {23, 9}, {16, 11}, {17, 10}, {26, 8}, {24, 7}, {27, 8}, {18, 10}, {28, 8}, {21, 6}, {9, 4}, {22, 6}, {29, 8}, {25, 7}, {10, 4}, {7, 3}, {11, 4}, {26, 7}, {30, 8}, {23, 6}, {12, 4}, {24, 6}, {31, 8}, {19, 10}, {32, 8}, {27, 7}, {33, 8}, {20, 10}, {17, 11}, {24, 9}, {34, 8}, {25, 9}, {18, 11}, {26, 9}, {25, 6}, {26, 6}, {27, 6}, {27, 9}, {35, 8}, {28, 6}, {13, 4}, {29, 6}, {36, 8}, {28, 9}, {28, 7}, {30, 6}, {31, 6}, {29, 9}, {19, 11}, {30, 9}, {37, 8}, {31, 9}, {20, 11}, {2, 13}, {21, 11}, {21, 10}, {22, 11}, {4, 12}, {23, 11}, {32, 9}, {38, 8}, {33, 9}, {24, 11}, {22, 10}, {39, 8}, {29, 7}, {40, 8}, {25, 11}, {26, 11}, {34, 9}, {41, 8}, {35, 9}, {27, 11}, {3, 13}, {28, 11}, {23, 10}, {29, 11}, {5, 12} + }, { + {2, 11}, {3, 10}, {15, 9}, {4, 10}, {0, 12}, {5, 10}, {12, 8}, {13, 8}, {14, 8}, {6, 10}, {7, 10}, {15, 8}, {30, 7}, {16, 8}, {16, 9}, {8, 10}, {17, 8}, {18, 8}, {19, 8}, {9, 10}, {3, 11}, {10, 10}, {17, 9}, {11, 10}, {1, 12}, {12, 10}, {20, 8}, {21, 8}, {22, 8}, {13, 10}, {23, 8}, {18, 6}, {14, 5}, {19, 6}, {24, 8}, {25, 8}, {20, 6}, {15, 5}, {16, 5}, {26, 8}, {27, 8}, {21, 6}, {17, 5}, {22, 6}, {28, 8}, {14, 10}, {29, 8}, {30, 8}, {31, 8}, {15, 10}, {18, 9}, {32, 8}, {31, 7}, {33, 8}, {19, 9}, {34, 8}, {18, 5}, {19, 5}, {20, 5}, {35, 8}, {32, 7}, {21, 5}, {15, 4}, {22, 5}, {33, 7}, {36, 8}, {23, 5}, {24, 5}, {25, 5}, {37, 8}, {20, 9}, {38, 8}, {34, 7}, {39, 8}, {21, 9}, {16, 10}, {40, 8}, {41, 8}, {42, 8}, {17, 10}, {43, 8}, {23, 6}, {26, 5}, {24, 6}, {44, 8}, {45, 8}, {27, 5}, {28, 5}, {25, 6}, {46, 8}, {47, 8}, {26, 6}, {29, 5}, {27, 6}, {48, 8}, {18, 10}, {49, 8}, {50, 8}, {51, 8}, {19, 10}, {2, 12}, {20, 10}, {21, 10}, {22, 10}, {4, 11}, {23, 10}, {52, 8}, {53, 8}, {54, 8}, {24, 10}, {22, 9}, {55, 8}, {35, 7}, {56, 8}, {25, 10}, {26, 10}, {57, 8}, {58, 8}, {59, 8}, {27, 10}, {3, 12}, {28, 10}, {23, 9}, {29, 10}, {5, 11} + } +}; + +static const Huffman_t HuffQ3 [49] = { + {0, 9}, {2, 8}, {5, 7}, {6, 7}, {7, 7}, {3, 8}, {1, 9}, {4, 8}, {9, 6}, {10, 6}, {10, 5}, {11, 6}, {8, 7}, {5, 8}, {9, 7}, {12, 6}, {8, 4}, {9, 4}, {11, 5}, {13, 6}, {10, 7}, {11, 7}, {12, 5}, {10, 4}, {7, 3}, {11, 4}, {13, 5}, {12, 7}, {13, 7}, {14, 6}, {14, 5}, {12, 4}, {13, 4}, {15, 6}, {14, 7}, {6, 8}, {16, 6}, {17, 6}, {15, 5}, {18, 6}, {19, 6}, {7, 8}, {2, 9}, {8, 8}, {15, 7}, {16, 7}, {17, 7}, {9, 8}, {3, 9} +}; + +static const Huffman_t HuffQ4 [81] = { + {0, 10}, {2, 9}, {5, 8}, {12, 7}, {13, 7}, {6, 8}, {7, 8}, {3, 9}, {1, 10}, {4, 9}, {8, 8}, {14, 7}, {13, 6}, {14, 6}, {15, 6}, {15, 7}, {9, 8}, {5, 9}, {10, 8}, {16, 7}, {16, 6}, {17, 6}, {18, 5}, {18, 6}, {19, 6}, {17, 7}, {11, 8}, {12, 8}, {20, 6}, {21, 6}, {19, 5}, {20, 5}, {21, 5}, {22, 6}, {23, 6}, {13, 8}, {18, 7}, {24, 6}, {22, 5}, {23, 5}, {15, 4}, {24, 5}, {25, 5}, {25, 6}, {19, 7}, {14, 8}, {26, 6}, {27, 6}, {26, 5}, {27, 5}, {28, 5}, {28, 6}, {29, 6}, {15, 8}, {16, 8}, {20, 7}, {30, 6}, {31, 6}, {29, 5}, {32, 6}, {33, 6}, {21, 7}, {17, 8}, {6, 9}, {18, 8}, {22, 7}, {23, 7}, {34, 6}, {35, 6}, {24, 7}, {19, 8}, {7, 9}, {2, 10}, {8, 9}, {20, 8}, {21, 8}, {25, 7}, {22, 8}, {23, 8}, {9, 9}, {3, 10} +}; + +static const Huffman_t HuffQ5 [2] [15] = { + { + {0, 7}, {1, 7}, {2, 6}, {2, 5}, {2, 4}, {2, 3}, {3, 3}, {3, 2}, {4, 3}, {5, 3}, {3, 4}, {3, 5}, {3, 6}, {2, 7}, {3, 7} + }, { + {0, 6}, {1, 6}, {2, 5}, {2, 4}, {3, 4}, {3, 3}, {4, 3}, {5, 3}, {6, 3}, {7, 3}, {4, 4}, {5, 4}, {3, 5}, {2, 6}, {3, 6} + } +}; + +static const Huffman_t HuffQ6 [2] [31] = { + { + {0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 8}, {5, 8}, {4, 7}, {3, 6}, {4, 6}, {5, 6}, {5, 5}, {6, 5}, {4, 4}, {5, 4}, {4, 3}, {3, 2}, {5, 3}, {6, 4}, {7, 4}, {7, 5}, {6, 6}, {7, 6}, {8, 6}, {9, 6}, {5, 7}, {6, 8}, {7, 8}, {4, 9}, {5, 9}, {6, 9}, {7, 9} + }, { + {0, 8}, {1, 8}, {2, 7}, {3, 7}, {4, 7}, {4, 6}, {5, 6}, {4, 5}, {5, 5}, {6, 5}, {5, 4}, {6, 4}, {7, 4}, {8, 4}, {9, 4}, {10, 4}, {11, 4}, {12, 4}, {13, 4}, {14, 4}, {15, 4}, {7, 5}, {8, 5}, {9, 5}, {6, 6}, {7, 6}, {5, 7}, {6, 7}, {7, 7}, {2, 8}, {3, 8} + } +}; + +static const Huffman_t HuffQ7 [2] [63] = { + { + {0, 10}, {1, 10}, {2, 10}, {8, 9}, {9, 9}, {3, 10}, {4, 10}, {5, 10}, {6, 10}, {7, 10}, {10, 9}, {11, 9}, {12, 9}, {13, 9}, {10, 8}, {11, 8}, {12, 8}, {13, 8}, {14, 8}, {10, 7}, {11, 7}, {12, 7}, {13, 7}, {14, 7}, {10, 6}, {11, 6}, {12, 6}, {8, 5}, {9, 5}, {6, 4}, {4, 3}, {3, 2}, {5, 3}, {7, 4}, {10, 5}, {11, 5}, {13, 6}, {14, 6}, {15, 6}, {15, 7}, {16, 7}, {17, 7}, {18, 7}, {15, 8}, {19, 7}, {16, 8}, {17, 8}, {18, 8}, {19, 8}, {14, 9}, {15, 9}, {16, 9}, {17, 9}, {8, 10}, {9, 10}, {10, 10}, {11, 10}, {12, 10}, {18, 9}, {19, 9}, {13, 10}, {14, 10}, {15, 10} + }, { + {0, 9}, {1, 9}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {8, 7}, {9, 7}, {10, 7}, {11, 7}, {12, 7}, {9, 6}, {10, 6}, {11, 6}, {12, 6}, {13, 6}, {14, 6}, {15, 6}, {16, 6}, {12, 5}, {13, 5}, {14, 5}, {15, 5}, {16, 5}, {17, 5}, {18, 5}, {19, 5}, {20, 5}, {21, 5}, {22, 5}, {23, 5}, {24, 5}, {25, 5}, {26, 5}, {27, 5}, {28, 5}, {29, 5}, {30, 5}, {31, 5}, {17, 6}, {18, 6}, {19, 6}, {20, 6}, {21, 6}, {22, 6}, {23, 6}, {13, 7}, {14, 7}, {15, 7}, {16, 7}, {17, 7}, {9, 8}, {10, 8}, {11, 8}, {12, 8}, {13, 8}, {14, 8}, {15, 8}, {2, 9}, {3, 9} + } +}; + +static const Huffman_t HuffQ8 [2] [127] = { + { + {3, 11}, {4, 11}, {10, 10}, {11, 10}, {12, 10}, {13, 10}, {14, 10}, {26, 9}, {15, 10}, {27, 9}, {16, 10}, {0, 12}, {1, 12}, {5, 11}, {6, 11}, {7, 11}, {8, 11}, {9, 11}, {10, 11}, {11, 11}, {17, 10}, {12, 11}, {18, 10}, {19, 10}, {20, 10}, {21, 10}, {22, 10}, {23, 10}, {24, 10}, {25, 10}, {28, 9}, {26, 10}, {27, 10}, {28, 10}, {29, 10}, {30, 10}, {29, 9}, {30, 9}, {31, 9}, {32, 9}, {33, 9}, {34, 9}, {35, 9}, {36, 9}, {25, 8}, {37, 9}, {26, 8}, {27, 8}, {28, 8}, {29, 8}, {30, 8}, {31, 8}, {20, 7}, {21, 7}, {22, 7}, {23, 7}, {14, 6}, {15, 6}, {16, 6}, {17, 6}, {11, 5}, {7, 4}, {4, 3}, {3, 2}, {5, 3}, {12, 5}, {13, 5}, {18, 6}, {19, 6}, {20, 6}, {21, 6}, {24, 7}, {25, 7}, {26, 7}, {27, 7}, {32, 8}, {33, 8}, {34, 8}, {35, 8}, {36, 8}, {37, 8}, {38, 8}, {39, 8}, {38, 9}, {39, 9}, {40, 9}, {41, 9}, {42, 9}, {43, 9}, {44, 9}, {45, 9}, {46, 9}, {31, 10}, {32, 10}, {47, 9}, {33, 10}, {34, 10}, {35, 10}, {36, 10}, {37, 10}, {38, 10}, {39, 10}, {40, 10}, {41, 10}, {13, 11}, {14, 11}, {42, 10}, {15, 11}, {16, 11}, {17, 11}, {18, 11}, {2, 12}, {19, 11}, {3, 12}, {4, 12}, {5, 12}, {43, 10}, {44, 10}, {48, 9}, {49, 9}, {45, 10}, {46, 10}, {47, 10}, {48, 10}, {49, 10}, {50, 10}, {51, 10} + }, { + {0, 9}, {1, 9}, {2, 9}, {3, 9}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8}, {9, 8}, {10, 8}, {11, 8}, {12, 8}, {13, 8}, {14, 8}, {15, 8}, {16, 8}, {17, 8}, {18, 8}, {19, 8}, {20, 8}, {21, 8}, {21, 7}, {22, 7}, {23, 7}, {24, 7}, {25, 7}, {26, 7}, {27, 7}, {28, 7}, {29, 7}, {30, 7}, {31, 7}, {32, 7}, {33, 7}, {34, 7}, {35, 7}, {36, 7}, {37, 7}, {38, 7}, {39, 7}, {40, 7}, {41, 7}, {42, 7}, {43, 7}, {44, 7}, {45, 7}, {46, 7}, {47, 7}, {48, 7}, {38, 6}, {39, 6}, {40, 6}, {41, 6}, {42, 6}, {43, 6}, {44, 6}, {45, 6}, {46, 6}, {47, 6}, {48, 6}, {49, 6}, {50, 6}, {51, 6}, {52, 6}, {53, 6}, {54, 6}, {55, 6}, {56, 6}, {57, 6}, {58, 6}, {59, 6}, {60, 6}, {61, 6}, {62, 6}, {49, 7}, {63, 6}, {50, 7}, {51, 7}, {52, 7}, {53, 7}, {54, 7}, {55, 7}, {56, 7}, {57, 7}, {58, 7}, {59, 7}, {60, 7}, {61, 7}, {62, 7}, {63, 7}, {64, 7}, {65, 7}, {66, 7}, {67, 7}, {68, 7}, {69, 7}, {70, 7}, {71, 7}, {72, 7}, {73, 7}, {74, 7}, {75, 7}, {22, 8}, {23, 8}, {24, 8}, {25, 8}, {26, 8}, {27, 8}, {28, 8}, {29, 8}, {30, 8}, {31, 8}, {32, 8}, {33, 8}, {34, 8}, {35, 8}, {36, 8}, {37, 8}, {38, 8}, {39, 8}, {40, 8}, {41, 8}, {4, 9}, {5, 9}, {6, 9}, {7, 9} + } +}; + +const Huffman_t HuffQ9up [256] = { + {1, 10}, {2, 10}, {3, 10}, {4, 10}, {5, 10}, {5, 9}, {6, 9}, {7, 9}, {8, 9}, {9, 9}, {10, 9}, {11, 9}, {12, 9}, {13, 9}, {14, 9}, {15, 9}, {16, 9}, {17, 9}, {18, 9}, {38, 8}, {39, 8}, {19, 9}, {20, 9}, {21, 9}, {22, 9}, {23, 9}, {24, 9}, {25, 9}, {26, 9}, {27, 9}, {28, 9}, {29, 9}, {30, 9}, {31, 9}, {32, 9}, {33, 9}, {34, 9}, {35, 9}, {36, 9}, {37, 9}, {40, 8}, {38, 9}, {41, 8}, {42, 8}, {43, 8}, {44, 8}, {45, 8}, {46, 8}, {47, 8}, {48, 8}, {49, 8}, {50, 8}, {51, 8}, {52, 8}, {53, 8}, {54, 8}, {55, 8}, {56, 8}, {57, 8}, {58, 8}, {59, 8}, {60, 8}, {61, 8}, {62, 8}, {63, 8}, {64, 8}, {65, 8}, {66, 8}, {67, 8}, {68, 8}, {69, 8}, {70, 8}, {71, 8}, {72, 8}, {73, 8}, {74, 8}, {75, 8}, {76, 8}, {77, 8}, {78, 8}, {79, 8}, {80, 8}, {81, 8}, {82, 8}, {83, 8}, {84, 8}, {85, 8}, {86, 8}, {87, 8}, {88, 8}, {89, 8}, {90, 8}, {91, 8}, {92, 8}, {93, 8}, {94, 8}, {95, 8}, {96, 8}, {97, 8}, {98, 8}, {99, 8}, {100, 8}, {101, 8}, {102, 8}, {103, 8}, {104, 8}, {105, 8}, {106, 8}, {86, 7}, {87, 7}, {88, 7}, {89, 7}, {90, 7}, {91, 7}, {92, 7}, {93, 7}, {94, 7}, {95, 7}, {96, 7}, {97, 7}, {98, 7}, {99, 7}, {100, 7}, {101, 7}, {102, 7}, {103, 7}, {104, 7}, {62, 6}, {63, 6}, {105, 7}, {106, 7}, {107, 7}, {108, 7}, {109, 7}, {110, 7}, {111, 7}, {112, 7}, {113, 7}, {114, 7}, {115, 7}, {116, 7}, {117, 7}, {118, 7}, {119, 7}, {120, 7}, {121, 7}, {122, 7}, {107, 8}, {123, 7}, {108, 8}, {109, 8}, {110, 8}, {111, 8}, {112, 8}, {113, 8}, {114, 8}, {115, 8}, {116, 8}, {117, 8}, {118, 8}, {119, 8}, {120, 8}, {121, 8}, {122, 8}, {123, 8}, {124, 8}, {125, 8}, {126, 8}, {127, 8}, {128, 8}, {129, 8}, {130, 8}, {131, 8}, {132, 8}, {133, 8}, {134, 8}, {135, 8}, {136, 8}, {137, 8}, {138, 8}, {139, 8}, {140, 8}, {141, 8}, {142, 8}, {143, 8}, {144, 8}, {145, 8}, {146, 8}, {147, 8}, {148, 8}, {149, 8}, {150, 8}, {151, 8}, {152, 8}, {153, 8}, {154, 8}, {155, 8}, {156, 8}, {157, 8}, {158, 8}, {159, 8}, {160, 8}, {161, 8}, {162, 8}, {163, 8}, {164, 8}, {165, 8}, {166, 8}, {167, 8}, {168, 8}, {169, 8}, {170, 8}, {171, 8}, {39, 9}, {40, 9}, {41, 9}, {42, 9}, {43, 9}, {44, 9}, {45, 9}, {46, 9}, {47, 9}, {48, 9}, {49, 9}, {50, 9}, {51, 9}, {52, 9}, {53, 9}, {54, 9}, {55, 9}, {56, 9}, {57, 9}, {58, 9}, {59, 9}, {60, 9}, {61, 9}, {62, 9}, {63, 9}, {64, 9}, {65, 9}, {66, 9}, {67, 9}, {68, 9}, {69, 9}, {70, 9}, {71, 9}, {72, 9}, {73, 9}, {74, 9}, {75, 9}, {6, 10}, {7, 10}, {8, 10}, {9, 10}, {0, 11}, {1, 11} +}; + +Huffman_t const * const HuffQ [2] [8] = { + { HuffQ1, HuffQ2[0], HuffQ3, HuffQ4, HuffQ5[0], HuffQ6[0], HuffQ7[0], HuffQ8[0] }, + { HuffQ1, HuffQ2[1], HuffQ3, HuffQ4, HuffQ5[1], HuffQ6[1], HuffQ7[1], HuffQ8[1] } +}; + +/* end of huffsv7.c */ diff --git a/third_party/musepack/libmpcenc/libmpcenc.h b/third_party/musepack/libmpcenc/libmpcenc.h new file mode 100755 index 0000000..e9d5f19 --- /dev/null +++ b/third_party/musepack/libmpcenc/libmpcenc.h @@ -0,0 +1,122 @@ +/* + * Musepack audio compression + * + * 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 + +#include +#include + +// FIXME : define this somewhere else +#ifndef NULL +#define NULL 0 +#endif + +#define MPC_FRAME_LENGTH (36 * 32) +#define MAX_FRAME_SIZE 4352 + +typedef struct { + mpc_uint16_t Code; // >= 14 bit + mpc_uint16_t Length; // >= 4 bit +} Huffman_t; + +typedef struct { + mpc_uint_t pos; // next free byte position in the buffer + mpc_uint_t bitsCount; // number of used bits in bitsBuff + mpc_uint64_t outputBits; // Counter for the number of written bits in the bitstream + mpc_uint32_t bitsBuff; // bits buffer + mpc_uint8_t * buffer; // Buffer for bitstream-file + mpc_uint_t framesInBlock; // Number of frames in current block + mpc_uint_t frames_per_block_pwr; // Number of frame in a block = 1 << frames_per_block_pwr + + // seeking + mpc_uint32_t * seek_table; + mpc_uint32_t seek_pos; /// current position in the seek table + mpc_uint32_t seek_ref; /// reference position for the seek information + mpc_uint32_t seek_ptr; /// position of the seek pointer block + mpc_uint32_t seek_pwr; /// keep a seek table entry every 2^seek_pwr block + mpc_uint32_t block_cnt; /// number of encoded blocks + + FILE * outputFile; // ouput file + + mpc_uint32_t MS_Channelmode; + mpc_uint32_t Overflows; // = 0; // number of internal (filterbank) clippings + mpc_uint32_t MaxBand; /// number of non zero bands in last frame + + mpc_int32_t SCF_Index_L [32] [3]; + mpc_int32_t SCF_Index_R [32] [3]; // holds scalefactor-indices + mpc_int32_t SCF_Last_L [32]; + mpc_int32_t SCF_Last_R [32]; // Last coded SCF value + 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_bool_t MS_Flag[32]; // MS used? + } mpc_encoder_t; + + void mpc_encoder_init ( mpc_encoder_t * e, + mpc_uint64_t SamplesInWAVE, + unsigned int FramesBlockPwr, + unsigned int SeekDistance ); + void mpc_encoder_exit ( mpc_encoder_t * e ); + void writeStreamInfo ( mpc_encoder_t*e, + const unsigned int MaxBand, + const unsigned int MS_on, + const unsigned int SamplesCount, + const unsigned int SamplesSkip, + const unsigned int SampleFreq, + const unsigned int ChannelCount); + void writeGainInfo ( mpc_encoder_t * e, + unsigned short t_gain, + unsigned short t_peak, + unsigned short a_gain, + unsigned short a_peak); + void writeEncoderInfo ( mpc_encoder_t * e, + const float profile, + const int PNS_on, + const int version_major, + const int version_minor, + const int version_build ); + mpc_uint32_t writeBlock ( mpc_encoder_t *, const char *, const mpc_bool_t, mpc_uint32_t); + void writeMagic (mpc_encoder_t * e); + void emptyBits(mpc_encoder_t * e); + + /// maximum number of output bits is 31 ! + static mpc_inline void writeBits (mpc_encoder_t * e, mpc_uint32_t input, unsigned int bits ) + { + e->outputBits += bits; + + if (e->bitsCount + bits > sizeof(e->bitsBuff) * 8) { + int tmp = (sizeof(e->bitsBuff) * 8 - e->bitsCount); + bits -= tmp; + e->bitsBuff = (e->bitsBuff << tmp) | (input >> bits); + e->bitsCount = sizeof(e->bitsBuff) * 8; + emptyBits(e); + input &= (1 << bits) - 1; + } + e->bitsBuff = (e->bitsBuff << bits) | input; + e->bitsCount += bits; + } + void writeSeekTable (mpc_encoder_t * e); + void writeBitstream_SV8 ( mpc_encoder_t*, int); + + unsigned int encodeSize(mpc_uint64_t, char *, mpc_bool_t); + void encodeEnum(mpc_encoder_t * e, const mpc_uint32_t bits, const mpc_uint_t N); + void encodeLog(mpc_encoder_t * e, mpc_uint32_t value, mpc_uint32_t max); + + diff --git a/third_party/musepack/libmpcenc/quant.c b/third_party/musepack/libmpcenc/quant.c new file mode 100755 index 0000000..4cad889 --- /dev/null +++ b/third_party/musepack/libmpcenc/quant.c @@ -0,0 +1,309 @@ +/* + * Musepack audio compression + * Copyright (c) 2005-2009, The Musepack Development Team + * 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 + */ + +#include "libmpcenc.h" +#include +#include + +/* V A R I A B L E S */ +float __SCF [128 + 6]; // tabulated scalefactors +#define SCF ( __SCF + 6 ) +float __invSCF [128 + 6]; // inverted scalefactors +#define invSCF (__invSCF + 6) + + +// Quantization-coefficients: step/65536 bzw. (2*D[Res]+1)/65536 +static const float __A [1 + 18] = { + 0.0000762939453125f, + 0.0000000000000000f, 0.0000457763671875f, 0.0000762939453125f, 0.0001068115234375f, + 0.0001373291015625f, 0.0002288818359375f, 0.0004730224609375f, 0.0009613037109375f, + 0.0019378662109375f, 0.0038909912109375f, 0.0077972412109375f, 0.0156097412109375f, + 0.0312347412109375f, 0.0624847412109375f, 0.1249847412109375f, 0.2499847412109375f, + 0.4999847412109375f +}; + + +// Requantization-coefficients: 65536/step bzw. 1/A[Res] +static const float __C [1 + 18] = { + 13107.200000000001f, + 65535.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.000015259022f +}; + + +// Requantization-Offset: 2*D+1 = steps of quantizer +static const int __D [1 + 18] = { + 2, + 0, 1, 2, 3, 4, 7, 15, 31, 63, + 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767 +}; + +#define A (__A + 1) +#define C (__C + 1) +#define D (__D + 1) + +// Generation of the scalefactors and their inverses +void +Init_Skalenfaktoren ( void ) +{ + int n; + + for ( n = -6; n < 128; n++ ) { + SCF[n] = (float) ( pow(10.,-0.1*(n-1)/1.26) ); + invSCF[n] = (float) ( pow(10., 0.1*(n-1)/1.26) ); + } +} + +#ifdef WIN32 +#pragma warning ( disable : 4305 ) +#endif + +static float NoiseInjectionCompensation1D [18] = { +#if 1 + 1.f, + 0.884621, + 0.935711, + 0.970829, + 0.987941, + 0.994315, + 0.997826, + 0.999744, + 1., 1., 1., 1., 1., 1., 1., 1., 1., 1. +#else + 1., + 0.907073, // -1...+1 + 0.946334, // -2...+2 + 0.974793, // -3...+3 + 0.987647, // -4...+4 + 0.994330, // -7...+7 + 0.997846, // -15...+15 + 1., // -31...+31 + 1., + 1., + 1., + 1., + 1., + 1., + 1., + 1., + 1., + 1., +#endif +} ; + +#if 0 +static float NoiseInjectionCompensation2D [18] [32] = { + { 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, }, + { 0.931595, 0.891390, 0.852494, 0.872420, 0.904053, 0.933716, 0.958976, 0.977719, 0.993979, 1.009011, 1.020961, 1.029564, 1.026582, 1.026753, 1.035573, 1.053251, 1.073429, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, 1.096344, }, + { 0.878264, 0.882351, 0.904261, 0.930843, 0.949243, 0.966741, 0.980500, 0.988182, 0.993361, 0.997112, 0.998918, 0.999501, 1.003179, 1.007445, 1.008678, 0.995890, 0.991015, 0.988019, 0.985479, 0.987646, 1.003605, 1.029301, 1.040511, 1.061531, 1.083302, 1.083302, 1.083302, 1.083302, 1.083302, 1.083302, 1.083302, 1.083302, }, + { 0.866977, 0.943500, 0.941561, 0.953049, 0.967274, 0.980476, 0.988678, 0.993240, 0.996376, 0.998513, 0.999545, 0.999775, 1.000898, 1.003954, 1.006308, 1.004932, 1.002867, 1.002922, 1.003624, 1.005487, 1.003919, 1.008022, 0.987693, 1.000358, 1.017461, 1.039166, 1.056053, 1.068191, 1.068191, 1.068191, 1.068191, 1.068191, }, + { 0.880390, 0.976713, 0.976180, 0.976596, 0.982011, 0.988786, 0.993619, 0.996641, 0.998824, 1.000297, 1.001195, 1.001718, 1.002395, 1.003503, 1.005617, 1.005072, 1.002409, 1.003703, 1.003412, 1.003318, 1.005290, 1.007112, 1.014370, 1.010040, 1.000780, 1.005700, 1.020505, 1.030123, 1.030123, 1.030123, 1.030123, 1.030123, }, + { 0.916894, 0.987164, 0.988734, 0.992318, 0.995268, 0.996932, 0.998141, 0.999072, 0.999674, 1.000104, 1.000292, 1.000386, 1.000399, 1.000222, 1.000671, 1.002127, 1.000137, 1.000046, 0.999644, 0.999156, 1.000568, 1.000098, 0.993764, 0.993954, 0.998971, 1.002835, 1.002972, 0.995376, 1.001643, 1.001643, 1.001643, 1.001643, }, + { 0.982771, 0.995034, 0.997118, 0.998294, 0.998652, 0.999016, 0.999382, 0.999598, 0.999746, 0.999851, 0.999837, 0.999881, 0.999847, 1.000154, 0.999885, 1.000222, 0.999963, 1.000934, 0.999804, 0.999927, 1.000379, 0.997574, 0.997943, 0.998748, 0.998151, 0.997458, 1.000319, 1.001091, 0.998461, 0.996151, 1.005969, 1.005969, }, + { 0.997150, 0.999903, 0.999424, 0.999537, 0.999661, 0.999753, 0.999851, 0.999903, 0.999928, 0.999963, 0.999969, 0.999941, 0.999974, 0.999967, 0.999996, 0.999975, 0.999966, 0.999704, 0.999946, 0.999894, 0.999905, 1.000840, 1.000716, 1.000799, 1.000406, 0.999912, 1.000153, 0.999789, 1.000495, 1.000495, 1.001167, 1.001347, }, + { 0.995524, 0.999983, 1.000044, 0.999965, 0.999970, 0.999974, 0.999986, 0.999995, 0.999996, 1.000011, 0.999997, 1.000010, 1.000010, 1.000026, 1.000006, 1.000148, 1.000048, 0.999999, 1.000161, 1.000193, 0.999797, 1.000145, 0.999974, 1.000039, 0.999731, 0.999985, 1.000563, 1.000256, 1.000637, 1.000050, 1.002013, 1.001053, }, + { 0.994796, 0.999833, 1.000003, 1.000012, 0.999986, 0.999991, 0.999991, 1.000000, 1.000004, 0.999999, 1.000005, 1.000004, 1.000008, 0.999996, 1.000027, 1.000097, 0.999951, 0.999938, 0.999989, 1.000001, 1.000048, 0.999935, 1.000068, 1.000134, 0.999961, 1.000198, 0.999956, 0.999957, 0.999844, 1.000087, 0.999708, 1.000198, }, + { 0.996046, 0.999902, 1.000019, 1.000017, 0.999983, 0.999997, 1.000002, 0.999993, 0.999999, 1.000003, 1.000001, 1.000015, 1.000004, 1.000006, 0.999987, 0.999993, 0.999992, 1.000029, 1.000064, 0.999997, 1.000044, 1.000044, 0.999919, 0.999875, 1.000011, 0.999897, 0.999905, 0.999996, 0.999934, 0.999968, 1.000008, 0.999902, }, + { 0.998703, 0.999963, 1.000021, 1.000006, 1.000008, 1.000000, 1.000003, 0.999994, 0.999990, 0.999990, 1.000003, 1.000009, 1.000001, 0.999999, 1.000001, 1.000009, 0.999999, 0.999988, 1.000003, 0.999971, 1.000005, 1.000042, 0.999924, 0.999995, 0.999998, 0.999988, 0.999961, 0.999942, 1.000046, 1.000061, 1.000112, 1.000052, }, + { 0.999872, 1.000001, 1.000004, 0.999998, 0.999999, 0.999998, 0.999992, 0.999990, 0.999991, 1.000000, 1.000000, 1.000000, 1.000002, 0.999996, 1.000004, 1.000011, 0.999963, 1.000016, 1.000050, 0.999996, 0.999998, 1.000006, 0.999990, 0.999948, 0.999974, 1.000060, 1.000014, 0.999987, 0.999986, 0.999917, 0.999973, 1.000035, }, + { 1.000366, 1.000006, 0.999996, 0.999995, 0.999998, 0.999996, 0.999991, 1.000001, 0.999990, 0.999996, 1.000010, 0.999999, 1.000002, 1.000000, 0.999996, 0.999990, 1.000014, 0.999978, 1.000011, 0.999983, 0.999988, 0.999971, 0.999997, 0.999989, 0.999986, 0.999958, 1.000005, 0.999992, 0.999975, 0.999975, 0.999975, 0.999975, }, + { 0.999736, 0.999995, 1.000002, 1.000004, 0.999999, 1.000000, 1.000003, 1.000000, 1.000007, 0.999992, 0.999997, 0.999998, 0.999998, 0.999997, 1.000007, 1.000012, 1.000004, 0.999995, 0.999996, 1.000009, 1.000003, 1.000008, 1.000001, 1.000003, 1.000011, 1.000019, 0.999991, 0.999970, 0.999970, 0.999970, 0.999970, 0.999965, }, + { 0.999970, 1.000000, 1.000000, 1.000000, 1.000001, 1.000000, 1.000000, 0.999999, 1.000001, 1.000000, 0.999999, 0.999999, 0.999999, 1.000007, 1.000005, 1.000002, 0.999999, 0.999999, 1.000000, 0.999997, 0.999999, 1.000001, 1.000001, 0.999988, 0.999988, 0.999984, 0.999995, 0.999986, 0.999986, 0.999986, 0.999986, 0.999986, }, + { 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, }, + { 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, }, +}; +#endif + +#ifdef WIN32 +#pragma warning ( default : 4305 ) +#endif + +void +NoiseInjectionComp ( void ) +{ + int i; + + for ( i = 0; i < sizeof(NoiseInjectionCompensation1D)/sizeof(*NoiseInjectionCompensation1D); i++ ) + NoiseInjectionCompensation1D [i] = 1.f; +#if 0 + for ( i = 0; i < sizeof(NoiseInjectionCompensation2D)/sizeof(**NoiseInjectionCompensation2D); i++ ) + NoiseInjectionCompensation2D [0][i] = 1.f; +#endif +} + + +// Quantizes a subband and calculates iSNR +float +ISNR_Schaetzer ( const float* input, const float SNRcomp, const int res ) +{ + const float fac = A [res] * NoiseInjectionCompensation1D [res]; + const float invfac = C [res] / NoiseInjectionCompensation1D [res]; + float signal = 1.e-30f; + float error = 1.e-30f; + const float * in_end = input + 36; + + // Summation of the absolute power and the quadratic error + do { + float err; + err = mpc_nearbyintf(input[0] * fac) * invfac - input[0]; + error += err * err; + signal += input[0] * input[0]; + + err = mpc_nearbyintf(input[1] * fac) * invfac - input[1]; + error += err * err; + signal += input[1] * input[1]; + + err = mpc_nearbyintf(input[2] * fac) * invfac - input[2]; + error += err * err; + signal += input[2] * input[2]; + + err = mpc_nearbyintf(input[3] * fac) * invfac - input[3]; + error += err * err; + signal += input[3] * input[3]; + + input += 4; + + } while (input < in_end); + + error *= NoiseInjectionCompensation1D [res] * NoiseInjectionCompensation1D [res]; + signal *= NoiseInjectionCompensation1D [res] * NoiseInjectionCompensation1D [res]; + + // Utilization of SNRcomp only if SNR > 1 !!! + return signal > error ? error / (SNRcomp * signal) : error / signal; +} + + +float +ISNR_Schaetzer_Trans ( const float* input, const float SNRcomp, const int res ) +{ + int k; + float fac = A [res]; + float invfac = C [res]; + float signal, error, ret, err, sig; + + // Summation of the absolute power and the quadratic error + k = 0; + signal = error = 1.e-30f; + for ( ; k < 12; k++ ) { + sig = input[k] * NoiseInjectionCompensation1D [res]; + err = mpc_nearbyintf(sig * fac) * invfac - sig; + + error += err * err; + signal += sig * sig; + } + err = signal > error ? error / (SNRcomp * signal) : error / signal; + ret = err; + signal = error = 1.e-30f; + for ( ; k < 24; k++ ) { + sig = input[k] * NoiseInjectionCompensation1D [res]; + err = mpc_nearbyintf(sig * fac) * invfac - sig; + + error += err * err; + signal += sig * sig; + } + err = signal > error ? error / (SNRcomp * signal) : error / signal; + ret = maxf(ret, err); + + signal = error = 1.e-30f; + for ( ; k < 36; k++ ) { + sig = input[k] * NoiseInjectionCompensation1D [res]; + err = mpc_nearbyintf(sig * fac) * invfac - sig; + + error += err * err; + signal += sig * sig; + } + err = signal > error ? error / (SNRcomp * signal) : error / signal; + ret = maxf(ret, err); + + return ret; +} + + +// Linear quantizer for a subband +void +QuantizeSubband ( mpc_int16_t* qu_output, const float* input, const int res, float* errors, const int maxNsOrder ) +{ + int n, quant; + int offset = D [res]; + float mult = A [res] * NoiseInjectionCompensation1D [res]; + float invmult = C [res]; + float signal; + + for ( n = 0; n < 36 - maxNsOrder; n++) { + quant = (unsigned int)(mpc_lrintf(input[n] * mult) + offset); + + // limitation to 0...2D + if ((unsigned int)quant > (unsigned int)offset * 2 ) { + quant = mini ( quant, offset * 2 ); + quant = maxi ( quant, 0 ); + } + qu_output[n] = quant; + } + + for ( ; n < 36; n++) { + signal = input[n] * mult; + quant = (unsigned int)(mpc_lrintf(signal) + offset); + + // calculate the current error and save it for error refeeding + errors [n + 6] = invmult * (quant - offset) - signal * NoiseInjectionCompensation1D [res]; + + // limitation to 0...2D + if ((unsigned int)quant > (unsigned int)offset * 2 ) { + quant = mini ( quant, offset * 2 ); + quant = maxi ( quant, 0 ); + } + qu_output[n] = quant; + } +} + + +// NoiseShaper for a subband +void +QuantizeSubbandWithNoiseShaping ( mpc_int16_t* qu_output, const float* input, const int res, float* errors, const float* FIR ) +{ + float signal; + float mult = A [res]; + float invmult = C [res]; + int offset = D [res]; + int n, quant; + + memset(errors, 0, 6 * sizeof *errors); // arghh, it produces pops on each frame boundary! + + for ( n = 0; n < 36; n++) { + signal = input[n] * NoiseInjectionCompensation1D [res] - (FIR[5]*errors[n+0] + FIR[4]*errors[n+1] + FIR[3]*errors[n+2] + FIR[2]*errors[n+3] + FIR[1]*errors[n+4] + FIR[0]*errors[n+5]); + quant = mpc_lrintf(signal * mult); + + // calculate the current error and save it for error refeeding + errors [n + 6] = invmult * quant - signal * NoiseInjectionCompensation1D [res]; + + // limitation to +/-D + quant = minf ( quant, +offset ); + quant = maxf ( quant, -offset ); + + qu_output[n] = (unsigned int)(quant + offset); + } +} + +/* end of quant.c */ + +// pfk@schnecke.offl.uni-jena.de@EMAIL, Andree.Buschmann@web.de@EMAIL, BuschmannA@becker.de@EMAIL, miyaguch@eskimo.com@EMAIL, r3mix@irc.openprojects.net@EMAIL, dibrom@users.sourceforge.net@EMAIL, m.p.bakker-10@student.utwente.nl@EMAIL, djmrob@essex.ac.uk@EMAIL, dim@psytel-research.co.yu@EMAIL, lerch@zplane.de@EMAIL, takehiro@users.sourceforge.net@EMAIL, aleidinger@users.sourceforge.net@EMAIL, Robert.Hegemann@gmx.de@EMAIL, bouvigne@mp3-tech.org@EMAIL, monty@xiph.org@EMAIL, Pumpkinz99@aol.com@EMAIL, spase@outerspase.net@EMAIL, mt@wildpuppy.com@EMAIL, juha.laaksonheimo@tut.fi@EMAIL, speek@myrealbox.com@EMAIL, w.speek@12move.nl@EMAIL, martin@spueler.de@EMAIL, nicolaus.berglmeir@t-online.de@EMAIL, thomas.a.juerges@ruhr-uni-bochum.de@EMAIL, HelH@mpex.net@EMAIL, garf@roadum.demon.co.uk@EMAIL, gcp@sjeng.org@EMAIL, mike@naivesoftware.com@EMAIL, case@mobiili.net@EMAIL, steve.lhomme@free.fr@EMAIL, walter@binity.com@EMAIL