Updated MPCDec to latest release, which now supports SV8 proper

CQTexperiment
Chris Moeller 2014-10-19 17:42:04 -07:00
parent 587db5fdbe
commit 58eda0e491
38 changed files with 4762 additions and 2738 deletions

View File

@ -1,105 +0,0 @@
/* include/config.h. Generated by configure. */
/* include/config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `memmove' function. */
#define HAVE_MEMMOVE 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if the system has the type `ptrdiff_t'. */
#define HAVE_PTRDIFF_T 1
/* Define to 1 if you have the `sqrt' function. */
#define HAVE_SQRT 1
/* Define to 1 if stdbool.h conforms to C99. */
#define HAVE_STDBOOL_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if the system has the type `_Bool'. */
#define HAVE__BOOL 1
/* Name of package */
#define PACKAGE "libmpcdec"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME ""
/* Define to the full name and version of this package. */
#define PACKAGE_STRING ""
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME ""
/* Define to the version of this package. */
#define PACKAGE_VERSION ""
/* The size of a `int', as computed by sizeof. */
#define SIZEOF_INT 4
/* The size of a `long', as computed by sizeof. */
#define SIZEOF_LONG 4
/* The size of a `long long', as computed by sizeof. */
#define SIZEOF_LONG_LONG 8
/* The size of a `short', as computed by sizeof. */
#define SIZEOF_SHORT 2
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Version number of package */
#define VERSION "1.2"
/* Define to 1 if your processor stores words with the most significant byte
first (like Motorola and SPARC, unlike Intel and VAX). */
#define WORDS_BIGENDIAN 1
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
/* #undef inline */
#endif
/* Define to `long' if <sys/types.h> does not define. */
/* #undef off_t */
/* Define to `unsigned' if <sys/types.h> does not define. */
/* #undef size_t */

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2005, The Musepack Development Team
Copyright (c) 2005-2009, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -31,19 +31,18 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file decoder.h
#ifndef _MPCDEC_DECODER_H_
#define _MPCDEC_DECODER_H_
#ifdef WIN32
#pragma once
#endif
#ifndef _mpcdec_decoder_h_
#define _mpcdec_decoder_h_
#include <mpcdec/reader.h>
#include "huffman.h"
#include "math.h"
#include "mpcdec.h"
#include "reader.h"
#include "streaminfo.h"
#define MPC_SUPPORT_SV456
#ifdef __cplusplus
extern "C" {
#endif
#define SEEKING_TABLE_SIZE 256u
// set it to SLOW_SEEKING_WINDOW to not use fast seeking
@ -52,55 +51,31 @@
#define SLOW_SEEKING_WINDOW 0x80000000
enum {
MPC_V_MEM = 2304,
MPC_V_MEM = 2304,
MPC_DECODER_MEMSIZE = 16384, // overall buffer size
};
typedef struct {
mpc_int32_t L [36];
mpc_int32_t R [36];
} QuantTyp;
typedef struct mpc_decoder_t {
mpc_reader *r;
struct mpc_decoder_t {
/// @name internal state variables
//@{
mpc_uint32_t stream_version; ///< Streamversion of stream
mpc_int32_t max_band; ///< Maximum band-index used in stream (0...31)
mpc_uint32_t ms; ///< Mid/side stereo (0: off, 1: on)
mpc_uint32_t channels; ///< Number of channels in stream
mpc_uint32_t dword; /// currently decoded 32bit-word
mpc_uint32_t pos; /// bit-position within dword
mpc_uint32_t Speicher[MPC_DECODER_MEMSIZE]; /// read-buffer
mpc_uint32_t Zaehler; /// actual index within read-buffer
mpc_uint64_t samples; ///< Number of samples in stream
mpc_uint32_t samples_to_skip;
mpc_uint32_t DecodedFrames;
mpc_uint32_t OverallFrames;
mpc_int32_t SampleRate; // Sample frequency
mpc_uint32_t StreamVersion; // version of bitstream
mpc_int32_t Max_Band;
mpc_uint32_t MPCHeaderPos; // AB: needed to support ID3v2
mpc_uint32_t FrameWasValid;
mpc_uint32_t MS_used; // MS-coding used ?
mpc_uint32_t TrueGaplessPresent;
mpc_uint32_t WordsRead; // counts amount of decoded dwords
mpc_uint64_t decoded_samples; ///< Number of samples decoded from file begining
mpc_uint32_t samples_to_skip; ///< Number samples to skip (used for seeking)
mpc_int32_t last_max_band; ///< number of bands used in the last frame
// randomizer state variables
mpc_uint32_t __r1;
mpc_uint32_t __r2;
// seeking
mpc_uint32_t seeking_table[SEEKING_TABLE_SIZE];
mpc_uint32_t seeking_pwr; // distance between 2 frames in seeking_table = 2^seeking_pwr
mpc_uint32_t seeking_table_frames; // last frame in seaking table
mpc_uint32_t seeking_window; // number of frames to look for scalefactors
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
QuantTyp Q [32]; // holds quantized samples
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];
@ -109,7 +84,7 @@ typedef struct mpc_decoder_t {
mpc_int32_t SCFI_R [32]; // describes order of transmitted SCF
mpc_bool_t MS_Flag[32]; // MS used?
#ifdef MPC_FIXED_POINT
unsigned char SCF_shift[256];
mpc_uint8_t SCF_shift[256];
#endif
MPC_SAMPLE_FORMAT V_L[MPC_V_MEM + 960];
@ -118,7 +93,9 @@ typedef struct mpc_decoder_t {
MPC_SAMPLE_FORMAT Y_R[36][32];
MPC_SAMPLE_FORMAT SCF[256]; ///< holds adapted scalefactors (for clipping prevention)
//@}
};
} mpc_decoder;
#endif // _mpc_decoder_h
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2005, The Musepack Development Team
Copyright (c) 2005-2009, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -31,28 +31,53 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file huffman.h
/// Data structures and functions for huffman coding.
#ifndef _mpcdec_huffman_h_
#define _mpcdec_huffman_h_
#ifndef WIN32
#include "mpcdec/config_types.h"
#else
#include "mpcdec/config_win32.h"
#ifndef _MPCDEC_HUFFMAN_H_
#define _MPCDEC_HUFFMAN_H_
#ifdef WIN32
#pragma once
#endif
#include "decoder.h"
#include <mpcdec/mpc_types.h>
struct mpc_decoder_t; // forward declare to break circular dependencies
#ifdef __cplusplus
extern "C" {
#endif
// LUT size parameter, LUT size is 1 << LUT_DEPTH
#define LUT_DEPTH 6
/// Huffman table entry.
typedef struct huffman_type_t {
mpc_uint32_t Code;
mpc_uint16_t Length;
mpc_int16_t Value;
} HuffmanTyp;
typedef struct mpc_huffman_t {
mpc_uint16_t Code;
mpc_uint8_t Length;
mpc_int8_t Value;
} mpc_huffman;
#endif // _mpcdec_huffman_h_
/// Huffman LUT entry.
typedef struct mpc_huff_lut_t {
mpc_uint8_t Length;
mpc_int8_t Value;
} mpc_huff_lut;
/// Type used for huffman LUT decoding
typedef struct mpc_lut_data_t {
mpc_huffman const * 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

View File

@ -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 <mpcdec/mpcdec.h>
/// 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

View File

@ -1,38 +0,0 @@
/**
\mainpage libmpcdec documentation
\section whats what is libmpcdec
libmpcdec is a library that decodes musepack compressed audio data. Musepack
is a free, high performance, high quality lossy audio compression codec. For
more information on musepack visit http://www.musepack.net.
\section using using libmpcdec
Using libmpcdec is very straightforward. There are typically four things you must
do to use libmpcdec in your application.
\subsection step1 step 1: implement an mpc_reader to provide raw data to the decoder library
The role of the mpc_reader is to provide raw mpc stream data to the mpc decoding library.
This data can come from a file, a network socket, or any other source you wish.
See the documentation of
\link mpc_reader_t mpc_reader \endlink
for more information.
\subsection step2 step2: read the streaminfo properties structure from the stream
This is a simple matter of calling the streaminfo_init() and streaminfo_read() functions,
supplying your mpc_reader as a source of raw data. This reads the stream properties header from the
mpc stream. This information will be used to prime the decoder for decoding in
the next step.
\subsection step3 step 3: initialize an mpc_decoder with your mpc_reader source
This is just a matter of calling the mpc_decoder_setup() and mpc_decoder_initialize()
functions with your mpc_decoder, mpc_reader data source and streaminfo information.
\subsection step4 step 4: iteratively read raw sample data from the mpc decoder
Once you've initialized the decoding library you just iteratively call the
mpc_decoder_decode routine until it indicates that the entire stream has been read.
For a simple example of all of these steps see the sample application distributed with
libmpcdec in src/sample.cpp.
*/

View File

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

View File

@ -1,48 +0,0 @@
/*
Copyright (c) 2005, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the The Musepack Development Team nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MUSEPACK_CONFIG_TYPES_H__
#define __MUSEPACK_CONFIG_TYPES_H__
typedef unsigned char mpc_bool_t;
#define TRUE 1
#define FALSE 0
typedef short mpc_int16_t;
typedef unsigned short mpc_uint16_t;
typedef int mpc_int32_t;
typedef unsigned int mpc_uint32_t;
typedef long long mpc_int64_t;
#endif // __MUSEPACK_CONFIG_TYPES_H__

View File

@ -1,50 +0,0 @@
/*
Copyright (c) 2005, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the The Musepack Development Team nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MUSEPACK_CONFIG_TYPES_H__
#define __MUSEPACK_CONFIG_TYPES_H__
@INTTYPES_H@
typedef unsigned char mpc_bool_t;
#define TRUE 1
#define FALSE 0
typedef @SIZE16@ mpc_int16_t;
typedef @USIZE16@ mpc_uint16_t;
typedef @SIZE32@ mpc_int32_t;
typedef @USIZE32@ mpc_uint32_t;
typedef @SIZE64@ mpc_int64_t;
#endif // __MUSEPACK_CONFIG_TYPES_H__

View File

@ -1,52 +0,0 @@
/*
Copyright (c) 2005, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the The Musepack Development Team nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __MUSEPACK_CONFIG_WIN32_H__
#define __MUSEPACK_CONFIG_WIN32_H__
typedef unsigned char mpc_bool_t;
#define TRUE 1
#define FALSE 0
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;
#define MPC_LITTLE_ENDIAN
#endif // __MUSEPACK_CONFIG_WIN32_H__

View File

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

View File

@ -1,65 +0,0 @@
/*
Copyright (c) 2005, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the The Musepack Development Team nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file internal.h
/// Definitions and structures used only internally by the libmpcdec.
#ifndef _mpcdec_internal_h
#define _mpcdec_internal_h
enum {
MPC_DECODER_SYNTH_DELAY = 481
};
/// Big/little endian 32 bit byte swapping routine.
static __inline
mpc_uint32_t mpc_swap32(mpc_uint32_t val) {
return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) |
((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24));
}
/// Searches for a ID3v2-tag and reads the length (in bytes) of it.
/// \param reader supplying raw stream data
/// \return size of tag, in bytes
/// \return -1 on errors of any kind
mpc_int32_t JumpID3v2(mpc_reader* fp);
/// helper functions used by multiple files
mpc_uint32_t mpc_random_int(mpc_decoder *d); // in synth_filter.c
void mpc_decoder_initialisiere_quantisierungstabellen(mpc_decoder *d, double scale_factor);
void mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT* OutData);
#endif // _mpcdec_internal_h

View File

@ -0,0 +1,57 @@
/*
* Musepack audio compression
* Copyright (C) 1999-2004 Buschmann/Klemm/Piecha/Wolf
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#pragma once
# define clip(x,min,max) ( (x) < (min) ? (min) : (x) > (max) ? (max) : (x) )
#ifdef __cplusplus
# define maxi(A,B) ( (A) >? (B) )
# define mini(A,B) ( (A) <? (B) )
# define maxd(A,B) ( (A) >? (B) )
# define mind(A,B) ( (A) <? (B) )
# define maxf(A,B) ( (A) >? (B) )
# define minf(A,B) ( (A) <? (B) )
#else
# define maxi(A,B) ( (A) > (B) ? (A) : (B) )
# define mini(A,B) ( (A) < (B) ? (A) : (B) )
# define maxd(A,B) ( (A) > (B) ? (A) : (B) )
# define mind(A,B) ( (A) < (B) ? (A) : (B) )
# define maxf(A,B) ( (A) > (B) ? (A) : (B) )
# define minf(A,B) ( (A) < (B) ? (A) : (B) )
#endif
#ifdef __GNUC__
# define absi(A) abs (A)
# define absf(A) fabsf (A)
# define absd(A) fabs (A)
#else
# define absi(A) ( (A) >= 0 ? (A) : -(A) )
# define absf(A) ( (A) >= 0.f ? (A) : -(A) )
# define absd(A) ( (A) >= 0. ? (A) : -(A) )
#endif

View File

@ -0,0 +1,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 <stdlib.h>
#include <memory.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _MSC_VER
typedef __int8 mpc_int8_t;
typedef unsigned __int8 mpc_uint8_t;
typedef __int16 mpc_int16_t;
typedef unsigned __int16 mpc_uint16_t;
typedef __int32 mpc_int32_t;
typedef unsigned __int32 mpc_uint32_t;
typedef __int64 mpc_int64_t;
typedef unsigned __int64 mpc_uint64_t;
#define mpc_inline __inline
#else
#include <stdint.h>
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

175
Frameworks/MPCDec/Files/include/mpcdec/mpcdec.h Normal file → Executable file
View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2005, The Musepack Development Team
Copyright (c) 2005-2009, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -31,115 +31,118 @@
(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
#ifndef _mpcdec_h_
#define _mpcdec_h_
#include "reader.h"
#include "streaminfo.h"
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32
#include "mpcdec/config_types.h"
#else
#include "mpcdec/config_win32.h"
#endif
#include "decoder.h"
#include "math.h"
#include "reader.h"
#include "streaminfo.h"
enum {
MPC_FRAME_LENGTH = (36 * 32), /// samples per mpc frame
MPC_DECODER_BUFFER_LENGTH = 4 * MPC_FRAME_LENGTH /// required buffer size for decoder
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
};
// error codes
#define ERROR_CODE_OK 0
#define ERROR_CODE_FILE -1
#define ERROR_CODE_SV7BETA 1
#define ERROR_CODE_CBR 2
#define ERROR_CODE_IS 3
#define ERROR_CODE_BLOCKSIZE 4
#define ERROR_CODE_INVALIDSV 5
typedef struct mpc_decoder_t mpc_decoder;
typedef struct mpc_demux_t mpc_demux;
/// Initializes a streaminfo structure.
/// \param si streaminfo structure to initialize
void mpc_streaminfo_init(mpc_streaminfo *si);
typedef struct mpc_bits_reader_t {
unsigned char * buff; /// pointer on current byte
unsigned int count; /// unread bits in current byte
} mpc_bits_reader;
/// Reads streaminfo header from the mpc stream supplied by r.
/// \param si streaminfo pointer to which info will be written
/// \param r stream reader to supply raw data
/// \return error code
mpc_int32_t mpc_streaminfo_read(mpc_streaminfo *si, mpc_reader *r);
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;
/// Gets length of stream si, in seconds.
/// \return length of stream in seconds
double mpc_streaminfo_get_length(mpc_streaminfo *si);
/// Returns length of stream si, in samples.
/// \return length of stream in samples
mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si);
/// Sets up decoder library.
/// Call this first when preparing to decode an mpc stream.
/// \param r reader that will supply raw data to the decoder
void mpc_decoder_setup(mpc_decoder *d, mpc_reader *r);
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.
/// Call this next after calling mpc_decoder_setup.
/// \param si streaminfo structure indicating format of source stream
/// \return TRUE if decoder was initalized successfully, FALSE otherwise
mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si);
/// \return pointer on the initialized decoder structure if successful, 0 if not
MPC_API mpc_decoder * mpc_decoder_init(mpc_streaminfo *si);
/// Call this next after calling mpc_decoder_setup.
/// \param si streaminfo structure indicating format of source stream
/// \param fast_seeking boolean 0 = use fast seeking if safe, 1 = force fast seeking
void mpc_decoder_set_seeking(mpc_decoder *d, mpc_streaminfo *si, mpc_bool_t fast_seeking);
/// Releases input mpc decoder
MPC_API void mpc_decoder_exit(mpc_decoder *p_dec);
void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si);
/**
* 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);
/// Sets decoder sample scaling factor. All decoded samples will be multiplied
/// by this factor.
/// \param scale_factor multiplicative scaling factor
void mpc_decoder_scale_output(mpc_decoder *d, double scale_factor);
MPC_API void mpc_decoder_decode_frame(mpc_decoder * d, mpc_bits_reader * r, mpc_frame_info * i);
/// Actually reads data from previously initialized stream. Call
/// this iteratively to decode the mpc stream.
/// \param buffer destination buffer for decoded samples
/// \param vbr_update_acc \todo document me
/// \param vbr_update_bits \todo document me
/// \return -1 if an error is encountered
/// \return 0 if the stream has been completely decoded successfully and there are no more samples
/// \return > 0 to indicate the number of bytes that were actually read from the stream.
mpc_uint32_t mpc_decoder_decode(
mpc_decoder *d,
MPC_SAMPLE_FORMAT *buffer,
mpc_uint32_t *vbr_update_acc,
mpc_uint32_t *vbr_update_bits);
// This is the gain reference used in old replaygain
#define MPC_OLD_GAIN_REF 64.82
mpc_uint32_t mpc_decoder_decode_frame(
mpc_decoder *d,
mpc_uint32_t *in_buffer,
mpc_uint32_t in_len,
MPC_SAMPLE_FORMAT *out_buffer);
/**
* 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);
/// Seeks to the specified sample in the source stream.
mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample);
/// \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);
/// Seeks to specified position in seconds in the source stream.
mpc_bool_t mpc_decoder_seek_seconds(mpc_decoder *d, double seconds);
/// 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 // __cplusplus
#endif // _mpcdec_h_
#endif
#endif

View File

@ -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 <math.h>
#include <mpcdec/mpc_types.h>
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

64
Frameworks/MPCDec/Files/include/mpcdec/reader.h Normal file → Executable file
View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2005, The Musepack Development Team
Copyright (c) 2005-2009, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -31,52 +31,68 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file reader.h
#ifndef _MPCDEC_READER_H_
#define _MPCDEC_READER_H_
#ifdef WIN32
#pragma once
#endif
#include <mpcdec/mpc_types.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _mpcdec_reader_h_
#define _mpcdec_reader_h_
/// \brief Stream reader interface structure.
///
/// This is the structure you must supply to the musepack decoding library
/// to feed it with raw data. Implement the five member functions to provide
/// a functional reader.
typedef struct mpc_reader_t {
typedef struct mpc_reader_t mpc_reader;
struct mpc_reader_t {
/// Reads size bytes of data into buffer at ptr.
mpc_int32_t (*read)(void *t, void *ptr, mpc_int32_t size);
mpc_int32_t (*read)(mpc_reader *p_reader, void *ptr, mpc_int32_t size);
/// Seeks to byte position offset.
mpc_bool_t (*seek)(void *t, mpc_int32_t offset);
mpc_bool_t (*seek)(mpc_reader *p_reader, mpc_int32_t offset);
/// Returns the current byte offset in the stream.
mpc_int32_t (*tell)(void *t);
mpc_int32_t (*tell)(mpc_reader *p_reader);
/// Returns the total length of the source stream, in bytes.
mpc_int32_t (*get_size)(void *t);
mpc_int32_t (*get_size)(mpc_reader *p_reader);
/// True if the stream is a seekable stream.
mpc_bool_t (*canseek)(void *t);
mpc_bool_t (*canseek)(mpc_reader *p_reader);
/// Field that can be used to identify a particular instance of
/// reader or carry along data associated with that reader.
void *data;
} mpc_reader;
typedef struct mpc_reader_file_t {
mpc_reader reader;
FILE *file;
long file_size;
mpc_bool_t is_seekable;
} mpc_reader_file;
};
/// Initializes reader with default stdio file reader implementation. Use
/// this if you're just reading from a plain file.
///
/// \param r reader struct to initalize
/// \param input input stream to attach to the reader
void mpc_reader_setup_file_reader(mpc_reader_file *r, FILE *input);
/// \param r p_reader handle to initialize
/// \param filename input filename to attach to the reader
MPC_API mpc_status mpc_reader_init_stdio(mpc_reader *p_reader, const char *filename);
#endif // _mpcdec_reader_h_
/// Initializes reader with default stdio file reader implementation. Use
/// this if you prefer to open the file yourself.
///
/// \param r p_reader handle to initialize
/// \param p_file input file handle (already open)
MPC_API mpc_status mpc_reader_init_stdio_stream(mpc_reader * p_reader, FILE * p_file);
/// Release reader with default stdio file reader implementation.
///
/// \param r reader handle to release
MPC_API void mpc_reader_exit_stdio(mpc_reader *p_reader);
#ifdef __cplusplus
}
#endif
#endif

92
Frameworks/MPCDec/Files/include/mpcdec/streaminfo.h Normal file → Executable file
View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2005, The Musepack Development Team
Copyright (c) 2005-2009, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -31,11 +31,19 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file streaminfo.h
#ifndef _MPCDEC_STREAMINFO_H_
#define _MPCDEC_STREAMINFO_H_
#ifdef WIN32
#pragma once
#endif
#include <mpcdec/mpc_types.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _mpcdec_streaminfo_h_
#define _mpcdec_streaminfo_h_
typedef mpc_int32_t mpc_streaminfo_off_t;
@ -44,48 +52,58 @@ typedef mpc_int32_t mpc_streaminfo_off_t;
/// Structure containing all the properties of an mpc stream. Populated
/// by the streaminfo_read function.
typedef struct mpc_streaminfo {
/// @name core mpc stream properties
/// @name Core mpc stream properties
//@{
mpc_uint32_t sample_freq; ///< sample frequency of stream
mpc_uint32_t channels; ///< number of channels in stream
mpc_streaminfo_off_t header_position; ///< byte offset of position of header in stream
mpc_uint32_t stream_version; ///< streamversion of stream
mpc_uint32_t bitrate; ///< bitrate of stream file (in bps)
double average_bitrate; ///< average bitrate of stream (in bits/sec)
mpc_uint32_t frames; ///< number of frames in stream
mpc_int64_t pcm_samples;
mpc_uint32_t max_band; ///< maximum band-index used in stream (0...31)
mpc_uint32_t is; ///< intensity stereo (0: off, 1: on)
mpc_uint32_t ms; ///< mid/side stereo (0: off, 1: on)
mpc_uint32_t block_size; ///< only needed for SV4...SV6 -> not supported
mpc_uint32_t profile; ///< quality profile of stream
const char* profile_name; ///< name of profile used by stream
mpc_uint32_t sample_freq; ///< Sample frequency of stream
mpc_uint32_t channels; ///< Number of channels in stream
mpc_uint32_t stream_version; ///< Streamversion of stream
mpc_uint32_t bitrate; ///< Bitrate of stream file (in bps)
double average_bitrate; ///< Average bitrate of stream (in bits/sec)
mpc_uint32_t max_band; ///< Maximum band-index used in stream (0...31)
mpc_uint32_t ms; ///< Mid/side stereo (0: off, 1: on)
mpc_uint32_t fast_seek; ///< True if stream supports fast-seeking (sv7)
mpc_uint32_t block_pwr; ///< Number of frames in a block = 2^block_pwr (sv8)
//@}
/// @name replaygain related fields
/// @name Replaygain properties
//@{
mpc_int16_t gain_title; ///< replaygain title value
mpc_int16_t gain_album; ///< replaygain album value
mpc_uint16_t peak_album; ///< peak album loudness level
mpc_uint16_t peak_title; ///< peak title loudness level
mpc_uint16_t gain_title; ///< Replaygain title value
mpc_uint16_t gain_album; ///< Replaygain album value
mpc_uint16_t peak_album; ///< Peak album loudness level
mpc_uint16_t peak_title; ///< Peak title loudness level
//@}
/// @name true gapless support data
/// @name True gapless properties
//@{
mpc_uint32_t is_true_gapless; ///< true gapless? (0: no, 1: yes)
mpc_uint32_t last_frame_samples; ///< number of valid samples within last frame
mpc_uint32_t encoder_version; ///< version of encoder used
char encoder[256]; ///< encoder name
mpc_streaminfo_off_t tag_offset; ///< offset to file tags
mpc_streaminfo_off_t total_file_length; ///< total length of underlying file
mpc_uint32_t is_true_gapless; ///< True gapless? (0: no, 1: yes)
mpc_uint64_t samples; ///< Number of samples in the stream
mpc_uint64_t beg_silence; ///< Number of samples that must not be played at the beginning of the stream
//@}
/// @name fast seeking support
/// @name Encoder informations
//@{
mpc_uint32_t fast_seek; ///< support fast seeking ? (0: no, 1: yes)
//@}
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;
#endif // _mpcdec_streaminfo_h_
/// Gets length of stream si, in seconds.
/// \return length of stream in seconds
MPC_API double mpc_streaminfo_get_length(mpc_streaminfo *si);
/// Returns length of stream si, in samples.
/// \return length of stream in samples
MPC_API mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2005, The Musepack Development Team
Copyright (c) 2005-2009, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -31,62 +31,53 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file mpcdec_math.h
/// Libmpcdec internal math routines.
#ifndef _MPCDEC_MATH_H_
#define _MPCDEC_MATH_H_
#ifdef WIN32
#pragma once
#endif
/// \file math.h
/// Libmpcdec internal math routines.
#include <mpcdec/mpc_types.h>
#ifndef _mpcdec_math_h_
#define _mpcdec_math_h_
//#define MPC_FIXED_POINT
#define MPC_FIXED_POINT_SHIFT 16
#ifdef __cplusplus
extern "C" {
#endif
#ifdef MPC_FIXED_POINT
#ifdef _WIN32_WCE
#include <cmnintrin.h>
#define MPC_HAVE_MULHIGH
#endif
#define MPC_FIXED_POINT_SCALE_SHIFT (MPC_FIXED_POINT_SHIFT + MPC_FIXED_POINT_FRACTPART)
#define MPC_FIXED_POINT_SCALE (1 << (MPC_FIXED_POINT_SCALE_SHIFT - 1))
//in fixedpoint mode, results in decode output buffer are in -MPC_FIXED_POINT_SCALE ... MPC_FIXED_POINT_SCALE range
#define MPC_FIXED_POINT_FRACTPART 14
typedef mpc_int32_t MPC_SAMPLE_FORMAT;
typedef mpc_int64_t MPC_SAMPLE_FORMAT_MULTIPLY;
#define MAKE_MPC_SAMPLE(X) (MPC_SAMPLE_FORMAT)((double)(X) * (double)(((mpc_int64_t)1)<<MPC_FIXED_POINT_FRACTPART))
#define MAKE_MPC_SAMPLE_EX(X,Y) (MPC_SAMPLE_FORMAT)((double)(X) * (double)(((mpc_int64_t)1)<<(Y)))
#define MPC_MULTIPLY_NOTRUNCATE(X,Y) \
(((MPC_SAMPLE_FORMAT_MULTIPLY)(X) * (MPC_SAMPLE_FORMAT_MULTIPLY)(Y)) >> MPC_FIXED_POINT_FRACTPART)
(((MPC_SAMPLE_FORMAT_MULTIPLY)(X) * (MPC_SAMPLE_FORMAT_MULTIPLY)(Y)) >> MPC_FIXED_POINT_FRACTPART)
#define MPC_MULTIPLY_EX_NOTRUNCATE(X,Y,Z) \
(((MPC_SAMPLE_FORMAT_MULTIPLY)(X) * (MPC_SAMPLE_FORMAT_MULTIPLY)(Y)) >> (Z))
(((MPC_SAMPLE_FORMAT_MULTIPLY)(X) * (MPC_SAMPLE_FORMAT_MULTIPLY)(Y)) >> (Z))
#ifdef _DEBUG
static inline MPC_SAMPLE_FORMAT MPC_MULTIPLY(MPC_SAMPLE_FORMAT item1,MPC_SAMPLE_FORMAT item2)
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;
MPC_SAMPLE_FORMAT_MULTIPLY temp = MPC_MULTIPLY_NOTRUNCATE(item1,item2);
assert(temp == (MPC_SAMPLE_FORMAT_MULTIPLY)(MPC_SAMPLE_FORMAT)temp);
return (MPC_SAMPLE_FORMAT)temp;
}
static inline MPC_SAMPLE_FORMAT MPC_MULTIPLY_EX(MPC_SAMPLE_FORMAT item1,MPC_SAMPLE_FORMAT item2,unsigned shift)
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;
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
@ -118,8 +109,6 @@ static inline MPC_SAMPLE_FORMAT MPC_MULTIPLY_EX(MPC_SAMPLE_FORMAT item1,MPC_SAMP
//in floating-point mode, decoded samples are in -1...1 range
typedef float MPC_SAMPLE_FORMAT;
#define MAKE_MPC_SAMPLE(X) ((MPC_SAMPLE_FORMAT)(X))
#define MAKE_MPC_SAMPLE_EX(X,Y) ((MPC_SAMPLE_FORMAT)(X))
@ -140,5 +129,7 @@ typedef float MPC_SAMPLE_FORMAT;
#endif
#endif // _mpcdec_math_h_
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2005, The Musepack Development Team
Copyright (c) 2005-2009, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -31,21 +31,31 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file requant.h
/// Requantization function definitions.
#ifndef _MPCDEC_REQUANT_H_
#define _MPCDEC_REQUANT_H_
#ifdef WIN32
#pragma once
#endif
#ifndef _mpcdec_requant_h
#define _mpcdec_requant_h_
#include <mpcdec/mpc_types.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "mpcdec.h"
/* C O N S T A N T S */
extern const mpc_uint32_t Res_bit [18]; // bits per sample for chosen quantizer
extern const MPC_SAMPLE_FORMAT __Cc [1 + 18]; // coefficients for requantization
extern const mpc_int32_t __Dc [1 + 18]; // offset for requantization
const mpc_uint8_t Res_bit [18]; ///< Bits per sample for chosen quantizer
const MPC_SAMPLE_FORMAT __Cc [1 + 18]; ///< Requantization coefficients
const mpc_int16_t __Dc [1 + 18]; ///< Requantization offset
#define Cc (__Cc + 1)
#define Dc (__Dc + 1)
#define Cc (__Cc + 1)
#define Dc (__Dc + 1)
#endif // _mpcdec_requant_h_
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,56 @@
/*
* C Implementation: crc32
*
* code from http://www.w3.org/TR/PNG/#D-CRCAppendix
*
*/
/* Table of CRCs of all 8-bit messages. */
static unsigned long crc_table[256];
/* Flag: has the table been computed? Initially false. */
static int crc_table_computed = 0;
/* Make the table for a fast CRC. */
static void make_crc_table(void)
{
unsigned long c;
int n, k;
for (n = 0; n < 256; n++) {
c = (unsigned long) n;
for (k = 0; k < 8; k++) {
if (c & 1)
c = 0xedb88320L ^ (c >> 1);
else
c = c >> 1;
}
crc_table[n] = c;
}
crc_table_computed = 1;
}
/* Update a running CRC with the bytes buf[0..len-1]--the CRC
should be initialized to all 1's, and the transmitted value
is the 1's complement of the final running CRC (see the
crc() routine below). */
static unsigned long update_crc(unsigned long crc, unsigned char *buf, int len)
{
unsigned long c = crc;
int n;
if (!crc_table_computed)
make_crc_table();
for (n = 0; n < len; n++) {
c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
}
return c;
}
/* Return the CRC of the bytes buf[0..len-1]. */
unsigned long mpc_crc32(unsigned char *buf, int len)
{
return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;
}

View File

@ -0,0 +1,77 @@
/*
* 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
*/
#include "mpcdec/mpcmath.h"
#ifdef FAST_MATH
const float tabatan2 [ 2*TABSTEP+1] [2];
const float tabcos [26*TABSTEP+1] [2];
const float tabsqrt_ex [256];
const float tabsqrt_m [ TABSTEP+1] [2];
void Init_FastMath ( void )
{
int i; mpc_floatint X, Y; double xm, x0, xp, x, y; float* p;
p = (float*) tabatan2;
for ( i = -TABSTEP; i <= TABSTEP; i++ ) {
xm = atan ((i-0.5)/TABSTEP);
x0 = atan ((i+0.0)/TABSTEP);
xp = atan ((i+0.5)/TABSTEP);
x = x0/2 + (xm + xp)/4;
y = xp - xm;
*p++ = x;
*p++ = y;
}
p = (float*) tabcos;
for ( i = -13*TABSTEP; i <= 13*TABSTEP; i++ ) {
xm = cos ((i-0.5)/TABSTEP);
x0 = cos ((i+0.0)/TABSTEP);
xp = cos ((i+0.5)/TABSTEP);
x = x0/2 + (xm + xp)/4;
y = xp - xm;
*p++ = x;
*p++ = y;
}
p = (float*) tabsqrt_ex;
for ( i = 0; i < 255; i++ ) {
X.n = (i << 23);
Y.n = (i << 23) + (1<<23) - 1;
*p++ = sqrt(X.f);
}
X.n = (255 << 23) - 1;
*p++ = sqrt(X.f);
p = (float*) tabsqrt_m;
for ( i = 1*TABSTEP; i <= 2*TABSTEP; i++ ) {
xm = sqrt ((i-0.5)/TABSTEP);
x0 = sqrt ((i+0.0)/TABSTEP);
xp = sqrt ((i+0.5)/TABSTEP);
x = x0/2 + (xm + xp)/4;
y = xp - xm;
*p++ = x;
*p++ = y;
}
}
#endif

View File

@ -0,0 +1,280 @@
/*************************************************************************
* Huffman codes generation, part of the code from the Basic Compression
* Library ( http://bcl.sourceforge.net )
*
* Modified by Nicolas BOTTI rududu at laposte.net
*
*-------------------------------------------------------------------------
* Copyright (c) 2003-2006 Marcus Geelnard
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would
* be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
* Marcus Geelnard
* marcus.geelnard at home.se
*************************************************************************/
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int Symbol;
unsigned int Count;
unsigned int Code;
unsigned int Bits;
} huff_sym_t;
typedef struct huff_node huff_node_t;
struct huff_node {
huff_node_t * ChildA;
union {
huff_node_t * ChildB;
huff_sym_t * Symbol;
};
int Count;
};
static void _Huffman_StoreTree( huff_node_t *node, unsigned int bits )
{
/* Is this a leaf node? */
if( node->ChildA == 0 ) {
/* Store code info in symbol array */
node->Symbol->Bits = bits;
return;
}
/* Branch A */
_Huffman_StoreTree( node->ChildA, bits+1 );
/* Branch B */
_Huffman_StoreTree( node->ChildB, bits+1 );
}
/**
* Compare 2 symbols to sort as canonical huffman (more bits first)
* @param sym1
* @param sym2
* @return
*/
static int _Huffman_CompBits(const huff_sym_t * sym1, const huff_sym_t * sym2)
{
if (sym1->Bits == sym2->Bits){
if (sym1->Symbol == sym2->Symbol)
return 0;
else
return ((sym1->Symbol > sym2->Symbol) << 1) - 1;
} else
return ((sym1->Bits < sym2->Bits) << 1) - 1;
}
/**
* Compare 2 symbols to sort in symbol order
* @param sym1
* @param sym2
* @return
*/
static int _Huffman_CompSym(const huff_sym_t * sym1, const huff_sym_t * sym2)
{
return ((sym1->Symbol > sym2->Symbol) << 1) - 1;
}
/**
* Generate canonical huffman codes from symbols and bit lengths
* @param sym
* @param num_symbols
*/
static void _Huffman_MakeCodes(huff_sym_t * sym, unsigned int num_symbols)
{
unsigned int code = 0, i;
int bits;
qsort(sym, num_symbols, sizeof(huff_sym_t),
(int (*)(const void *, const void *)) _Huffman_CompBits);
bits = sym[0].Bits;
sym[0].Code = 0;
for( i = 1; i < num_symbols; i++){
code >>= bits - sym[i].Bits;
bits = sym[i].Bits;
code++;
sym[i].Code = code;
}
}
/**
* Make a canonical huffman tree from symbols and counts
* @param sym
* @param num_symbols
*/
void _Huffman_MakeTree( huff_sym_t * sym, unsigned int num_symbols)
{
huff_node_t * nodes, * node_1, * node_2, * root;
unsigned int k, nodes_left, next_idx;
nodes = malloc(sizeof(huff_node_t) * (num_symbols * 2 - 1));
/* Initialize all leaf nodes */
for( k = 0; k < num_symbols; ++ k ) {
nodes[k].Symbol = & sym[k];
nodes[k].Count = sym[k].Count;
nodes[k].ChildA = (huff_node_t *) 0;
}
/* Build tree by joining the lightest nodes until there is only
one node left (the root node). */
root = (huff_node_t *) 0;
nodes_left = num_symbols;
next_idx = num_symbols;
while( nodes_left > 1 ) {
/* Find the two lightest nodes */
node_1 = (huff_node_t *) 0;
node_2 = (huff_node_t *) 0;
for( k = 0; k < next_idx; ++ k ) {
if( nodes[k].Count >= 0 ) {
if( !node_1 || (nodes[k].Count <= node_1->Count) ) {
node_2 = node_1;
node_1 = &nodes[k];
} else if( !node_2 || (nodes[k].Count <= node_2->Count) )
node_2 = &nodes[k];
}
}
/* Join the two nodes into a new parent node */
root = &nodes[next_idx];
root->ChildA = node_1;
root->ChildB = node_2;
root->Count = node_1->Count + node_2->Count;
node_1->Count = -1;
node_2->Count = -1;
++ next_idx;
-- nodes_left;
}
/* Store the tree in the output stream, and in the sym[] array (the
latter is used as a look-up-table for faster encoding) */
if( root ) {
_Huffman_StoreTree( root, 0 );
} else {
/* Special case: only one symbol => no binary tree */
root = &nodes[0];
_Huffman_StoreTree( root, 1 );
}
free(nodes);
_Huffman_MakeCodes(sym, num_symbols);
}
#ifdef __GNUC__
/**
* Print the huffman tables
* print_type = 0 => print the coding table
* print_type = 1 => print the decoding table
* print_type = 2 => print the full codes in symbols order
* print_type = 3 => print the full codes in codes order
* @param sym
* @param num_symbols
* @param print_type
* @param offset
*/
void _Huffman_PrintCodes(huff_sym_t * sym, unsigned int num_symbols, int print_type, int offset)
{
unsigned int total_cnt = 0, total_size = 0, optim_size = 0, i;
int packs[4];
switch( print_type ) {
case 0 :
qsort(sym, num_symbols, sizeof(huff_sym_t),
(int (*)(const void *, const void *)) _Huffman_CompSym);
printf("{\n ");
for( i = 0; i < num_symbols; i++) {
if (i != 0)
printf(", ");
printf("{%u, %u}", sym[i].Code, sym[i].Bits);
}
printf("\n}\n");
break;
case 1:
qsort(sym, num_symbols, sizeof(huff_sym_t),
(int (*)(const void *, const void *)) _Huffman_CompBits);
printf("{\n ");
for( i = num_symbols - 1; i >= 0; i--) {
printf("{0x%.8x, %u, %i}", sym[i].Code << (32 - sym[i].Bits), sym[i].Bits, sym[i].Symbol - offset);
if (i != 0)
printf(", ");
}
printf("\n}\n");
break;
case 4:
qsort(sym, num_symbols, sizeof(huff_sym_t),
(int (*)(const void *, const void *)) _Huffman_CompBits);
printf("{\n ");
for( i = num_symbols - 1; i >= 0; i--) {
int symbol = sym[i].Symbol;
packs[3] = symbol / (offset * offset * offset);
packs[2] = (symbol - packs[3] * offset * offset * offset) / (offset * offset);
packs[1] = (symbol - (packs[3] * offset + packs[2]) * offset * offset) / offset;
packs[0] = symbol - ((packs[3] * offset + packs[2]) * offset + packs[1] * offset);
packs[0] -= offset >> 1;
packs[1] -= offset >> 1;
packs[2] -= offset >> 1;
packs[3] -= offset >> 1;
symbol = ((packs[3] & 15) << 12) | ((packs[2] & 15) << 8) | ((packs[1] & 15) << 4) | (packs[0] & 15);
printf("{0x%.8x, %u, %i}", sym[i].Code << (32 - sym[i].Bits), sym[i].Bits, symbol);
if (i != 0)
printf(", ");
}
printf("\n}\n");
break;
default:
if (print_type == 2)
qsort(sym, num_symbols, sizeof(huff_sym_t),
(int (*)(const void *, const void *)) _Huffman_CompSym);
else
qsort(sym, num_symbols, sizeof(huff_sym_t),
(int (*)(const void *, const void *)) _Huffman_CompBits);
printf("Symbol Count Lenth Code\n");
for( i = 0; i < num_symbols; i++) {
int k = sym[i].Bits - 1;
printf("%-10i %-10u %-10u ", sym[i].Symbol - offset, sym[i].Count, sym[i].Bits);
for (; k >= 0 ; k--)
printf("%u", (sym[i].Code >> k) & 1 );
printf("\n");
total_cnt += sym[i].Count;
total_size += sym[i].Count * sym[i].Bits;
if (sym[i].Count != 0)
optim_size += sym[i].Count * __builtin_log2(sym[i].Count);
}
optim_size = total_cnt * __builtin_log2(total_cnt) - optim_size;
printf("\ncount : %u huff : %f bps ", 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);
break;
}
}
#endif

View File

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

View File

@ -1,75 +0,0 @@
/*
Copyright (c) 2005, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the The Musepack Development Team nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file huffsv46.c
/// Implementations of huffman decoding for streamversions < 7.
#include <mpcdec/mpcdec.h>
#include <mpcdec/requant.h>
#include <mpcdec/huffman.h>
#ifdef MPC_SUPPORT_SV456
const HuffmanTyp mpc_table_SCFI_Bundle [ 8] =
{{2147483648u,1,7},{1073741824u,2,3},{939524096u,5,1},{805306368u,5,2},{738197504u,6,0},{671088640u,6,6},{536870912u,5,4},{0u,3,5},};
const HuffmanTyp mpc_table_DSCF_Entropie [13] =
{{3758096384u,3,1},{3489660928u,4,3},{3355443200u,5,5},{3221225472u,5,-3},{2952790016u,4,-2},{2684354560u,4,4},{2147483648u,3,-1},{1610612736u,3,2},{1476395008u,5,-5},{1409286144u,6,6},{1342177280u,6,-6},{1073741824u,4,-4},{0u,2,0},};
const HuffmanTyp mpc_table_Region_A [16] =
{{2147483648u,1,1},{2013265920u,5,3},{1946157056u,6,4},{1912602624u,7,7},{1895825408u,8,8},{1887436800u,9,9},{1883242496u,10,10},{1881145344u,11,11},{1880096768u,12,12},{1879572480u,13,13},{1879310336u,14,14},{1879048192u,14,15},{1744830464u,5,5},{1610612736u,5,6},{1073741824u,3,0},{0u,2,2},};
const HuffmanTyp mpc_table_Region_B [ 8] =
{{2147483648u,1,1},{1073741824u,2,0},{536870912u,3,2},{268435456u,4,3},{134217728u,5,4},{67108864u,6,5},{33554432u,7,6},{0u,7,7},};
const HuffmanTyp mpc_table_Region_C [ 4] =
{{2147483648u,1,0},{1073741824u,2,1},{536870912u,3,2},{0u,3,3},};
static const HuffmanTyp mpc_table_Entropie_1 [ 3] =
{{2147483648u,1,0},{1073741824u,2,-1},{0u,2,1},};
static const HuffmanTyp mpc_table_Entropie_2 [ 5] =
{{3221225472u,2,0},{2684354560u,3,2},{2147483648u,3,-2},{1073741824u,2,1},{0u,2,-1},};
static const HuffmanTyp mpc_table_Entropie_3 [ 7] =
{{3221225472u,2,0},{2684354560u,3,-2},{2415919104u,4,2},{2281701376u,5,-3},{2147483648u,5,3},{1073741824u,2,-1},{0u,2,1},};
static const HuffmanTyp mpc_table_Entropie_4 [ 9] =
{{4026531840u,4,3},{3758096384u,4,-3},{3221225472u,3,1},{2684354560u,3,-1},{2147483648u,3,2},{1610612736u,3,-2},{1342177280u,4,-4},{1073741824u,4,4},{0u,2,0},};
static const HuffmanTyp mpc_table_Entropie_5 [15] =
{{4026531840u,4,-2},{3892314112u,5,-5},{3825205248u,6,-7},{3758096384u,6,7},{3489660928u,4,-3},{3221225472u,4,3},{3087007744u,5,-6},{2952790016u,5,6},{2684354560u,4,4},{2147483648u,3,0},{1610612736u,3,1},{1073741824u,3,-1},{805306368u,4,-4},{536870912u,4,5},{0u,3,2},};
static const HuffmanTyp mpc_table_Entropie_6 [31] =
{{4160749568u,5,-4},{4026531840u,5,5},{3892314112u,5,-5},{3825205248u,6,10},{3758096384u,6,-10},{3623878656u,5,-6},{3489660928u,5,6},{3355443200u,5,7},{3221225472u,5,-7},{3087007744u,5,-8},{3019898880u,6,-11},{2986344448u,7,14},{2952790016u,7,-14},{2818572288u,5,8},{2751463424u,6,11},{2684354560u,6,-13},{2415919104u,4,0},{2147483648u,4,1},{1879048192u,4,-1},{1610612736u,4,3},{1342177280u,4,2},{1207959552u,5,-9},{1140850688u,6,12},{1073741824u,6,13},{805306368u,4,-3},{536870912u,4,-2},{402653184u,5,9},{335544320u,6,-12},{301989888u,7,15},{268435456u,7,-15},{0u,4,4},};
static const HuffmanTyp mpc_table_Entropie_7 [63] =
{{4278190080u,8,28},{4261412864u,8,26},{4227858432u,7,-20},{4160749568u,6,8},{4093640704u,6,-8},{4026531840u,6,-9},{3959422976u,6,9},{3925868544u,7,20},{3892314112u,7,21},{3825205248u,6,-10},{3758096384u,6,-11},{3690987520u,6,10},{3623878656u,6,11},{3590324224u,7,-21},{3573547008u,8,29},{3556769792u,8,-29},{3489660928u,6,13},{3422552064u,6,-13},{3355443200u,6,-12},{3288334336u,6,12},{3254779904u,7,-22},{3221225472u,7,22},{3154116608u,6,14},{3087007744u,6,15},{3019898880u,6,-14},{2986344448u,7,-23},{2952790016u,7,23},{2885681152u,6,-15},{2818572288u,6,-16},{2751463424u,6,16},{2717908992u,7,27},{2684354560u,7,-27},{2617245696u,6,17},{2550136832u,6,-17},{2533359616u,8,-30},{2516582400u,8,30},{2483027968u,7,24},{2415919104u,6,-18},{2281701376u,5,-1},{2147483648u,5,1},{2113929216u,7,-24},{2080374784u,7,25},{2013265920u,6,18},{1879048192u,5,-3},{1744830464u,5,3},{1610612736u,5,5},{1476395008u,5,0},{1342177280u,5,-2},{1275068416u,6,19},{1207959552u,6,-19},{1073741824u,5,-5},{939524096u,5,-4},{805306368u,5,-7},{671088640u,5,2},{536870912u,5,4},{402653184u,5,7},{369098752u,7,-25},{335544320u,7,-26},{301989888u,7,-28},{285212672u,8,-31},{268435456u,8,31},{134217728u,5,6},{0u,5,-6},};
const HuffmanTyp* mpc_table_SampleHuff [18] = {
NULL,mpc_table_Entropie_1,mpc_table_Entropie_2,mpc_table_Entropie_3,mpc_table_Entropie_4,mpc_table_Entropie_5,mpc_table_Entropie_6,mpc_table_Entropie_7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
};
#endif //#ifdef MPC_SUPPORT_SV456

View File

@ -1,81 +0,0 @@
/*
Copyright (c) 2005, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the The Musepack Development Team nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file huffsv7.c
/// Implementations of sv7 huffman decoding functions.
#include <mpcdec/mpcdec.h>
#include <mpcdec/huffman.h>
#include <mpcdec/requant.h>
const HuffmanTyp mpc_table_HuffHdr [10] =
{{2147483648u,1,0},{1610612736u,3,1},{1577058304u,7,-4},{1568669696u,9,3},{1560281088u,9,4},{1543503872u,8,-5},{1476395008u,6,2},{1342177280u,5,-3},{1073741824u,4,-2},{0u,2,-1},};
const HuffmanTyp mpc_table_HuffSCFI [ 4] =
{{2147483648u,1,1},{1610612736u,3,2},{1073741824u,3,0},{0u,2,3},};
const HuffmanTyp mpc_table_HuffDSCF [16] =
{{4160749568u,5,5},{4026531840u,5,-4},{3758096384u,4,3},{3489660928u,4,-3},{3221225472u,4,8},{2684354560u,3,1},{2415919104u,4,0},{2281701376u,5,-5},{2214592512u,6,7},{2147483648u,6,-7},{1610612736u,3,-1},{1073741824u,3,2},{805306368u,4,4},{671088640u,5,6},{536870912u,5,-6},{0u,3,-2},};
static const HuffmanTyp mpc_table_HuffQ1 [2] [3*3*3] = {
{{3758096384u,3,13},{3690987520u,6,26},{3623878656u,6,0},{3556769792u,6,20},{3489660928u,6,6},{3221225472u,4,14},{2952790016u,4,12},{2684354560u,4,4},{2415919104u,4,22},{2348810240u,6,8},{2281701376u,6,18},{2214592512u,6,24},{2147483648u,6,2},{1879048192u,4,16},{1610612736u,4,10},{1476395008u,5,17},{1342177280u,5,9},{1207959552u,5,1},{1073741824u,5,25},{939524096u,5,5},{805306368u,5,21},{671088640u,5,3},{536870912u,5,11},{402653184u,5,15},{268435456u,5,23},{134217728u,5,19},{0u,5,7},},
{{2147483648u,1,13},{2113929216u,7,15},{2080374784u,7,1},{2046820352u,7,11},{2013265920u,7,7},{1979711488u,7,17},{1946157056u,7,25},{1912602624u,7,19},{1904214016u,9,8},{1895825408u,9,18},{1887436800u,9,2},{1879048192u,9,24},{1845493760u,7,3},{1811939328u,7,23},{1778384896u,7,21},{1744830464u,7,5},{1728053248u,8,0},{1711276032u,8,26},{1694498816u,8,6},{1677721600u,8,20},{1610612736u,6,9},{1342177280u,4,14},{1073741824u,4,12},{805306368u,4,4},{536870912u,4,22},{268435456u,4,16},{0u,4,10},},
};
static const HuffmanTyp mpc_table_HuffQ2 [2] [5*5] = {
{{4026531840u,4,13},{3758096384u,4,17},{3489660928u,4,7},{3221225472u,4,11},{3154116608u,6,1},{3087007744u,6,23},{3053453312u,7,4},{3019898880u,7,20},{2986344448u,7,0},{2952790016u,7,24},{2818572288u,5,22},{2684354560u,5,10},{2147483648u,3,12},{2013265920u,5,2},{1879048192u,5,14},{1610612736u,4,6},{1342177280u,4,18},{1073741824u,4,8},{805306368u,4,16},{671088640u,5,9},{536870912u,5,5},{402653184u,5,15},{268435456u,5,21},{134217728u,5,19},{0u,5,3},},
{{4160749568u,5,18},{4026531840u,5,6},{3892314112u,5,8},{3875536896u,8,3},{3871342592u,10,24},{3867148288u,10,4},{3862953984u,10,0},{3858759680u,10,20},{3825205248u,7,23},{3791650816u,7,1},{3758096384u,7,19},{3623878656u,5,16},{3590324224u,7,15},{3556769792u,7,21},{3523215360u,7,9},{3489660928u,7,5},{3422552064u,6,2},{3355443200u,6,10},{3288334336u,6,14},{3221225472u,6,22},{2147483648u,2,12},{1610612736u,3,13},{1073741824u,3,17},{536870912u,3,11},{0u,3,7},},
};
static const HuffmanTyp mpc_table_HuffQ3 [2] [ 7] = {
{{3758096384u,3,1},{3489660928u,4,3},{3221225472u,4,-3},{2684354560u,3,2},{2147483648u,3,-2},{1073741824u,2,0},{0u,2,-1},},
{{3221225472u,2,0},{2147483648u,2,-1},{1073741824u,2,1},{805306368u,4,-2},{671088640u,5,3},{536870912u,5,-3},{0u,3,2},},
};
static const HuffmanTyp mpc_table_HuffQ4 [2] [ 9] = {
{{3758096384u,3,0},{3221225472u,3,-1},{2684354560u,3,1},{2147483648u,3,-2},{1610612736u,3,2},{1342177280u,4,-4},{1073741824u,4,4},{536870912u,3,3},{0u,3,-3},},
{{3758096384u,3,1},{3489660928u,4,2},{3221225472u,4,-3},{2147483648u,2,0},{1610612736u,3,-2},{1342177280u,4,3},{1207959552u,5,-4},{1073741824u,5,4},{0u,2,-1},},
};
static const HuffmanTyp mpc_table_HuffQ5 [2] [15] = {
{{4026531840u,4,2},{3892314112u,5,5},{3825205248u,6,-7},{3758096384u,6,7},{3489660928u,4,-3},{3221225472u,4,3},{3087007744u,5,-6},{2952790016u,5,6},{2684354560u,4,-4},{2415919104u,4,4},{2147483648u,4,-5},{1610612736u,3,0},{1073741824u,3,-1},{536870912u,3,1},{0u,3,-2},},
{{4026531840u,4,3},{3892314112u,5,4},{3858759680u,7,6},{3841982464u,8,-7},{3825205248u,8,7},{3758096384u,6,-6},{3221225472u,3,0},{2684354560u,3,-1},{2147483648u,3,1},{1610612736u,3,-2},{1073741824u,3,2},{939524096u,5,-5},{805306368u,5,5},{536870912u,4,-4},{0u,3,-3},},
};
static const HuffmanTyp mpc_table_HuffQ6 [2] [31] = {
{{4160749568u,5,3},{4026531840u,5,-4},{3959422976u,6,-11},{3892314112u,6,12},{3758096384u,5,4},{3623878656u,5,6},{3489660928u,5,-5},{3355443200u,5,5},{3221225472u,5,7},{3087007744u,5,-7},{3019898880u,6,-12},{2952790016u,6,-13},{2818572288u,5,-6},{2684354560u,5,8},{2550136832u,5,-8},{2415919104u,5,9},{2281701376u,5,-9},{2214592512u,6,13},{2181038080u,7,-15},{2147483648u,7,15},{1879048192u,4,0},{1744830464u,5,-10},{1610612736u,5,10},{1342177280u,4,-1},{1073741824u,4,2},{805306368u,4,1},{536870912u,4,-2},{469762048u,6,14},{402653184u,6,-14},{268435456u,5,11},{0u,4,-3},},
{{4160749568u,5,-6},{4026531840u,5,6},{3758096384u,4,1},{3489660928u,4,-1},{3456106496u,7,10},{3422552064u,7,-10},{3405774848u,8,-11},{3397386240u,9,-12},{3395289088u,11,13},{3394764800u,13,15},{3394240512u,13,-14},{3393716224u,13,14},{3393191936u,13,-15},{3388997632u,10,-13},{3372220416u,8,11},{3355443200u,8,12},{3288334336u,6,-9},{3221225472u,6,9},{2952790016u,4,-2},{2684354560u,4,2},{2415919104u,4,3},{2147483648u,4,-3},{2013265920u,5,-7},{1879048192u,5,7},{1610612736u,4,-4},{1342177280u,4,4},{1207959552u,5,-8},{1073741824u,5,8},{805306368u,4,5},{536870912u,4,-5},{0u,3,0},},
};
static const HuffmanTyp mpc_table_HuffQ7 [2] [63] = {
{{4227858432u,6,7},{4160749568u,6,8},{4093640704u,6,9},{4026531840u,6,-8},{3959422976u,6,11},{3925868544u,7,21},{3909091328u,8,-28},{3892314112u,8,28},{3825205248u,6,-9},{3791650816u,7,-22},{3758096384u,7,-21},{3690987520u,6,-10},{3623878656u,6,-11},{3556769792u,6,10},{3489660928u,6,12},{3422552064u,6,-13},{3388997632u,7,22},{3355443200u,7,23},{3288334336u,6,-12},{3221225472u,6,13},{3154116608u,6,14},{3087007744u,6,-14},{3053453312u,7,-23},{3036676096u,8,-29},{3019898880u,8,29},{2952790016u,6,-15},{2885681152u,6,15},{2818572288u,6,16},{2751463424u,6,-16},{2717908992u,7,-24},{2684354560u,7,24},{2617245696u,6,17},{2583691264u,7,-25},{2566914048u,8,-30},{2550136832u,8,30},{2483027968u,6,-17},{2415919104u,6,18},{2348810240u,6,-18},{2315255808u,7,25},{2281701376u,7,26},{2214592512u,6,19},{2181038080u,7,-26},{2147483648u,7,-27},{2013265920u,5,2},{1946157056u,6,-19},{1879048192u,6,20},{1744830464u,5,-1},{1728053248u,8,-31},{1711276032u,8,31},{1677721600u,7,27},{1610612736u,6,-20},{1476395008u,5,1},{1342177280u,5,-5},{1207959552u,5,-3},{1073741824u,5,3},{939524096u,5,0},{805306368u,5,-2},{671088640u,5,-4},{536870912u,5,4},{402653184u,5,5},{268435456u,5,-6},{134217728u,5,6},{0u,5,-7},},
{{4160749568u,5,-1},{4026531840u,5,2},{3892314112u,5,-2},{3758096384u,5,3},{3741319168u,8,-20},{3737124864u,10,24},{3736862720u,14,28},{3736600576u,14,-28},{3736338432u,14,-30},{3736076288u,14,30},{3735027712u,12,-27},{3734765568u,14,29},{3734503424u,14,-29},{3734241280u,14,31},{3733979136u,14,-31},{3732930560u,12,27},{3724541952u,9,-22},{3690987520u,7,-17},{3623878656u,6,-11},{3489660928u,5,-3},{3355443200u,5,4},{3221225472u,5,-4},{3187671040u,7,17},{3170893824u,8,20},{3162505216u,9,22},{3158310912u,10,-25},{3154116608u,10,-26},{3087007744u,6,12},{2952790016u,5,5},{2818572288u,5,-5},{2684354560u,5,6},{2550136832u,5,-6},{2483027968u,6,-12},{2449473536u,7,-18},{2415919104u,7,18},{2348810240u,6,13},{2281701376u,6,-13},{2147483648u,5,-7},{2080374784u,6,14},{2063597568u,8,21},{2046820352u,8,-21},{2013265920u,7,-19},{1879048192u,5,7},{1744830464u,5,8},{1677721600u,6,-14},{1610612736u,6,-15},{1476395008u,5,-8},{1409286144u,6,15},{1375731712u,7,19},{1371537408u,10,25},{1367343104u,10,26},{1358954496u,9,-23},{1350565888u,9,23},{1342177280u,9,-24},{1207959552u,5,-9},{1073741824u,5,9},{1006632960u,6,16},{939524096u,6,-16},{805306368u,5,10},{536870912u,4,0},{402653184u,5,-10},{268435456u,5,11},{0u,4,1},},
};
const HuffmanTyp* mpc_table_HuffQ [2] [8] = {
{0,mpc_table_HuffQ1[0],mpc_table_HuffQ2[0],mpc_table_HuffQ3[0],mpc_table_HuffQ4[0],mpc_table_HuffQ5[0],mpc_table_HuffQ6[0],mpc_table_HuffQ7[0]},
{0,mpc_table_HuffQ1[1],mpc_table_HuffQ2[1],mpc_table_HuffQ3[1],mpc_table_HuffQ4[1],mpc_table_HuffQ5[1],mpc_table_HuffQ6[1],mpc_table_HuffQ7[1]},
};

View File

@ -1,83 +0,0 @@
/*
Copyright (c) 2005, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the The Musepack Development Team nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file idtag.c
/// Rudimentary id3tag handling routines, just enough to skip id3v2 tags,
/// if present.
#include <mpcdec/mpcdec.h>
#include <mpcdec/internal.h>
mpc_int32_t
JumpID3v2 (mpc_reader* r) {
unsigned char tmp [10];
mpc_uint32_t Unsynchronisation; // ID3v2.4-flag
mpc_uint32_t ExtHeaderPresent; // ID3v2.4-flag
mpc_uint32_t ExperimentalFlag; // ID3v2.4-flag
mpc_uint32_t FooterPresent; // ID3v2.4-flag
mpc_int32_t ret;
// seek to first byte of mpc data
if (!r->seek (r->data, 0)) {
return 0;
}
r->read(r->data, tmp, sizeof(tmp));
// check id3-tag
if ( 0 != memcmp ( tmp, "ID3", 3) )
return 0;
// read flags
Unsynchronisation = tmp[5] & 0x80;
ExtHeaderPresent = tmp[5] & 0x40;
ExperimentalFlag = tmp[5] & 0x20;
FooterPresent = tmp[5] & 0x10;
if ( tmp[5] & 0x0F )
return -1; // not (yet???) allowed
if ( (tmp[6] | tmp[7] | tmp[8] | tmp[9]) & 0x80 )
return -1; // not allowed
// read HeaderSize (syncsave: 4 * $0xxxxxxx = 28 significant bits)
ret = tmp[6] << 21;
ret += tmp[7] << 14;
ret += tmp[8] << 7;
ret += tmp[9] ;
ret += 10;
if ( FooterPresent )
ret += 10;
return ret;
}

View File

@ -0,0 +1,181 @@
/*
Copyright (c) 2007-2009, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the The Musepack Development Team nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <mpcdec/mpcdec.h>
#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;
}

1470
Frameworks/MPCDec/Files/src/mpc_decoder.c Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@ -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 <math.h>
#include <string.h>
#include <mpcdec/streaminfo.h>
#include <mpcdec/mpcdec.h>
#include <mpcdec/minimax.h>
#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);
}

118
Frameworks/MPCDec/Files/src/mpc_reader.c Normal file → Executable file
View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2005, The Musepack Development Team
Copyright (c) 2005-2009, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -31,66 +31,114 @@
(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 <mpcdec/reader.h>
#include "internal.h"
#include <stdio.h>
#include <mpcdec/mpcdec.h>
#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_impl(void *data, void *ptr, mpc_int32_t size)
read_stdio(mpc_reader *p_reader, void *ptr, mpc_int32_t size)
{
mpc_reader_file *d = (mpc_reader_file *) data;
return (mpc_int32_t) fread(ptr, 1, size, d->file);
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_impl(void *data, mpc_int32_t offset)
seek_stdio(mpc_reader *p_reader, mpc_int32_t offset)
{
mpc_reader_file *d = (mpc_reader_file *) data;
return d->is_seekable ? fseek(d->file, offset, SEEK_SET) == 0 : FALSE;
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_impl(void *data)
tell_stdio(mpc_reader *p_reader)
{
mpc_reader_file *d = (mpc_reader_file *) data;
return ftell(d->file);
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_impl(void *data)
get_size_stdio(mpc_reader *p_reader)
{
mpc_reader_file *d = (mpc_reader_file *) data;
return d->file_size;
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_impl(void *data)
canseek_stdio(mpc_reader *p_reader)
{
mpc_reader_file *d = (mpc_reader_file *) data;
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;
}
return d->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_setup_file_reader(mpc_reader_file *p_reader, FILE *input)
mpc_reader_exit_stdio(mpc_reader *p_reader)
{
p_reader->reader.seek = seek_impl;
p_reader->reader.read = read_impl;
p_reader->reader.tell = tell_impl;
p_reader->reader.get_size = get_size_impl;
p_reader->reader.canseek = canseek_impl;
p_reader->reader.data = p_reader; // point back to ourselves
p_reader->file = input;
p_reader->is_seekable = TRUE;
fseek(input, 0, SEEK_END);
p_reader->file_size = ftell(input);
fseek(input, 0, SEEK_SET);
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;
}

72
Frameworks/MPCDec/Files/src/requant.c Normal file → Executable file
View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2005, The Musepack Development Team
Copyright (c) 2005-2009, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -31,39 +31,40 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file requant.c
/// Requantization function implementations.
/// \todo document me
#include <mpcdec/mpcdec.h>
#include <mpcdec/internal.h>
#include "requant.h"
#include "mpcdec_math.h"
#include "decoder.h"
/* C O N S T A N T S */
// bits per sample for chosen quantizer
const mpc_uint32_t Res_bit [18] = {
// 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
};
// coefficients for requantization
// Requantization coefficients
// 65536/step bzw. 65536/(2*D+1)
#define _(X) MAKE_MPC_SAMPLE_EX(X,14)
const MPC_SAMPLE_FORMAT __Cc [1 + 18] = {
_(111.285962475327f), // 32768/2/255*sqrt(3)
_(111.285962475327f), // 32768/2/255*sqrt(3)
_(65536.000000000000f), _(21845.333333333332f), _(13107.200000000001f), _(9362.285714285713f),
_(7281.777777777777f), _(4369.066666666666f), _(2114.064516129032f), _(1040.253968253968f),
_(516.031496062992f), _(257.003921568627f), _(128.250489236790f), _(64.062561094819f),
_(32.015632633121f), _(16.003907203907f), _(8.000976681723f), _(4.000244155527f),
_(2.000061037018f), _(1.000015259021f)
_(7281.777777777777f), _(4369.066666666666f), _(2114.064516129032f), _(1040.253968253968f),
_(516.031496062992f), _(257.003921568627f), _(128.250489236790f), _(64.062561094819f),
_(32.015632633121f), _(16.003907203907f), _(8.000976681723f), _(4.000244155527f),
_(2.000061037018f), _(1.000015259021f)
};
#undef _
// offset for requantization
// Requantization offset
// 2*D+1 = steps of quantizer
const mpc_int32_t __Dc [1 + 18] = {
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
@ -72,49 +73,52 @@ const mpc_int32_t __Dc [1 + 18] = {
#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;
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] = (unsigned char)find_shift(X));
#define SET_SCF(N,X) d->SCF[N] = MAKE_MPC_SAMPLE_EX(X,d->SCF_shift[N] = (mpc_uint8_t) find_shift(X));
void
mpc_decoder_scale_output(mpc_decoder *d, double factor)
mpc_decoder_scale_output(mpc_decoder *d, double factor)
{
mpc_int32_t n;
double f1;
double f2;
mpc_int32_t n; double f1, f2;
#ifndef MPC_FIXED_POINT
factor *= 1.0 / (double)(1<<(MPC_FIXED_POINT_SHIFT-1));
factor *= 1.0 / (double) (1<<(MPC_FIXED_POINT_SHIFT-1));
#else
factor *= 1.0 / (double)(1<<(16 - MPC_FIXED_POINT_SHIFT));
factor *= 1.0 / (double) (1<<(16-MPC_FIXED_POINT_SHIFT));
#endif
f1 = f2 = factor;
// handles +1.58...-98.41 dB, where's scf[n] / scf[n-1] = 1.20050805774840750476
SET_SCF(1,factor);
f1 *= 0.83298066476582673961;
f2 *= 1/0.83298066476582673961;
SET_SCF(1,factor);
f1 *= 0.83298066476582673961;
f2 *= 1/0.83298066476582673961;
for ( n = 1; n <= 128; n++ ) {
SET_SCF((unsigned char)(1+n),f1);
SET_SCF((unsigned char)(1-n),f2);
SET_SCF((mpc_uint8_t)(1+n),f1);
SET_SCF((mpc_uint8_t)(1-n),f2);
f1 *= 0.83298066476582673961;
f2 *= 1/0.83298066476582673961;
}
}
void
mpc_decoder_initialisiere_quantisierungstabellen(mpc_decoder *d, double scale_factor)
mpc_decoder_init_quant(mpc_decoder *d, double scale_factor)
{
mpc_decoder_scale_output(d, scale_factor);
}

View File

@ -1,328 +0,0 @@
/*
Copyright (c) 2005, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of the The Musepack Development Team nor the
names of its contributors may be used to endorse or promote
products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <assert.h>
#include <time.h>
#include <mpcdec/mpcdec.h>
/*
The data bundle we pass around with our reader to store file
position and size etc.
*/
typedef struct reader_data_t {
FILE *file;
long size;
mpc_bool_t seekable;
} reader_data;
/*
Our implementations of the mpc_reader callback functions.
*/
mpc_int32_t
read_impl(void *data, void *ptr, mpc_int32_t size)
{
reader_data *d = (reader_data *) data;
return fread(ptr, 1, size, d->file);
}
mpc_bool_t
seek_impl(void *data, mpc_int32_t offset)
{
reader_data *d = (reader_data *) data;
return d->seekable ? !fseek(d->file, offset, SEEK_SET) : false;
}
mpc_int32_t
tell_impl(void *data)
{
reader_data *d = (reader_data *) data;
return ftell(d->file);
}
mpc_int32_t
get_size_impl(void *data)
{
reader_data *d = (reader_data *) data;
return d->size;
}
mpc_bool_t
canseek_impl(void *data)
{
reader_data *d = (reader_data *) data;
return d->seekable;
}
#define WFX_SIZE (2+2+4+4+2+2)
#ifdef MPC_FIXED_POINT
static int
shift_signed(MPC_SAMPLE_FORMAT val, int shift)
{
if (shift > 0)
val <<= shift;
else if (shift < 0)
val >>= -shift;
return (int)val;
}
#endif
class WavWriter {
public:
WavWriter(FILE * p_output, unsigned p_nch, unsigned p_bps,
unsigned p_srate)
: m_file(p_output), m_nch(p_nch), m_bps(p_bps), m_srate(p_srate) {
assert(m_bps == 16 || m_bps == 24);
WriteRaw("RIFF", 4);
WriteDword(0); //fix this in destructor
WriteRaw("WAVE", 4);
WriteRaw("fmt ", 4);
WriteDword(WFX_SIZE);
WriteWord(1); //WAVE_FORMAT_PCM
WriteWord(m_nch);
WriteDword(m_srate);
WriteDword(m_srate * m_nch * (m_bps >> 3));
WriteWord(m_nch * (m_bps >> 3));
WriteWord(m_bps);
/*
WORD wFormatTag;
WORD nChannels;
DWORD nSamplesPerSec;
DWORD nAvgBytesPerSec;
WORD nBlockAlign;
WORD wBitsPerSample;
*/
WriteRaw("data", 4);
WriteDword(0); //fix this in destructor
m_data_bytes_written = 0;
} mpc_bool_t WriteSamples(const MPC_SAMPLE_FORMAT * p_buffer, unsigned p_size) {
unsigned n;
int clip_min = -1 << (m_bps - 1),
clip_max = (1 << (m_bps - 1)) - 1, float_scale = 1 << (m_bps - 1);
for (n = 0; n < p_size; n++) {
int val;
#ifdef MPC_FIXED_POINT
val =
shift_signed(p_buffer[n],
m_bps - MPC_FIXED_POINT_SCALE_SHIFT);
#else
val = (int)(p_buffer[n] * float_scale);
#endif
if (val < clip_min)
val = clip_min;
else if (val > clip_max)
val = clip_max;
if (!WriteInt(val, m_bps))
return false;
}
m_data_bytes_written += p_size * (m_bps >> 3);
return true;
}
~WavWriter() {
if (m_data_bytes_written & 1) {
char blah = 0;
WriteRaw(&blah, 1);
m_data_bytes_written++;
}
Seek(4);
WriteDword((unsigned long)(m_data_bytes_written + 4 + 8 + WFX_SIZE +
8));
Seek(8 + 4 + 8 + WFX_SIZE + 4);
WriteDword(m_data_bytes_written);
}
private:
mpc_bool_t Seek(unsigned p_offset) {
return !fseek(m_file, p_offset, SEEK_SET);
}
mpc_bool_t WriteRaw(const void *p_buffer, unsigned p_bytes) {
return fwrite(p_buffer, 1, p_bytes, m_file) == p_bytes;
}
mpc_bool_t WriteDword(unsigned long p_val) {
return WriteInt(p_val, 32);
}
mpc_bool_t WriteWord(unsigned short p_val) {
return WriteInt(p_val, 16);
}
// write a little-endian number properly
mpc_bool_t WriteInt(unsigned int p_val, unsigned p_width_bits) {
unsigned char temp;
unsigned shift = 0;
assert((p_width_bits % 8) == 0);
do {
temp = (unsigned char)((p_val >> shift) & 0xFF);
if (!WriteRaw(&temp, 1))
return false;
shift += 8;
} while (shift < p_width_bits);
return true;
}
unsigned m_nch, m_bps, m_srate;
FILE *m_file;
unsigned m_data_bytes_written;
};
static void
usage(const char *exename)
{
printf
("Usage: %s <infile.mpc> [<outfile.wav>]\nIf <outfile.wav> is not specified, decoder will run in benchmark mode.\n",
exename);
}
int
main(int argc, char **argv)
{
if (argc != 2 && argc != 3) {
if (argc > 0)
usage(argv[0]);
return 0;
}
FILE *input = fopen(argv[1], "rb");
FILE *output = 0;
if (input == 0) {
usage(argv[0]);
printf("Error opening input file: \"%s\"\n", argv[1]);
return 1;
}
if (argc == 3) {
output = fopen(argv[2], "wb");
if (output == 0) {
fclose(input);
usage(argv[0]);
printf("Error opening output file: \"%s\"\n", argv[2]);
return 1;
}
}
/* initialize our reader_data tag the reader will carry around with it */
reader_data data;
data.file = input;
data.seekable = true;
fseek(data.file, 0, SEEK_END);
data.size = ftell(data.file);
fseek(data.file, 0, SEEK_SET);
/* set up an mpc_reader linked to our function implementations */
mpc_decoder decoder;
mpc_reader reader;
reader.read = read_impl;
reader.seek = seek_impl;
reader.tell = tell_impl;
reader.get_size = get_size_impl;
reader.canseek = canseek_impl;
reader.data = &data;
/* read file's streaminfo data */
mpc_streaminfo info;
mpc_streaminfo_init(&info);
if (mpc_streaminfo_read(&info, &reader) != ERROR_CODE_OK) {
printf("Not a valid musepack file: \"%s\"\n", argv[1]);
return 1;
}
/* instantiate a decoder with our file reader */
mpc_decoder_setup(&decoder, &reader);
if (!mpc_decoder_initialize(&decoder, &info)) {
printf("Error initializing decoder.\n", argv[1]);
return 1;
}
/* decode the file */
printf("Decoding from:\n%s\nTo:\n%s\n", argv[1],
output ? argv[2] : "N/A");
WavWriter *wavwriter =
output ? new WavWriter(output, 2, 16, info.sample_freq) : 0;
MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH];
clock_t begin, end;
begin = clock();
unsigned total_samples = 0;
mpc_bool_t successful = FALSE;
for (;;) {
unsigned status = mpc_decoder_decode(&decoder, sample_buffer, 0, 0);
if (status == (unsigned)(-1)) {
//decode error
printf("Error decoding file.\n");
break;
}
else if (status == 0) //EOF
{
successful = true;
break;
}
else //status>0
{
total_samples += status;
if (wavwriter) {
if (!wavwriter->
WriteSamples(sample_buffer, status * /* stereo */ 2)) {
printf("Write error.\n");
break;
}
}
}
}
end = clock();
if (wavwriter) {
delete wavwriter;
}
printf("Total samples decoded: %u.\n", total_samples);
if (successful) {
unsigned ms = (end - begin) * 1000 / CLOCKS_PER_SEC;
unsigned ratio =
(unsigned)((double)total_samples / (double)info.sample_freq /
((double)ms / 1000.0) * 100.0);
printf("Time: %u ms (%u.%02ux).\n", ms, ratio / 100, ratio % 100);
}
return 0;
}

376
Frameworks/MPCDec/Files/src/streaminfo.c Normal file → Executable file
View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2005, The Musepack Development Team
Copyright (c) 2005-2009, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -31,251 +31,215 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file streaminfo.c
/// Implementation of streaminfo reading functions.
#include <math.h>
#include <mpcdec/mpcdec.h>
#include <mpcdec/internal.h>
#include <mpcdec/streaminfo.h>
#include <stdio.h>
#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 *
Stringify(mpc_uint32_t profile) // profile is 0...15, where 7...13 is used
mpc_get_version_string(float profile) // profile is 0...15, where 7...13 is used
{
static const char na[] = "n.a.";
static const char *Names[] = {
na, "'Unstable/Experimental'", na, na,
na, "'quality 0'", "'quality 1'", "'Telephone'",
"'Thumb'", "'Radio'", "'Standard'", "'Xtreme'",
"'Insane'", "'BrainDead'", "'quality 9'", "'quality 10'"
};
return profile >= sizeof(Names) / sizeof(*Names) ? na : Names[profile];
return profile >= sizeof versionNames / sizeof *versionNames ? na : versionNames[(int)profile];
}
void
mpc_streaminfo_init(mpc_streaminfo * si)
static void
mpc_get_encoder_string(mpc_streaminfo* si)
{
memset(si, 0, sizeof(mpc_streaminfo));
int ver = si->encoder_version;
if (si->stream_version >= 8)
ver = (si->encoder_version >> 24) * 100 + ((si->encoder_version >> 16) & 0xFF);
if (ver <= 116) {
if (ver == 0) {
sprintf(si->encoder, "Buschmann 1.7.0...9, Klemm 0.90...1.05");
} else {
switch (ver % 10) {
case 0:
sprintf(si->encoder, "Release %u.%u", ver / 100,
ver / 10 % 10);
break;
case 2: case 4: case 6: case 8:
sprintf(si->encoder, "Beta %u.%02u", ver / 100,
ver % 100);
break;
default:
sprintf(si->encoder, "--Alpha-- %u.%02u",
ver / 100, ver % 100);
break;
}
}
} else {
int major = si->encoder_version >> 24;
int minor = (si->encoder_version >> 16) & 0xFF;
int build = (si->encoder_version >> 8) & 0xFF;
char * tmp = "--Stable--";
if (minor & 1)
tmp = "--Unstable--";
sprintf(si->encoder, "%s %u.%u.%u", tmp, major, minor, build);
}
}
/// Reads streaminfo from SV7 header.
static mpc_int32_t
streaminfo_read_header_sv7(mpc_streaminfo * si, mpc_uint32_t HeaderData[8])
static mpc_status check_streaminfo(mpc_streaminfo * si)
{
const mpc_int32_t samplefreqs[4] = { 44100, 48000, 37800, 32000 };
if (si->max_band == 0 || si->max_band >= 32
|| si->channels > 2 || si->channels == 0 || si->sample_freq == 0)
return MPC_STATUS_FAIL;
return MPC_STATUS_OK;
}
//mpc_uint32_t HeaderData [8];
/// Reads streaminfo from SV7 header.
mpc_status
streaminfo_read_header_sv7(mpc_streaminfo* si, mpc_bits_reader * r)
{
mpc_uint16_t Estimatedpeak_title = 0;
mpc_uint32_t frames, last_frame_samples;
if (si->stream_version > 0x71) {
// Update (si->stream_version);
return 0;
}
si->bitrate = 0;
frames = (mpc_bits_read(r, 16) << 16) | mpc_bits_read(r, 16);
mpc_bits_read(r, 1); // intensity stereo : should be 0
si->ms = mpc_bits_read(r, 1);
si->max_band = mpc_bits_read(r, 6);
si->profile = mpc_bits_read(r, 4);
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;
/*
if ( !fp->seek ( si->header_position ) ) // seek to header start
return ERROR_CODE_FILE;
if ( fp->read ( HeaderData, sizeof HeaderData) != sizeof HeaderData )
return ERROR_CODE_FILE;
*/
// 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;
}
si->bitrate = 0;
si->frames = HeaderData[1];
si->is = 0;
si->ms = (HeaderData[2] >> 30) & 0x0001;
si->max_band = (HeaderData[2] >> 24) & 0x003F;
si->block_size = 1;
si->profile = (HeaderData[2] << 8) >> 28;
si->profile_name = Stringify(si->profile);
si->sample_freq = samplefreqs[(HeaderData[2] >> 16) & 0x0003];
Estimatedpeak_title = (mpc_uint16_t) (HeaderData[2] & 0xFFFF); // read the ReplayGain data
si->gain_title = (mpc_uint16_t) ((HeaderData[3] >> 16) & 0xFFFF);
si->peak_title = (mpc_uint16_t) (HeaderData[3] & 0xFFFF);
si->gain_album = (mpc_uint16_t) ((HeaderData[4] >> 16) & 0xFFFF);
si->peak_album = (mpc_uint16_t) (HeaderData[4] & 0xFFFF);
si->is_true_gapless = (HeaderData[5] >> 31) & 0x0001; // true gapless: used?
si->last_frame_samples = (HeaderData[5] >> 20) & 0x07FF; // true gapless: valid samples for last frame
si->fast_seek = (HeaderData[5] >> 19) & 0x0001; // fast seeking
si->encoder_version = (HeaderData[6] >> 24) & 0x00FF;
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->encoder_version == 0) {
sprintf(si->encoder, "Buschmann 1.7.0...9, Klemm 0.90...1.05");
}
else {
switch (si->encoder_version % 10) {
case 0:
sprintf(si->encoder, "Release %u.%u", si->encoder_version / 100,
si->encoder_version / 10 % 10);
break;
case 2:
case 4:
case 6:
case 8:
sprintf(si->encoder, "Beta %u.%02u", si->encoder_version / 100,
si->encoder_version % 100);
break;
default:
sprintf(si->encoder, "--Alpha-- %u.%02u",
si->encoder_version / 100, si->encoder_version % 100);
break;
}
}
if (si->peak_title != 0)
si->peak_title = (mpc_uint16_t) (log10(si->peak_title) * 20 * 256 + .5);
// if ( si->peak_title == 0 ) // there is no correct peak_title contained within header
// si->peak_title = (mpc_uint16_t)(Estimatedpeak_title * 1.18);
// if ( si->peak_album == 0 )
// si->peak_album = si->peak_title; // no correct peak_album, use peak_title
if (si->peak_album != 0)
si->peak_album = (mpc_uint16_t) (log10(si->peak_album) * 20 * 256 + .5);
//si->sample_freq = 44100; // AB: used by all files up to SV7
si->channels = 2;
mpc_get_encoder_string(si);
return ERROR_CODE_OK;
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);
}
// read information from SV4-SV6 header
#ifdef MPC_SUPPORT_SV456
static mpc_int32_t
streaminfo_read_header_sv6(mpc_streaminfo * si, mpc_uint32_t HeaderData[8])
/// Reads replay gain datas
void streaminfo_gain(mpc_streaminfo* si, const mpc_bits_reader * r_in)
{
//mpc_uint32_t HeaderData [8];
mpc_bits_reader r = *r_in;
/*
if ( !fp->seek ( si->header_position ) ) // seek to header start
return ERROR_CODE_FILE;
if ( fp->read ( HeaderData, sizeof HeaderData ) != sizeof HeaderData )
return ERROR_CODE_FILE;
*/
si->bitrate = (HeaderData[0] >> 23) & 0x01FF; // read the file-header (SV6 and below)
si->is = (HeaderData[0] >> 22) & 0x0001;
si->ms = (HeaderData[0] >> 21) & 0x0001;
si->stream_version = (HeaderData[0] >> 11) & 0x03FF;
si->max_band = (HeaderData[0] >> 6) & 0x001F;
si->block_size = (HeaderData[0]) & 0x003F;
si->profile = 0;
si->profile_name = Stringify((mpc_uint32_t) (-1));
if (si->stream_version >= 5)
si->frames = HeaderData[1]; // 32 bit
else
si->frames = (HeaderData[1] >> 16); // 16 bit
si->gain_title = 0; // not supported
si->peak_title = 0;
si->gain_album = 0;
si->peak_album = 0;
si->last_frame_samples = 0;
si->is_true_gapless = 0;
si->encoder_version = 0;
si->encoder[0] = '\0';
if (si->stream_version == 7)
return ERROR_CODE_SV7BETA; // are there any unsupported parameters used?
if (si->bitrate != 0)
return ERROR_CODE_CBR;
if (si->is != 0)
return ERROR_CODE_IS;
if (si->block_size != 1)
return ERROR_CODE_BLOCKSIZE;
if (si->stream_version < 6) // Bugfix: last frame was invalid for up to SV5
si->frames -= 1;
si->sample_freq = 44100; // AB: used by all files up to SV7
si->channels = 2;
if (si->stream_version < 4 || si->stream_version > 7)
return ERROR_CODE_INVALIDSV;
return ERROR_CODE_OK;
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);
}
#endif
// reads file header and tags
mpc_int32_t
mpc_streaminfo_read(mpc_streaminfo * si, mpc_reader * r)
/// 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 HeaderData[8];
mpc_int32_t Error = 0;
mpc_uint32_t CRC;
mpc_bits_reader r = *r_in;
// get header position
if ((si->header_position = JumpID3v2(r)) < 0) {
return ERROR_CODE_FILE;
}
// seek to first byte of mpc data
if (!r->seek(r->data, si->header_position)) {
return ERROR_CODE_FILE;
}
if (r->read(r->data, HeaderData, 8 * 4) != 8 * 4) {
return ERROR_CODE_FILE;
}
if (!r->seek(r->data, si->header_position + 6 * 4)) {
return ERROR_CODE_FILE;
}
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->total_file_length = r->get_size(r->data);
si->tag_offset = si->total_file_length;
if (memcmp(HeaderData, "MP+", 3)) return ERROR_CODE_INVALIDSV;
#ifndef MPC_LITTLE_ENDIAN
{
mpc_uint32_t ptr;
for (ptr = 0; ptr < 8; ptr++) {
HeaderData[ptr] = mpc_swap32(HeaderData[ptr]);
}
}
#endif
si->stream_version = HeaderData[0] >> 24;
si->stream_version = mpc_bits_read(&r, 8);
if (si->stream_version != 8)
return MPC_STATUS_FAIL;
// stream version 8
if ((si->stream_version & 15) >= 8) {
return ERROR_CODE_INVALIDSV;
}
// stream version 7
else if ((si->stream_version & 15) == 7) {
Error = streaminfo_read_header_sv7(si, HeaderData);
if (Error != ERROR_CODE_OK) return Error;
}
#ifdef MPC_SUPPORT_SV456
else {
// stream version 4-6
Error = streaminfo_read_header_sv6(si, HeaderData);
if (Error != ERROR_CODE_OK) return Error;
}
#endif
mpc_bits_get_size(&r, &si->samples);
mpc_bits_get_size(&r, &si->beg_silence);
// estimation, exact value needs too much time
si->pcm_samples = 1152 * si->frames - 576;
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;
if (si->pcm_samples > 0) {
si->average_bitrate =
(si->tag_offset -
si->header_position) * 8.0 * si->sample_freq / si->pcm_samples;
}
else {
si->average_bitrate = 0;
}
si->bitrate = 0;
return ERROR_CODE_OK;
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)mpc_streaminfo_get_length_samples(si) /
(double)si->sample_freq;
return (double) (si->samples - si->beg_silence) / si->sample_freq;
}
mpc_int64_t
mpc_streaminfo_get_length_samples(mpc_streaminfo * si)
mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si)
{
mpc_int64_t samples = (mpc_int64_t) si->frames * MPC_FRAME_LENGTH;
if (si->is_true_gapless) {
samples -= (MPC_FRAME_LENGTH - si->last_frame_samples);
}
else {
samples -= MPC_DECODER_SYNTH_DELAY;
}
return samples;
return si->samples - si->beg_silence;
}

268
Frameworks/MPCDec/Files/src/synth_filter.c Normal file → Executable file
View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2005, The Musepack Development Team
Copyright (c) 2005-2009, The Musepack Development Team
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -31,19 +31,18 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/// \file synth_filter.c
/// Synthesis functions.
/// \todo document me
#include <string.h>
#include <mpcdec/mpcdec.h>
#include <mpcdec/internal.h>
#include "decoder.h"
#include "mpcdec_math.h"
/* C O N S T A N T S */
#undef _
#define MPC_FIXED_POINT_SYNTH_FIX 2
#undef _
#ifdef MPC_FIXED_POINT
#define _(value) MPC_MAKE_FRACT_CONST((double)value/(double)(0x40000))
#else
@ -88,31 +87,32 @@ static const MPC_SAMPLE_FORMAT Di_opt [32] [16] = {
#undef _
static void Calculate_New_V ( const MPC_SAMPLE_FORMAT * Sample, MPC_SAMPLE_FORMAT * V )
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
/*static*/ MPC_SAMPLE_FORMAT A00, A01, A02, A03, A04, A05, A06, A07, A08, A09, A10, A11, A12, A13, A14, A15;
/*static*/ MPC_SAMPLE_FORMAT B00, B01, B02, B03, B04, B05, B06, B07, B08, B09, B10, B11, B12, B13, B14, B15;
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 = Sample[ 0] + Sample[31];
A01 = Sample[ 1] + Sample[30];
A02 = Sample[ 2] + Sample[29];
A03 = Sample[ 3] + Sample[28];
A04 = Sample[ 4] + Sample[27];
A05 = Sample[ 5] + Sample[26];
A06 = Sample[ 6] + Sample[25];
A07 = Sample[ 7] + Sample[24];
A08 = Sample[ 8] + Sample[23];
A09 = Sample[ 9] + Sample[22];
A10 = Sample[10] + Sample[21];
A11 = Sample[11] + Sample[20];
A12 = Sample[12] + Sample[19];
A13 = Sample[13] + Sample[18];
A14 = Sample[14] + Sample[17];
A15 = Sample[15] + Sample[16];
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;
@ -182,37 +182,37 @@ static void Calculate_New_V ( const MPC_SAMPLE_FORMAT * Sample, MPC_SAMPLE_FORMA
A14 = B14 + B15;
A15 = MPC_MULTIPLY_FRACT_CONST_FIX((B14 - B15) , 0.7071067691f , 1);
V[48] = -A00;
V[ 0] = A01;
V[40] = -A02 - (V[ 8] = A03);
V[36] = -((V[ 4] = A05 + (V[12] = A07)) + A06);
V[44] = - A04 - A06 - A07;
V[ 6] = (V[10] = A11 + (V[14] = A15)) + A13;
V[38] = (V[34] = -(V[ 2] = A09 + A13 + A15) - A14) + A09 - A10 - A11;
V[46] = (tmp = -(A12 + A14 + A15)) - A08;
V[42] = tmp - A10 - A11;
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((Sample[ 0] - Sample[31]) , 0.5006030202f , MPC_FIXED_POINT_SYNTH_FIX);
A01 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 1] - Sample[30]) , 0.5054709315f , MPC_FIXED_POINT_SYNTH_FIX);
A02 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 2] - Sample[29]) , 0.5154473186f , MPC_FIXED_POINT_SYNTH_FIX);
A03 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 3] - Sample[28]) , 0.5310425758f , MPC_FIXED_POINT_SYNTH_FIX);
A04 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 4] - Sample[27]) , 0.5531039238f , MPC_FIXED_POINT_SYNTH_FIX);
A05 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 5] - Sample[26]) , 0.5829349756f , MPC_FIXED_POINT_SYNTH_FIX);
A06 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 6] - Sample[25]) , 0.6225041151f , MPC_FIXED_POINT_SYNTH_FIX);
A07 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 7] - Sample[24]) , 0.6748083234f , MPC_FIXED_POINT_SYNTH_FIX);
A08 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 8] - Sample[23]) , 0.7445362806f , MPC_FIXED_POINT_SYNTH_FIX);
A09 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 9] - Sample[22]) , 0.8393496275f , MPC_FIXED_POINT_SYNTH_FIX);
A10 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[10] - Sample[21]) , 0.9725682139f , MPC_FIXED_POINT_SYNTH_FIX);
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((Sample[11] - Sample[20]) , 1.1694399118f , MPC_FIXED_POINT_SYNTH_FIX);
A12 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[12] - Sample[19]) , 1.4841645956f , MPC_FIXED_POINT_SYNTH_FIX);
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 ((Sample[11] - Sample[20]) , 1.1694399118f , 30, MPC_FIXED_POINT_SYNTH_FIX);
A12 = MPC_SCALE_CONST_SHR ((Sample[12] - Sample[19]) , 1.4841645956f , 30, MPC_FIXED_POINT_SYNTH_FIX);
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 ((Sample[13] - Sample[18]) , 2.0577809811f , 29, MPC_FIXED_POINT_SYNTH_FIX);
A14 = MPC_SCALE_CONST_SHR ((Sample[14] - Sample[17]) , 3.4076085091f , 29, MPC_FIXED_POINT_SYNTH_FIX);
A15 = MPC_SCALE_CONST_SHR ((Sample[15] - Sample[16]) , 10.1900081635f, 27 ,MPC_FIXED_POINT_SYNTH_FIX);
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;
@ -282,100 +282,90 @@ static void Calculate_New_V ( const MPC_SAMPLE_FORMAT * Sample, MPC_SAMPLE_FORMA
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 Ausdrücke: A04+A06+A07, A09+A13+A15
V[ 5] = (V[11] = (V[13] = A07 + (V[15] = A15)) + A11) + A05 + A13;
V[ 7] = (V[ 9] = A03 + A11 + A15) + A13;
V[33] = -(V[ 1] = A01 + A09 + A13 + A15) - A14;
V[35] = -(V[ 3] = A05 + A07 + A09 + A13 + A15) - A06 - A14;
V[37] = (tmp = -(A10 + A11 + A13 + A14 + A15)) - A05 - A06 - A07;
V[39] = tmp - A02 - A03; // abhängig vom Befehl drüber
V[41] = (tmp += A13 - A12) - A02 - A03; // abhängig vom Befehl 2 drüber
V[43] = tmp - A04 - A06 - A07; // abhängig von Befehlen 1 und 3 drüber
V[47] = (tmp = -(A08 + A12 + A14 + A15)) - A00;
V[45] = tmp - A04 - A06 - A07; // abhängig vom Befehl drüber
// 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<EFBFBD>gig vom Befehl drber
pV[41] = (tmp += A13 - A12) - A02 - A03; // abh<EFBFBD>gig vom Befehl 2 drber
pV[43] = tmp - A04 - A06 - A07; // abh<EFBFBD>gig von Befehlen 1 und 3 drber
pV[47] = (tmp = -(A08 + A12 + A14 + A15)) - A00;
pV[45] = tmp - A04 - A06 - A07; // abh<EFBFBD>gig vom Befehl drber
V[32] = -V[ 0];
V[31] = -V[ 1];
V[30] = -V[ 2];
V[29] = -V[ 3];
V[28] = -V[ 4];
V[27] = -V[ 5];
V[26] = -V[ 6];
V[25] = -V[ 7];
V[24] = -V[ 8];
V[23] = -V[ 9];
V[22] = -V[10];
V[21] = -V[11];
V[20] = -V[12];
V[19] = -V[13];
V[18] = -V[14];
V[17] = -V[15];
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];
V[63] = V[33];
V[62] = V[34];
V[61] = V[35];
V[60] = V[36];
V[59] = V[37];
V[58] = V[38];
V[57] = V[39];
V[56] = V[40];
V[55] = V[41];
V[54] = V[42];
V[53] = V[43];
V[52] = V[44];
V[51] = V[45];
V[50] = V[46];
V[49] = V[47];
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 Synthese_Filter_float_internal(MPC_SAMPLE_FORMAT * OutData,MPC_SAMPLE_FORMAT * V,const MPC_SAMPLE_FORMAT * Y)
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++, Y += 32 ) {
V -= 64;
Calculate_New_V ( Y, V );
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++ )
{
MPC_SAMPLE_FORMAT * Data = OutData;
const MPC_SAMPLE_FORMAT * D = (const MPC_SAMPLE_FORMAT *) &Di_opt;
mpc_int32_t k;
//mpc_int32_t tmp;
for ( k = 0; k < 32; k++, D += 16, V++ ) {
*Data = MPC_SHL(
MPC_MULTIPLY_FRACT(V[ 0],D[ 0]) + MPC_MULTIPLY_FRACT(V[ 96],D[ 1]) + MPC_MULTIPLY_FRACT(V[128],D[ 2]) + MPC_MULTIPLY_FRACT(V[224],D[ 3])
+ MPC_MULTIPLY_FRACT(V[256],D[ 4]) + MPC_MULTIPLY_FRACT(V[352],D[ 5]) + MPC_MULTIPLY_FRACT(V[384],D[ 6]) + MPC_MULTIPLY_FRACT(V[480],D[ 7])
+ MPC_MULTIPLY_FRACT(V[512],D[ 8]) + MPC_MULTIPLY_FRACT(V[608],D[ 9]) + MPC_MULTIPLY_FRACT(V[640],D[10]) + MPC_MULTIPLY_FRACT(V[736],D[11])
+ MPC_MULTIPLY_FRACT(V[768],D[12]) + MPC_MULTIPLY_FRACT(V[864],D[13]) + MPC_MULTIPLY_FRACT(V[896],D[14]) + MPC_MULTIPLY_FRACT(V[992],D[15])
, 2);
Data += 2;
}
V -= 32;//bleh
OutData+=64;
*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 *d, MPC_SAMPLE_FORMAT* OutData)
mpc_decoder_synthese_filter_float(mpc_decoder* p_dec, MPC_SAMPLE_FORMAT* p_out, mpc_int_t channels)
{
/********* left channel ********/
memmove(d->V_L + MPC_V_MEM, d->V_L, 960 * sizeof(MPC_SAMPLE_FORMAT) );
Synthese_Filter_float_internal(
OutData,
(MPC_SAMPLE_FORMAT *)(d->V_L + MPC_V_MEM),
(MPC_SAMPLE_FORMAT *)(d->Y_L [0]));
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 ********/
memmove(d->V_R + MPC_V_MEM, d->V_R, 960 * sizeof(MPC_SAMPLE_FORMAT) );
Synthese_Filter_float_internal(
OutData + 1,
(MPC_SAMPLE_FORMAT *)(d->V_R + MPC_V_MEM),
(MPC_SAMPLE_FORMAT *)(d->Y_R [0]));
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);
}
}
/*******************************************/
@ -384,7 +374,7 @@ mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT* OutData)
/* */
/*******************************************/
static const unsigned char Parity [256] = { // parity
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,
@ -422,19 +412,19 @@ static const unsigned char Parity [256] = { // parity
* XORed values of both generators.
*/
mpc_uint32_t
mpc_random_int(mpc_decoder *d)
mpc_random_int(mpc_decoder* p_dec)
{
#if 1
mpc_uint32_t t1, t2, t3, t4;
t3 = t1 = d->__r1; t4 = t2 = d->__r2; // Parity calculation is done via table lookup, this is also available
t1 &= 0xF5; t2 >>= 25; // on CPUs without parity, can be implemented in C and avoid unpredictable
t1 = Parity [t1]; t2 &= 0x63; // jumps and slow rotate through the carry flag operations.
t1 <<= 31; t2 = Parity [t2];
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 (d->__r1 = (t3 >> 1) | t1 ) ^ (d->__r2 = (t4 + t4) | t2 );
return (p_dec->__r1 = (t3 >> 1) | t1 ) ^ (p_dec->__r2 = (t4 + t4) | t2 );
#else
return (d->__r1 = (d->__r1 >> 1) | ((mpc_uint32_t)Parity [d->__r1 & 0xF5] << 31) ) ^
(d->__r2 = (d->__r2 << 1) | (mpc_uint32_t)Parity [(d->__r2 >> 25) & 0x63] );
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
}

1134
Frameworks/MPCDec/Files/src/tags.c Executable file

File diff suppressed because it is too large Load Diff

View File

@ -7,54 +7,63 @@
objects = {
/* Begin PBXBuildFile section */
83A16EF019F48A2E00842DBC /* huffman.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A16EED19F48A2E00842DBC /* huffman.c */; };
83A16EF119F48A2E00842DBC /* mpc_bits_reader.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A16EEE19F48A2E00842DBC /* mpc_bits_reader.c */; };
83A16EF219F48A2E00842DBC /* mpc_demux.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A16EEF19F48A2E00842DBC /* mpc_demux.c */; };
83A16EF919F48A3A00842DBC /* decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A16EF319F48A3A00842DBC /* decoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
83A16EFA19F48A3A00842DBC /* huffman.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A16EF419F48A3A00842DBC /* huffman.h */; settings = {ATTRIBUTES = (Public, ); }; };
83A16EFB19F48A3A00842DBC /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A16EF519F48A3A00842DBC /* internal.h */; settings = {ATTRIBUTES = (Public, ); }; };
83A16EFC19F48A3A00842DBC /* mpc_bits_reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A16EF619F48A3A00842DBC /* mpc_bits_reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
83A16EFD19F48A3A00842DBC /* mpcdec_math.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A16EF719F48A3A00842DBC /* mpcdec_math.h */; settings = {ATTRIBUTES = (Public, ); }; };
83A16EFE19F48A3A00842DBC /* requant.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A16EF819F48A3A00842DBC /* requant.h */; settings = {ATTRIBUTES = (Public, ); }; };
83A16F1219F48AE200842DBC /* crc32.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A16F0E19F48AE200842DBC /* crc32.c */; };
83A16F1319F48AE200842DBC /* fastmath.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A16F0F19F48AE200842DBC /* fastmath.c */; };
83A16F1419F48AE200842DBC /* huffman-bcl.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A16F1019F48AE200842DBC /* huffman-bcl.c */; };
83A16F1519F48AE200842DBC /* tags.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A16F1119F48AE200842DBC /* tags.c */; };
83A16F1E19F48FB800842DBC /* datatypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A16F1719F48FB800842DBC /* datatypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
83A16F1F19F48FB800842DBC /* minimax.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A16F1819F48FB800842DBC /* minimax.h */; settings = {ATTRIBUTES = (Public, ); }; };
83A16F2019F48FB800842DBC /* mpc_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A16F1919F48FB800842DBC /* mpc_types.h */; settings = {ATTRIBUTES = (Public, ); }; };
83A16F2119F48FB800842DBC /* mpcdec.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A16F1A19F48FB800842DBC /* mpcdec.h */; settings = {ATTRIBUTES = (Public, ); }; };
83A16F2219F48FB800842DBC /* mpcmath.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A16F1B19F48FB800842DBC /* mpcmath.h */; settings = {ATTRIBUTES = (Public, ); }; };
83A16F2319F48FB800842DBC /* reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A16F1C19F48FB800842DBC /* reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
83A16F2419F48FB800842DBC /* streaminfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A16F1D19F48FB800842DBC /* streaminfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
8DC2EF530486A6940098B216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C1666FE841158C02AAC07 /* InfoPlist.strings */; };
8E6096C509F314CF006D8BD7 /* huffsv7.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E6096BC09F314CF006D8BD7 /* huffsv7.c */; };
8E6096C609F314CF006D8BD7 /* huffsv46.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E6096BD09F314CF006D8BD7 /* huffsv46.c */; };
8E6096C709F314CF006D8BD7 /* idtag.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E6096BE09F314CF006D8BD7 /* idtag.c */; };
8E6096C809F314CF006D8BD7 /* mpc_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E6096BF09F314CF006D8BD7 /* mpc_decoder.c */; };
8E6096C909F314CF006D8BD7 /* mpc_reader.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E6096C009F314CF006D8BD7 /* mpc_reader.c */; };
8E6096CA09F314CF006D8BD7 /* requant.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E6096C109F314CF006D8BD7 /* requant.c */; };
8E6096CC09F314CF006D8BD7 /* streaminfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E6096C309F314CF006D8BD7 /* streaminfo.c */; };
8E6096CD09F314CF006D8BD7 /* synth_filter.c in Sources */ = {isa = PBXBuildFile; fileRef = 8E6096C409F314CF006D8BD7 /* synth_filter.c */; };
8E6096DC09F314DB006D8BD7 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E6096CE09F314DB006D8BD7 /* config.h */; };
8E6096DD09F314DB006D8BD7 /* mainpage.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E6096CF09F314DB006D8BD7 /* mainpage.h */; };
8E6096DE09F314DB006D8BD7 /* config_types.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E6096D109F314DB006D8BD7 /* config_types.h */; settings = {ATTRIBUTES = (Public, ); }; };
8E6096E009F314DB006D8BD7 /* config_win32.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E6096D309F314DB006D8BD7 /* config_win32.h */; settings = {ATTRIBUTES = (Public, ); }; };
8E6096E109F314DB006D8BD7 /* decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E6096D409F314DB006D8BD7 /* decoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
8E6096E209F314DB006D8BD7 /* huffman.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E6096D509F314DB006D8BD7 /* huffman.h */; settings = {ATTRIBUTES = (Public, ); }; };
8E6096E309F314DB006D8BD7 /* internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E6096D609F314DB006D8BD7 /* internal.h */; settings = {ATTRIBUTES = (Public, ); }; };
8E6096E409F314DB006D8BD7 /* math.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E6096D709F314DB006D8BD7 /* math.h */; settings = {ATTRIBUTES = (Public, ); }; };
8E6096E509F314DB006D8BD7 /* mpcdec.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E6096D809F314DB006D8BD7 /* mpcdec.h */; settings = {ATTRIBUTES = (Public, ); }; };
8E6096E609F314DB006D8BD7 /* reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E6096D909F314DB006D8BD7 /* reader.h */; settings = {ATTRIBUTES = (Public, ); }; };
8E6096E709F314DB006D8BD7 /* requant.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E6096DA09F314DB006D8BD7 /* requant.h */; settings = {ATTRIBUTES = (Public, ); }; };
8E6096E809F314DB006D8BD7 /* streaminfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E6096DB09F314DB006D8BD7 /* streaminfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
089C1667FE841158C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
83A16EED19F48A2E00842DBC /* huffman.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = huffman.c; path = Files/src/huffman.c; sourceTree = "<group>"; };
83A16EEE19F48A2E00842DBC /* mpc_bits_reader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mpc_bits_reader.c; path = Files/src/mpc_bits_reader.c; sourceTree = "<group>"; };
83A16EEF19F48A2E00842DBC /* mpc_demux.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mpc_demux.c; path = Files/src/mpc_demux.c; sourceTree = "<group>"; };
83A16EF319F48A3A00842DBC /* decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = decoder.h; path = Files/include/decoder.h; sourceTree = "<group>"; };
83A16EF419F48A3A00842DBC /* huffman.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = huffman.h; path = Files/include/huffman.h; sourceTree = "<group>"; };
83A16EF519F48A3A00842DBC /* internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = internal.h; path = Files/include/internal.h; sourceTree = "<group>"; };
83A16EF619F48A3A00842DBC /* mpc_bits_reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mpc_bits_reader.h; path = Files/include/mpc_bits_reader.h; sourceTree = "<group>"; };
83A16EF719F48A3A00842DBC /* mpcdec_math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mpcdec_math.h; path = Files/include/mpcdec_math.h; sourceTree = "<group>"; };
83A16EF819F48A3A00842DBC /* requant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = requant.h; path = Files/include/requant.h; sourceTree = "<group>"; };
83A16F0E19F48AE200842DBC /* crc32.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = crc32.c; path = Files/src/crc32.c; sourceTree = "<group>"; };
83A16F0F19F48AE200842DBC /* fastmath.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fastmath.c; path = Files/src/fastmath.c; sourceTree = "<group>"; };
83A16F1019F48AE200842DBC /* huffman-bcl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "huffman-bcl.c"; path = "Files/src/huffman-bcl.c"; sourceTree = "<group>"; };
83A16F1119F48AE200842DBC /* tags.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tags.c; path = Files/src/tags.c; sourceTree = "<group>"; };
83A16F1719F48FB800842DBC /* datatypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = datatypes.h; sourceTree = "<group>"; };
83A16F1819F48FB800842DBC /* minimax.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = minimax.h; sourceTree = "<group>"; };
83A16F1919F48FB800842DBC /* mpc_types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpc_types.h; sourceTree = "<group>"; };
83A16F1A19F48FB800842DBC /* mpcdec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpcdec.h; sourceTree = "<group>"; };
83A16F1B19F48FB800842DBC /* mpcmath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpcmath.h; sourceTree = "<group>"; };
83A16F1C19F48FB800842DBC /* reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = reader.h; sourceTree = "<group>"; };
83A16F1D19F48FB800842DBC /* streaminfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = streaminfo.h; sourceTree = "<group>"; };
8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
8DC2EF5B0486A6940098B216 /* mpcdec.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = mpcdec.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8E6096BC09F314CF006D8BD7 /* huffsv7.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = huffsv7.c; path = Files/src/huffsv7.c; sourceTree = "<group>"; };
8E6096BD09F314CF006D8BD7 /* huffsv46.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = huffsv46.c; path = Files/src/huffsv46.c; sourceTree = "<group>"; };
8E6096BE09F314CF006D8BD7 /* idtag.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = idtag.c; path = Files/src/idtag.c; sourceTree = "<group>"; };
8E6096BF09F314CF006D8BD7 /* mpc_decoder.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = mpc_decoder.c; path = Files/src/mpc_decoder.c; sourceTree = "<group>"; };
8E6096C009F314CF006D8BD7 /* mpc_reader.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = mpc_reader.c; path = Files/src/mpc_reader.c; sourceTree = "<group>"; };
8E6096C109F314CF006D8BD7 /* requant.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = requant.c; path = Files/src/requant.c; sourceTree = "<group>"; };
8E6096C209F314CF006D8BD7 /* sample.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sample.cpp; path = Files/src/sample.cpp; sourceTree = "<group>"; };
8E6096C309F314CF006D8BD7 /* streaminfo.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = streaminfo.c; path = Files/src/streaminfo.c; sourceTree = "<group>"; };
8E6096C409F314CF006D8BD7 /* synth_filter.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = synth_filter.c; path = Files/src/synth_filter.c; sourceTree = "<group>"; };
8E6096CE09F314DB006D8BD7 /* config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = config.h; path = Files/include/config.h; sourceTree = "<group>"; };
8E6096CF09F314DB006D8BD7 /* mainpage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mainpage.h; path = Files/include/mainpage.h; sourceTree = "<group>"; };
8E6096D109F314DB006D8BD7 /* config_types.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = config_types.h; sourceTree = "<group>"; };
8E6096D309F314DB006D8BD7 /* config_win32.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = config_win32.h; sourceTree = "<group>"; };
8E6096D409F314DB006D8BD7 /* decoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = decoder.h; sourceTree = "<group>"; };
8E6096D509F314DB006D8BD7 /* huffman.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = huffman.h; sourceTree = "<group>"; };
8E6096D609F314DB006D8BD7 /* internal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = internal.h; sourceTree = "<group>"; };
8E6096D709F314DB006D8BD7 /* math.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = math.h; sourceTree = "<group>"; };
8E6096D809F314DB006D8BD7 /* mpcdec.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = mpcdec.h; sourceTree = "<group>"; };
8E6096D909F314DB006D8BD7 /* reader.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = reader.h; sourceTree = "<group>"; };
8E6096DA09F314DB006D8BD7 /* requant.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = requant.h; sourceTree = "<group>"; };
8E6096DB09F314DB006D8BD7 /* streaminfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = streaminfo.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -120,16 +129,34 @@
name = "Other Frameworks";
sourceTree = "<group>";
};
83A16F1619F48FB800842DBC /* mpcdec */ = {
isa = PBXGroup;
children = (
83A16F1719F48FB800842DBC /* datatypes.h */,
83A16F1819F48FB800842DBC /* minimax.h */,
83A16F1919F48FB800842DBC /* mpc_types.h */,
83A16F1A19F48FB800842DBC /* mpcdec.h */,
83A16F1B19F48FB800842DBC /* mpcmath.h */,
83A16F1C19F48FB800842DBC /* reader.h */,
83A16F1D19F48FB800842DBC /* streaminfo.h */,
);
name = mpcdec;
path = Files/include/mpcdec;
sourceTree = "<group>";
};
8E6096BA09F314AD006D8BD7 /* Source */ = {
isa = PBXGroup;
children = (
8E6096BC09F314CF006D8BD7 /* huffsv7.c */,
8E6096BD09F314CF006D8BD7 /* huffsv46.c */,
8E6096BE09F314CF006D8BD7 /* idtag.c */,
83A16F0E19F48AE200842DBC /* crc32.c */,
83A16F0F19F48AE200842DBC /* fastmath.c */,
83A16F1019F48AE200842DBC /* huffman-bcl.c */,
83A16F1119F48AE200842DBC /* tags.c */,
83A16EED19F48A2E00842DBC /* huffman.c */,
83A16EEE19F48A2E00842DBC /* mpc_bits_reader.c */,
83A16EEF19F48A2E00842DBC /* mpc_demux.c */,
8E6096BF09F314CF006D8BD7 /* mpc_decoder.c */,
8E6096C009F314CF006D8BD7 /* mpc_reader.c */,
8E6096C109F314CF006D8BD7 /* requant.c */,
8E6096C209F314CF006D8BD7 /* sample.cpp */,
8E6096C309F314CF006D8BD7 /* streaminfo.c */,
8E6096C409F314CF006D8BD7 /* synth_filter.c */,
);
@ -139,31 +166,17 @@
8E6096BB09F314B2006D8BD7 /* Headers */ = {
isa = PBXGroup;
children = (
8E6096CE09F314DB006D8BD7 /* config.h */,
8E6096CF09F314DB006D8BD7 /* mainpage.h */,
8E6096D009F314DB006D8BD7 /* mpcdec */,
83A16F1619F48FB800842DBC /* mpcdec */,
83A16EF319F48A3A00842DBC /* decoder.h */,
83A16EF419F48A3A00842DBC /* huffman.h */,
83A16EF519F48A3A00842DBC /* internal.h */,
83A16EF619F48A3A00842DBC /* mpc_bits_reader.h */,
83A16EF719F48A3A00842DBC /* mpcdec_math.h */,
83A16EF819F48A3A00842DBC /* requant.h */,
);
name = Headers;
sourceTree = "<group>";
};
8E6096D009F314DB006D8BD7 /* mpcdec */ = {
isa = PBXGroup;
children = (
8E6096D109F314DB006D8BD7 /* config_types.h */,
8E6096D309F314DB006D8BD7 /* config_win32.h */,
8E6096D409F314DB006D8BD7 /* decoder.h */,
8E6096D509F314DB006D8BD7 /* huffman.h */,
8E6096D609F314DB006D8BD7 /* internal.h */,
8E6096D709F314DB006D8BD7 /* math.h */,
8E6096D809F314DB006D8BD7 /* mpcdec.h */,
8E6096D909F314DB006D8BD7 /* reader.h */,
8E6096DA09F314DB006D8BD7 /* requant.h */,
8E6096DB09F314DB006D8BD7 /* streaminfo.h */,
);
name = mpcdec;
path = Files/include/mpcdec;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@ -171,18 +184,19 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
8E6096DC09F314DB006D8BD7 /* config.h in Headers */,
8E6096DD09F314DB006D8BD7 /* mainpage.h in Headers */,
8E6096DE09F314DB006D8BD7 /* config_types.h in Headers */,
8E6096E009F314DB006D8BD7 /* config_win32.h in Headers */,
8E6096E109F314DB006D8BD7 /* decoder.h in Headers */,
8E6096E209F314DB006D8BD7 /* huffman.h in Headers */,
8E6096E309F314DB006D8BD7 /* internal.h in Headers */,
8E6096E409F314DB006D8BD7 /* math.h in Headers */,
8E6096E509F314DB006D8BD7 /* mpcdec.h in Headers */,
8E6096E609F314DB006D8BD7 /* reader.h in Headers */,
8E6096E709F314DB006D8BD7 /* requant.h in Headers */,
8E6096E809F314DB006D8BD7 /* streaminfo.h in Headers */,
83A16F2219F48FB800842DBC /* mpcmath.h in Headers */,
83A16F1F19F48FB800842DBC /* minimax.h in Headers */,
83A16F2319F48FB800842DBC /* reader.h in Headers */,
83A16F1E19F48FB800842DBC /* datatypes.h in Headers */,
83A16F2419F48FB800842DBC /* streaminfo.h in Headers */,
83A16F2019F48FB800842DBC /* mpc_types.h in Headers */,
83A16F2119F48FB800842DBC /* mpcdec.h in Headers */,
83A16EFB19F48A3A00842DBC /* internal.h in Headers */,
83A16EFE19F48A3A00842DBC /* requant.h in Headers */,
83A16EFA19F48A3A00842DBC /* huffman.h in Headers */,
83A16EFD19F48A3A00842DBC /* mpcdec_math.h in Headers */,
83A16EFC19F48A3A00842DBC /* mpc_bits_reader.h in Headers */,
83A16EF919F48A3A00842DBC /* decoder.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -249,13 +263,17 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8E6096C509F314CF006D8BD7 /* huffsv7.c in Sources */,
8E6096C609F314CF006D8BD7 /* huffsv46.c in Sources */,
8E6096C709F314CF006D8BD7 /* idtag.c in Sources */,
8E6096C809F314CF006D8BD7 /* mpc_decoder.c in Sources */,
83A16EF019F48A2E00842DBC /* huffman.c in Sources */,
83A16F1519F48AE200842DBC /* tags.c in Sources */,
83A16EF119F48A2E00842DBC /* mpc_bits_reader.c in Sources */,
83A16F1219F48AE200842DBC /* crc32.c in Sources */,
8E6096C909F314CF006D8BD7 /* mpc_reader.c in Sources */,
8E6096CA09F314CF006D8BD7 /* requant.c in Sources */,
83A16F1419F48AE200842DBC /* huffman-bcl.c in Sources */,
8E6096CC09F314CF006D8BD7 /* streaminfo.c in Sources */,
83A16F1319F48AE200842DBC /* fastmath.c in Sources */,
83A16EF219F48A2E00842DBC /* mpc_demux.c in Sources */,
8E6096CD09F314CF006D8BD7 /* synth_filter.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -8,14 +8,16 @@
#import <Cocoa/Cocoa.h>
#import <mpcdec/mpcdec.h>
#import <mpcdec/decoder.h>
#import <mpcdec/internal.h>
#import "Plugin.h"
@interface MusepackDecoder : NSObject <CogDecoder>
{
id<CogSource> source;
mpc_decoder decoder;
mpc_reader reader;
mpc_demux* demux;
mpc_streaminfo info;
mpc_reader reader;
char buffer[MPC_FRAME_LENGTH*4];
int bufferFrames;

View File

@ -12,30 +12,30 @@
@implementation MusepackDecoder
mpc_int32_t ReadProc(void *data, void *ptr, mpc_int32_t size)
mpc_int32_t ReadProc(mpc_reader *p_reader, void *ptr, mpc_int32_t size)
{
MusepackDecoder *decoder = (MusepackDecoder *) data;
MusepackDecoder *decoder = (MusepackDecoder *) p_reader->data;
return [[decoder source] read:ptr amount:size];
}
mpc_bool_t SeekProc(void *data, mpc_int32_t offset)
mpc_bool_t SeekProc(mpc_reader *p_reader, mpc_int32_t offset)
{
MusepackDecoder *decoder = (MusepackDecoder *) data;
MusepackDecoder *decoder = (MusepackDecoder *) p_reader->data;
return [[decoder source] seek:offset whence:SEEK_SET];
}
mpc_int32_t TellProc(void *data)
mpc_int32_t TellProc(mpc_reader *p_reader)
{
MusepackDecoder *decoder = (MusepackDecoder *) data;
MusepackDecoder *decoder = (MusepackDecoder *) p_reader->data;
return [[decoder source] tell];
}
mpc_int32_t GetSizeProc(void *data)
mpc_int32_t GetSizeProc(mpc_reader *p_reader)
{
MusepackDecoder *decoder = (MusepackDecoder *) data;
MusepackDecoder *decoder = (MusepackDecoder *) p_reader->data;
if ([[decoder source] seekable]) {
long currentPos = [[decoder source] tell];
@ -52,9 +52,9 @@ mpc_int32_t GetSizeProc(void *data)
}
}
mpc_bool_t CanSeekProc(void *data)
mpc_bool_t CanSeekProc(mpc_reader *p_reader)
{
MusepackDecoder *decoder = (MusepackDecoder *) data;
MusepackDecoder *decoder = (MusepackDecoder *) p_reader->data;
return [[decoder source] seekable];
}
@ -70,24 +70,14 @@ mpc_bool_t CanSeekProc(void *data)
reader.canseek = CanSeekProc;
reader.data = self;
mpc_streaminfo_init(&info);
if (mpc_streaminfo_read(&info, &reader) != ERROR_CODE_OK)
{
DLog(@"Not a valid musepack file.");
return NO;
}
/* instantiate a decoder with our reader */
mpc_decoder_setup(&decoder, &reader);
if (!mpc_decoder_initialize(&decoder, &info))
/* instantiate a demuxer with our reader */
demux = mpc_demux_init(&reader);
if (!demux)
{
DLog(@"Error initializing decoder.");
return NO;
}
/* Only use fast seeking if format supports it */
mpc_decoder_set_seeking(&decoder, &info, FALSE);
mpc_demux_get_info(demux, &info);
bitrate = (int)(info.average_bitrate/1000.0);
frequency = info.sample_freq;
@ -139,22 +129,21 @@ mpc_bool_t CanSeekProc(void *data)
if (bufferFrames == 0)
{
/* returns the length of the samples*/
unsigned status = mpc_decoder_decode(&decoder, sampleBuffer, 0, 0);
if (status == (unsigned)( -1))
mpc_frame_info frame;
frame.buffer = sampleBuffer;
mpc_status err = mpc_demux_decode(demux, &frame);
if (frame.bits == -1)
{
//decode error
DLog(@"Decode error");
return 0;
}
else if (status == 0) //EOF
{
if (err != MPC_STATUS_OK)
DLog(@"Decode error");
return 0;
}
else //status>0 /* status == MPC_FRAME_LENGTH */
{
}
bufferFrames = status;
bufferFrames = frame.samples;
}
int framesToRead = bufferFrames;
@ -163,7 +152,7 @@ mpc_bool_t CanSeekProc(void *data)
framesToRead = frames;
}
[self writeToBuffer:((float*)(buf + (framesRead*bytesPerFrame))) fromBuffer:sampleBuffer frames: framesToRead];
[self writeToBuffer:((float*)(buf + (framesRead *bytesPerFrame))) fromBuffer:sampleBuffer frames: framesToRead];
frames -= framesToRead;
framesRead += framesToRead;
@ -180,12 +169,17 @@ mpc_bool_t CanSeekProc(void *data)
- (void)close
{
if (demux)
{
mpc_demux_exit(demux);
demux = NULL;
}
[source close];
}
- (long)seek:(long)sample
{
mpc_decoder_seek_sample(&decoder, sample);
mpc_demux_seek_sample(&demux, sample);
return sample;
}