diff options
Diffstat (limited to 'contrib/libmpcdec')
| -rw-r--r-- | contrib/libmpcdec/COPYING | 31 | ||||
| -rw-r--r-- | contrib/libmpcdec/Makefile.am | 15 | ||||
| -rw-r--r-- | contrib/libmpcdec/diff_from_libmpcdec_1.2.5.patch | 20 | ||||
| -rw-r--r-- | contrib/libmpcdec/huffsv46.c | 75 | ||||
| -rw-r--r-- | contrib/libmpcdec/huffsv7.c | 81 | ||||
| -rw-r--r-- | contrib/libmpcdec/idtag.c | 83 | ||||
| -rw-r--r-- | contrib/libmpcdec/mpc_decoder.c | 1271 | ||||
| -rw-r--r-- | contrib/libmpcdec/mpc_reader.c | 96 | ||||
| -rw-r--r-- | contrib/libmpcdec/mpcdec/config_types.h | 50 | ||||
| -rw-r--r-- | contrib/libmpcdec/mpcdec/decoder.h | 124 | ||||
| -rw-r--r-- | contrib/libmpcdec/mpcdec/huffman.h | 58 | ||||
| -rw-r--r-- | contrib/libmpcdec/mpcdec/internal.h | 65 | ||||
| -rw-r--r-- | contrib/libmpcdec/mpcdec/math.h | 144 | ||||
| -rw-r--r-- | contrib/libmpcdec/mpcdec/mpcdec.h | 145 | ||||
| -rw-r--r-- | contrib/libmpcdec/mpcdec/reader.h | 82 | ||||
| -rw-r--r-- | contrib/libmpcdec/mpcdec/requant.h | 51 | ||||
| -rw-r--r-- | contrib/libmpcdec/mpcdec/streaminfo.h | 91 | ||||
| -rw-r--r-- | contrib/libmpcdec/requant.c | 120 | ||||
| -rw-r--r-- | contrib/libmpcdec/streaminfo.c | 281 | ||||
| -rw-r--r-- | contrib/libmpcdec/synth_filter.c | 440 | 
20 files changed, 3323 insertions, 0 deletions
| diff --git a/contrib/libmpcdec/COPYING b/contrib/libmpcdec/COPYING new file mode 100644 index 000000000..10190c014 --- /dev/null +++ b/contrib/libmpcdec/COPYING @@ -0,0 +1,31 @@ +Copyright (c) 2005, The Musepack Development Team +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + +    * Redistributions of source code must retain the above copyright +      notice, this list of conditions and the following disclaimer. + +    * Redistributions in binary form must reproduce the above +      copyright notice, this list of conditions and the following +      disclaimer in the documentation and/or other materials provided +      with the distribution. + +    * Neither the name of the The Musepack Development Team nor the +      names of its contributors may be used to endorse or promote +      products derived from this software without specific prior +      written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/contrib/libmpcdec/Makefile.am b/contrib/libmpcdec/Makefile.am new file mode 100644 index 000000000..24e2c0157 --- /dev/null +++ b/contrib/libmpcdec/Makefile.am @@ -0,0 +1,15 @@ +AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) + +EXTRA_DIST = diff_from_libmpcdec_1.2.5.patch COPYING + +if ENABLE_MUSEPACK +if !WITH_EXTERNAL_LIBMPCDEC +noinst_LTLIBRARIES = libmpcdec.la +endif +endif + +libmpcdec_la_SOURCES = huffsv46.c huffsv7.c idtag.c mpc_decoder.c mpc_reader.c \ +	requant.c streaminfo.c synth_filter.c \ +	mpcdec/internal.h mpcdec/mpcdec.h mpcdec/streaminfo.h mpcdec/math.h \ +	mpcdec/decoder.h mpcdec/config_types.h mpcdec/requant.h mpcdec/huffman.h \ +	mpcdec/reader.h diff --git a/contrib/libmpcdec/diff_from_libmpcdec_1.2.5.patch b/contrib/libmpcdec/diff_from_libmpcdec_1.2.5.patch new file mode 100644 index 000000000..f0e3b0cb6 --- /dev/null +++ b/contrib/libmpcdec/diff_from_libmpcdec_1.2.5.patch @@ -0,0 +1,20 @@ +Use xine's os_types.h file. +Define MPC_LITTLE_ENDIAN when needed. + +Index: libmpcdec/mpcdec/config_types.h +=================================================================== +--- libmpcdec.orig/mpcdec/config_types.h ++++ libmpcdec/mpcdec/config_types.h +@@ -35,7 +35,11 @@ + #ifndef __MUSEPACK_CONFIG_TYPES_H__ + #define __MUSEPACK_CONFIG_TYPES_H__ +  +-#include <inttypes.h> ++#include "os_types.h" ++ ++#ifndef WORDS_BIGENDIAN ++# define MPC_LITTLE_ENDIAN ++#endif +  + typedef unsigned char mpc_bool_t; + #define TRUE  1 diff --git a/contrib/libmpcdec/huffsv46.c b/contrib/libmpcdec/huffsv46.c new file mode 100644 index 000000000..a6f031160 --- /dev/null +++ b/contrib/libmpcdec/huffsv46.c @@ -0,0 +1,75 @@ +/* +  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 diff --git a/contrib/libmpcdec/huffsv7.c b/contrib/libmpcdec/huffsv7.c new file mode 100644 index 000000000..96f81ce24 --- /dev/null +++ b/contrib/libmpcdec/huffsv7.c @@ -0,0 +1,81 @@ +/* +  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]}, +}; diff --git a/contrib/libmpcdec/idtag.c b/contrib/libmpcdec/idtag.c new file mode 100644 index 000000000..7cecdb04e --- /dev/null +++ b/contrib/libmpcdec/idtag.c @@ -0,0 +1,83 @@ +/* +  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; +} diff --git a/contrib/libmpcdec/mpc_decoder.c b/contrib/libmpcdec/mpc_decoder.c new file mode 100644 index 000000000..a7b31c970 --- /dev/null +++ b/contrib/libmpcdec/mpc_decoder.c @@ -0,0 +1,1271 @@ +/* +  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 mpc_decoder.c +/// Core decoding routines and logic. + +#include <mpcdec/mpcdec.h> +#include <mpcdec/internal.h> +#include <mpcdec/requant.h> +#include <mpcdec/huffman.h> + +//SV7 tables +extern const HuffmanTyp*   mpc_table_HuffQ [2] [8]; +extern const HuffmanTyp    mpc_table_HuffHdr  [10]; +extern const HuffmanTyp    mpc_table_HuffSCFI [ 4]; +extern const HuffmanTyp    mpc_table_HuffDSCF [16]; + + +#ifdef MPC_SUPPORT_SV456 +//SV4/5/6 tables +extern const HuffmanTyp*   mpc_table_SampleHuff [18]; +extern const HuffmanTyp    mpc_table_SCFI_Bundle   [ 8]; +extern const HuffmanTyp    mpc_table_DSCF_Entropie [13]; +extern const HuffmanTyp    mpc_table_Region_A [16]; +extern const HuffmanTyp    mpc_table_Region_B [ 8]; +extern const HuffmanTyp    mpc_table_Region_C [ 4]; + +#endif + +#ifndef MPC_LITTLE_ENDIAN +#define SWAP(X) mpc_swap32(X) +#else +#define SWAP(X) (X) +#endif + +//------------------------------------------------------------------------------ +// types +//------------------------------------------------------------------------------ +enum +    { +        EQ_TAP = 13,                        // length of FIR filter for EQ +        DELAY = ((EQ_TAP + 1) / 2),         // delay of FIR +        FIR_BANDS = 4,                      // number of subbands to be FIR filtered +        MEMSIZE = MPC_DECODER_MEMSIZE,      // overall buffer size +        MEMSIZE2 = (MEMSIZE/2),             // size of one buffer +        MEMMASK = (MEMSIZE-1) +    }; + +//------------------------------------------------------------------------------ +// forward declarations +//------------------------------------------------------------------------------ +void mpc_decoder_read_bitstream_sv6(mpc_decoder *d, mpc_bool_t seeking); +void mpc_decoder_read_bitstream_sv7(mpc_decoder *d, mpc_bool_t seeking); +mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample); +void mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band); + +//------------------------------------------------------------------------------ +// utility functions +//------------------------------------------------------------------------------ +static mpc_int32_t f_read(mpc_decoder *d, void *ptr, mpc_int32_t size)  +{  +    return d->r->read(d->r->data, ptr, size);  +} + +static mpc_bool_t f_seek(mpc_decoder *d, mpc_int32_t offset)  +{  +    return d->r->seek(d->r->data, offset);  +} + +static mpc_int32_t f_read_dword(mpc_decoder *d, mpc_uint32_t * ptr, mpc_uint32_t count)  +{ +    return f_read(d, ptr, count << 2) >> 2; +} + +static void mpc_decoder_seek(mpc_decoder *d, mpc_uint32_t bitpos) +{ +    f_seek(d, (bitpos>>5) * 4 + d->MPCHeaderPos); +    f_read_dword(d, d->Speicher, MEMSIZE); +    d->dword = SWAP(d->Speicher[d->Zaehler = 0]); +    d->pos = bitpos & 31; +    d->WordsRead = bitpos >> 5; +} + +// jump desired number of bits out of the bitstream +static void mpc_decoder_bitstream_jump(mpc_decoder *d, const mpc_uint32_t bits) +{ +    d->pos += bits; + +    if (d->pos >= 32) { +        d->Zaehler = (d->Zaehler + (d->pos >> 5)) & MEMMASK; +        d->dword = SWAP(d->Speicher[d->Zaehler]); +        d->WordsRead += d->pos >> 5; +        d->pos &= 31; +    } +} + +void mpc_decoder_update_buffer(mpc_decoder *d, mpc_uint32_t RING) +{ +    if ((RING ^ d->Zaehler) & MEMSIZE2 ) { +        // update buffer +        f_read_dword(d, d->Speicher + (RING & MEMSIZE2), MEMSIZE2); +    } +} + +//------------------------------------------------------------------------------ +// huffman & bitstream functions +//------------------------------------------------------------------------------ + +/* F U N C T I O N S */ + +// resets bitstream decoding +static void +mpc_decoder_reset_bitstream_decode(mpc_decoder *d)  +{ +    d->dword = 0; +    d->pos = 0; +    d->Zaehler = 0; +    d->WordsRead = 0; +} + +// reports the number of read bits +static mpc_uint32_t +mpc_decoder_bits_read(mpc_decoder *d)  +{ +    return 32 * d->WordsRead + d->pos; +} + +// read desired number of bits out of the bitstream (max 31) +static mpc_uint32_t +mpc_decoder_bitstream_read(mpc_decoder *d, const mpc_uint32_t bits)  +{ +    mpc_uint32_t out = d->dword; + +    d->pos += bits; + +    if (d->pos < 32) { +        out >>= (32 - d->pos); +    } else { +        d->dword = SWAP(d->Speicher[d->Zaehler = (d->Zaehler + 1) & MEMMASK]); +        d->pos -= 32; +        if (d->pos) { +            out <<= d->pos; +            out |= d->dword >> (32 - d->pos); +        } +        d->WordsRead++; +    } + +    return out & ((1 << bits) - 1); +} + +// basic huffman decoding routine +// works with maximum lengths up to max_length +static mpc_int32_t +mpc_decoder_huffman_decode(mpc_decoder *d, const HuffmanTyp *Table, +                           const mpc_uint32_t max_length) +{ +    // load preview and decode +    mpc_uint32_t code = d->dword << d->pos; +    if (32 - d->pos < max_length) +        code |= SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]) >> (32 - d->pos); + +    while (code < Table->Code) Table++; + +    // set the new position within bitstream without performing a dummy-read +    if ((d->pos += Table->Length) >= 32) { +        d->pos -= 32; +        d->dword = SWAP(d->Speicher[d->Zaehler = (d->Zaehler + 1) & MEMMASK]); +        d->WordsRead++; +    } + +    return Table->Value; +} + +// decode SCFI-bundle (sv4,5,6) +static void +mpc_decoder_scfi_bundle_read(mpc_decoder *d, const HuffmanTyp* Table, +                             mpc_int32_t* SCFI, mpc_bool_t* DSCF) +{ +    mpc_uint32_t value = mpc_decoder_huffman_decode(d, Table, 6); + +    *SCFI = value >> 1; +    *DSCF = value &  1; +} + +static void +mpc_decoder_reset_v(mpc_decoder *d)  +{ +    memset(d->V_L, 0, sizeof d->V_L); +    memset(d->V_R, 0, sizeof d->V_R); +} + +static void +mpc_decoder_reset_synthesis(mpc_decoder *d)  +{ +    mpc_decoder_reset_v(d); +} + +static void +mpc_decoder_reset_y(mpc_decoder *d)  +{ +    memset(d->Y_L, 0, sizeof d->Y_L); +    memset(d->Y_R, 0, sizeof d->Y_R); +} + +static void +mpc_decoder_reset_globals(mpc_decoder *d)  +{ +    mpc_decoder_reset_bitstream_decode(d); + +    d->DecodedFrames  = 0; +    d->StreamVersion  = 0; +    d->MS_used        = 0; + +    memset(d->Y_L             , 0, sizeof d->Y_L              ); +    memset(d->Y_R             , 0, sizeof d->Y_R              ); +    memset(d->SCF_Index_L     , 0, sizeof d->SCF_Index_L      ); +    memset(d->SCF_Index_R     , 0, sizeof d->SCF_Index_R      ); +    memset(d->Res_L           , 0, sizeof d->Res_L            ); +    memset(d->Res_R           , 0, sizeof d->Res_R            ); +    memset(d->SCFI_L          , 0, sizeof d->SCFI_L           ); +    memset(d->SCFI_R          , 0, sizeof d->SCFI_R           ); +    memset(d->DSCF_Flag_L     , 0, sizeof d->DSCF_Flag_L      ); +    memset(d->DSCF_Flag_R     , 0, sizeof d->DSCF_Flag_R      ); +    memset(d->Q               , 0, sizeof d->Q                ); +    memset(d->MS_Flag         , 0, sizeof d->MS_Flag          ); +    memset(d->seeking_table   , 0, sizeof d->seeking_table    ); +} + +// Frame decoding. Takes big endian 32 bits words as input +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) +{ +  unsigned int i; +  mpc_decoder_reset_bitstream_decode(d); +  if (in_len > sizeof(d->Speicher)) in_len = sizeof(d->Speicher); +  memcpy(d->Speicher, in_buffer, in_len); +  for (i = 0; i < (in_len + 3) / 4; i++) +    d->Speicher[i] = mpc_swap32(d->Speicher[i]); +  d->dword = SWAP(d->Speicher[0]); +  switch (d->StreamVersion) { +#ifdef MPC_SUPPORT_SV456 +    case 0x04: +    case 0x05: +    case 0x06: +        mpc_decoder_read_bitstream_sv6(d, FALSE); +        break; +#endif +    case 0x07: +    case 0x17: +        mpc_decoder_read_bitstream_sv7(d, FALSE); +        break; +    default: +        return (mpc_uint32_t)(-1); +  } +  mpc_decoder_requantisierung(d, d->Max_Band); +  mpc_decoder_synthese_filter_float(d, out_buffer); +  return mpc_decoder_bits_read(d); +} + +static mpc_uint32_t +mpc_decoder_decode_internal(mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer)  +{ +    mpc_uint32_t output_frame_length = MPC_FRAME_LENGTH; +    mpc_uint32_t FwdJumpInfo = 0; +    mpc_uint32_t  FrameBitCnt = 0; + +    if (d->DecodedFrames >= d->OverallFrames) { +        return (mpc_uint32_t)(-1);                           // end of file -> abort decoding +    } + +    // add seeking info +    if (d->seeking_table_frames < d->DecodedFrames && +       (d->DecodedFrames & ((1 << d->seeking_pwr) - 1)) == 0) { +        d->seeking_table[d->DecodedFrames >> d->seeking_pwr] = mpc_decoder_bits_read(d); +        d->seeking_table_frames = d->DecodedFrames; +    } + +    // read jump-info for validity check of frame +    FwdJumpInfo  = mpc_decoder_bitstream_read(d, 20); + +    // decode data and check for validity of frame +    FrameBitCnt = mpc_decoder_bits_read(d); +    switch (d->StreamVersion) { +#ifdef MPC_SUPPORT_SV456 +    case 0x04: +    case 0x05: +    case 0x06: +        mpc_decoder_read_bitstream_sv6(d, FALSE); +        break; +#endif +    case 0x07: +    case 0x17: +        mpc_decoder_read_bitstream_sv7(d, FALSE); +        break; +    default: +        return (mpc_uint32_t)(-1); +    } +    d->FrameWasValid = mpc_decoder_bits_read(d) - FrameBitCnt == FwdJumpInfo; + +    // synthesize signal +    mpc_decoder_requantisierung(d, d->Max_Band); +    mpc_decoder_synthese_filter_float(d, buffer); + +    d->DecodedFrames++; + +    // cut off first MPC_DECODER_SYNTH_DELAY zero-samples +    if (d->DecodedFrames == d->OverallFrames  && d->StreamVersion >= 6) {         +        // reconstruct exact filelength +        mpc_int32_t  mod_block   = mpc_decoder_bitstream_read(d,  11); +        mpc_int32_t  FilterDecay; + +        if (mod_block == 0) { +            // Encoder bugfix +            mod_block = 1152;                     +        } +        FilterDecay = (mod_block + MPC_DECODER_SYNTH_DELAY) % MPC_FRAME_LENGTH; + +        // additional FilterDecay samples are needed for decay of synthesis filter +        if (MPC_DECODER_SYNTH_DELAY + mod_block >= MPC_FRAME_LENGTH) { +            if (!d->TrueGaplessPresent) { +                mpc_decoder_reset_y(d); +            } else { +                mpc_decoder_bitstream_read(d, 20); +                mpc_decoder_read_bitstream_sv7(d, FALSE); +                mpc_decoder_requantisierung(d, d->Max_Band); +            } + +            mpc_decoder_synthese_filter_float(d, buffer + 2304); + +            output_frame_length = MPC_FRAME_LENGTH + FilterDecay; +        } +        else {                              // there are only FilterDecay samples needed for this frame +            output_frame_length = FilterDecay; +        } +    } + +    if (d->samples_to_skip) { +        if (output_frame_length < d->samples_to_skip) { +            d->samples_to_skip -= output_frame_length; +            output_frame_length = 0; +        } +        else { +            output_frame_length -= d->samples_to_skip; +            memmove( +                buffer,  +                buffer + d->samples_to_skip * 2,  +                output_frame_length * 2 * sizeof (MPC_SAMPLE_FORMAT)); +            d->samples_to_skip = 0; +        } +    } + +    return output_frame_length; +} + +mpc_uint32_t mpc_decoder_decode( +    mpc_decoder *d, +    MPC_SAMPLE_FORMAT *buffer,  +    mpc_uint32_t *vbr_update_acc,  +    mpc_uint32_t *vbr_update_bits) +{ +    for(;;) +    { +        //const mpc_int32_t MaxBrokenFrames = 0; // PluginSettings.MaxBrokenFrames + +        mpc_uint32_t RING = d->Zaehler; +        mpc_int32_t vbr_ring = (RING << 5) + d->pos; + +        mpc_uint32_t valid_samples = mpc_decoder_decode_internal(d, buffer); + +        if (valid_samples == (mpc_uint32_t)(-1) ) { +            return 0; +        } + +        /**************** ERROR CONCEALMENT *****************/ +        if (d->FrameWasValid == 0 ) { +            // error occurred in bitstream +            return (mpc_uint32_t)(-1); +        }  +        else { +            if (vbr_update_acc && vbr_update_bits) { +                (*vbr_update_acc) ++; +                vbr_ring = (d->Zaehler << 5) + d->pos - vbr_ring; +                if (vbr_ring < 0) { +                    vbr_ring += 524288; +                } +                (*vbr_update_bits) += vbr_ring; +            } + +        } +        mpc_decoder_update_buffer(d, RING); + +        if (valid_samples > 0) { +            return valid_samples; +        } +    } +} + +void +mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band)  +{ +    mpc_int32_t     Band; +    mpc_int32_t     n; +    MPC_SAMPLE_FORMAT facL; +    MPC_SAMPLE_FORMAT facR; +    MPC_SAMPLE_FORMAT templ; +    MPC_SAMPLE_FORMAT tempr; +    MPC_SAMPLE_FORMAT* YL; +    MPC_SAMPLE_FORMAT* YR; +    mpc_int32_t*    L; +    mpc_int32_t*    R; + +#ifdef MPC_FIXED_POINT +#if MPC_FIXED_POINT_FRACTPART == 14 +#define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \ +    MPC_MULTIPLY_EX(CcVal, d->SCF[SCF_idx], d->SCF_shift[SCF_idx]) +#else + +#error FIXME, Cc table is in 18.14 format + +#endif +#else +#define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \ +    MPC_MULTIPLY(CcVal, d->SCF[SCF_idx]) +#endif +    // requantization and scaling of subband-samples +    for ( Band = 0; Band <= Last_Band; Band++ ) {   // setting pointers +        YL = d->Y_L[0] + Band; +        YR = d->Y_R[0] + Band; +        L  = d->Q[Band].L; +        R  = d->Q[Band].R; +        /************************** MS-coded **************************/ +        if ( d->MS_Flag [Band] ) { +            if ( d->Res_L [Band] ) { +                if ( d->Res_R [Band] ) {    // M!=0, S!=0 +                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]); +                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]); +                    for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { +                        *YL   = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); +                        *YR   = templ - tempr; +                    } +                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]); +                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]); +                    for ( ; n < 24; n++, YL += 32, YR += 32 ) { +                        *YL   = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); +                        *YR   = templ - tempr; +                    } +                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]); +                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]); +                    for ( ; n < 36; n++, YL += 32, YR += 32 ) { +                        *YL   = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); +                        *YR   = templ - tempr; +                    } +                } else {    // M!=0, S==0 +                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]); +                    for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { +                        *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); +                    } +                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]); +                    for ( ; n < 24; n++, YL += 32, YR += 32 ) { +                        *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); +                    } +                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]); +                    for ( ; n < 36; n++, YL += 32, YR += 32 ) { +                        *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); +                    } +                } +            } else { +                if (d->Res_R[Band])    // M==0, S!=0 +                { +                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]); +                    for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { +                        *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); +                    } +                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]); +                    for ( ; n < 24; n++, YL += 32, YR += 32 ) { +                        *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); +                    } +                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]); +                    for ( ; n < 36; n++, YL += 32, YR += 32 ) { +                        *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); +                    } +                } else {    // M==0, S==0 +                    for ( n = 0; n < 36; n++, YL += 32, YR += 32 ) { +                        *YR = *YL = 0; +                    } +                } +            } +        } +        /************************** LR-coded **************************/ +        else { +            if ( d->Res_L [Band] ) { +                if ( d->Res_R [Band] ) {    // L!=0, R!=0 +                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]); +                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]); +                    for (n = 0; n < 12; n++, YL += 32, YR += 32 ) { +                        *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); +                        *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); +                    } +                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]); +                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]); +                    for (; n < 24; n++, YL += 32, YR += 32 ) { +                        *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); +                        *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); +                    } +                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]); +                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]); +                    for (; n < 36; n++, YL += 32, YR += 32 ) { +                        *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); +                        *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); +                    } +                } else {     // L!=0, R==0 +                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]); +                    for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { +                        *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); +                        *YR = 0; +                    } +                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]); +                    for ( ; n < 24; n++, YL += 32, YR += 32 ) { +                        *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); +                        *YR = 0; +                    } +                    facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]); +                    for ( ; n < 36; n++, YL += 32, YR += 32 ) { +                        *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); +                        *YR = 0; +                    } +                } +            } +            else { +                if ( d->Res_R [Band] ) {    // L==0, R!=0 +                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]); +                    for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { +                        *YL = 0; +                        *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); +                    } +                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]); +                    for ( ; n < 24; n++, YL += 32, YR += 32 ) { +                        *YL = 0; +                        *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); +                    } +                    facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]); +                    for ( ; n < 36; n++, YL += 32, YR += 32 ) { +                        *YL = 0; +                        *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); +                    } +                } else {    // L==0, R==0 +                    for ( n = 0; n < 36; n++, YL += 32, YR += 32 ) { +                        *YR = *YL = 0; +                    } +                } +            } +        } +    } +} + +#ifdef MPC_SUPPORT_SV456 +static const unsigned char Q_res[32][16] = { +{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, +{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, +{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, +{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, +{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, +{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, +{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, +{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, +{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, +{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, +{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, +{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, +{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, +{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, +{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, +{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, +{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, +{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, +{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, +{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, +{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, +{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, +{0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, +{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, +{0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, +}; + +/****************************************** SV 6 ******************************************/ +void +mpc_decoder_read_bitstream_sv6(mpc_decoder *d, mpc_bool_t seeking) +{ +    mpc_int32_t n,k; +    mpc_int32_t Max_used_Band=0; +    const HuffmanTyp *Table; +    const HuffmanTyp *x1; +    const HuffmanTyp *x2; +    mpc_int32_t *L; +    mpc_int32_t *R; +    mpc_int32_t *ResL = d->Res_L; +    mpc_int32_t *ResR = d->Res_R; + +    /************************ HEADER **************************/ +    ResL = d->Res_L; +    ResR = d->Res_R; +    for (n=0; n <= d->Max_Band; ++n, ++ResL, ++ResR) +    { +        if      (n<11)           Table = mpc_table_Region_A; +        else if (n>=11 && n<=22) Table = mpc_table_Region_B; +        else /*if (n>=23)*/      Table = mpc_table_Region_C; + +        *ResL = Q_res[n][mpc_decoder_huffman_decode(d, Table, 14)]; +        if (d->MS_used) { +            d->MS_Flag[n] = mpc_decoder_bitstream_read(d,  1); +        } +        *ResR = Q_res[n][mpc_decoder_huffman_decode(d, Table, 14)]; + +        // only perform the following procedure up to the maximum non-zero subband +        if (*ResL || *ResR) Max_used_Band = n; +    } + +    /************************* SCFI-Bundle *****************************/ +    ResL = d->Res_L; +    ResR = d->Res_R; +    for (n=0; n<=Max_used_Band; ++n, ++ResL, ++ResR) { +        if (*ResL) mpc_decoder_scfi_bundle_read(d, mpc_table_SCFI_Bundle, &(d->SCFI_L[n]), &(d->DSCF_Flag_L[n])); +        if (*ResR) mpc_decoder_scfi_bundle_read(d, mpc_table_SCFI_Bundle, &(d->SCFI_R[n]), &(d->DSCF_Flag_R[n])); +    } + +    /***************************** SCFI ********************************/ +    ResL = d->Res_L; +    ResR = d->Res_R; +    L    = d->SCF_Index_L[0]; +    R    = d->SCF_Index_R[0]; +    for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR, L+=3, R+=3) +    { +        if (*ResL) +        { +            /*********** DSCF ************/ +            if (d->DSCF_Flag_L[n]==1) +            { +                switch (d->SCFI_L[n]) +                { +                case 3: +                    L[0] = L[2] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    L[1] = L[0]; +                    L[2] = L[1]; +                    break; +                case 1: +                    L[0] = L[2] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    L[1] = L[0] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    L[2] = L[1]; +                    break; +                case 2: +                    L[0] = L[2] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    L[1] = L[0]; +                    L[2] = L[1] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    break; +                case 0: +                    L[0] = L[2] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    L[1] = L[0] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    L[2] = L[1] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    break; +                default: +                    return; +                } +                if (L[0] > 1024) +                    L[0] = 0x8080; +                if (L[1] > 1024) +                    L[1] = 0x8080; +                if (L[2] > 1024) +                    L[2] = 0x8080; +            } +            /************ SCF ************/ +            else +            { +                switch (d->SCFI_L[n]) +                { +                case 3: +                    L[0] = mpc_decoder_bitstream_read(d,  6); +                    L[1] = L[0]; +                    L[2] = L[1]; +                    break; +                case 1: +                    L[0] = mpc_decoder_bitstream_read(d,  6); +                    L[1] = mpc_decoder_bitstream_read(d,  6); +                    L[2] = L[1]; +                    break; +                case 2: +                    L[0] = mpc_decoder_bitstream_read(d,  6); +                    L[1] = L[0]; +                    L[2] = mpc_decoder_bitstream_read(d,  6); +                    break; +                case 0: +                    L[0] = mpc_decoder_bitstream_read(d,  6); +                    L[1] = mpc_decoder_bitstream_read(d,  6); +                    L[2] = mpc_decoder_bitstream_read(d,  6); +                    break; +                default: +                    return; +                } +            } +        } +        if (*ResR) +        { +            /*********** DSCF ************/ +            if (d->DSCF_Flag_R[n]==1) +            { +                switch (d->SCFI_R[n]) +                { +                case 3: +                    R[0] = R[2] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    R[1] = R[0]; +                    R[2] = R[1]; +                    break; +                case 1: +                    R[0] = R[2] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    R[1] = R[0] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    R[2] = R[1]; +                    break; +                case 2: +                    R[0] = R[2] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    R[1] = R[0]; +                    R[2] = R[1] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    break; +                case 0: +                    R[0] = R[2] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    R[1] = R[0] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    R[2] = R[1] + mpc_decoder_huffman_decode(d,  mpc_table_DSCF_Entropie, 6); +                    break; +                default: +                    return; +                } +                if (R[0] > 1024) +                    R[0] = 0x8080; +                if (R[1] > 1024) +                    R[1] = 0x8080; +                if (R[2] > 1024) +                    R[2] = 0x8080; +            } +            /************ SCF ************/ +            else +            { +                switch (d->SCFI_R[n]) +                { +                case 3: +                    R[0] = mpc_decoder_bitstream_read(d, 6); +                    R[1] = R[0]; +                    R[2] = R[1]; +                    break; +                case 1: +                    R[0] = mpc_decoder_bitstream_read(d, 6); +                    R[1] = mpc_decoder_bitstream_read(d, 6); +                    R[2] = R[1]; +                    break; +                case 2: +                    R[0] = mpc_decoder_bitstream_read(d, 6); +                    R[1] = R[0]; +                    R[2] = mpc_decoder_bitstream_read(d, 6); +                    break; +                case 0: +                    R[0] = mpc_decoder_bitstream_read(d, 6); +                    R[1] = mpc_decoder_bitstream_read(d, 6); +                    R[2] = mpc_decoder_bitstream_read(d, 6); +                    break; +                default: +                    return; +                    break; +                } +            } +        } +    } + +    if (seeking == TRUE) +        return; + +    /**************************** Samples ****************************/ +    ResL = d->Res_L; +    ResR = d->Res_R; +    for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR) +    { +        // setting pointers +        x1 = mpc_table_SampleHuff[*ResL]; +        x2 = mpc_table_SampleHuff[*ResR]; +        L = d->Q[n].L; +        R = d->Q[n].R; + +        if (x1!=NULL || x2!=NULL) +            for (k=0; k<36; ++k) +            { +                if (x1 != NULL) *L++ = mpc_decoder_huffman_decode(d,  x1, 8); +                if (x2 != NULL) *R++ = mpc_decoder_huffman_decode(d,  x2, 8); +            } + +        if (*ResL>7 || *ResR>7) +            for (k=0; k<36; ++k) +            { +                if (*ResL>7) *L++ = (mpc_int32_t)mpc_decoder_bitstream_read(d,  Res_bit[*ResL]) - Dc[*ResL]; +                if (*ResR>7) *R++ = (mpc_int32_t)mpc_decoder_bitstream_read(d,  Res_bit[*ResR]) - Dc[*ResR]; +            } +    } +} +#endif //MPC_SUPPORT_SV456 +/****************************************** SV 7 ******************************************/ +void +mpc_decoder_read_bitstream_sv7(mpc_decoder *d, mpc_bool_t seeking) +{ +    // these arrays hold decoding results for bundled quantizers (3- and 5-step) +    static const mpc_int32_t idx30[] = { -1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1}; +    static const mpc_int32_t idx31[] = { -1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1}; +    static const mpc_int32_t idx32[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}; +    static const mpc_int32_t idx50[] = { -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2}; +    static const mpc_int32_t idx51[] = { -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2}; + +    mpc_int32_t n,k; +    mpc_int32_t Max_used_Band=0; +    const HuffmanTyp *Table; +    mpc_int32_t idx; +    mpc_int32_t *L   ,*R; +    mpc_int32_t *ResL,*ResR; +    mpc_uint32_t tmp; + +    /***************************** Header *****************************/ +    ResL  = d->Res_L; +    ResR  = d->Res_R; + +    // first subband +    *ResL = mpc_decoder_bitstream_read(d, 4); +    *ResR = mpc_decoder_bitstream_read(d, 4); +    if (d->MS_used && !(*ResL==0 && *ResR==0)) { +        d->MS_Flag[0] = mpc_decoder_bitstream_read(d, 1); +    } + +    // consecutive subbands +    ++ResL; ++ResR; // increase pointers +    for (n=1; n <= d->Max_Band; ++n, ++ResL, ++ResR) +    { +        idx   = mpc_decoder_huffman_decode(d, mpc_table_HuffHdr, 9); +        *ResL = (idx!=4) ? *(ResL-1) + idx : (int) mpc_decoder_bitstream_read(d, 4); + +        idx   = mpc_decoder_huffman_decode(d, mpc_table_HuffHdr, 9); +        *ResR = (idx!=4) ? *(ResR-1) + idx : (int) mpc_decoder_bitstream_read(d, 4); + +        if (d->MS_used && !(*ResL==0 && *ResR==0)) { +            d->MS_Flag[n] = mpc_decoder_bitstream_read(d, 1); +        } + +        // only perform following procedures up to the maximum non-zero subband +        if (*ResL!=0 || *ResR!=0) { +            Max_used_Band = n; +        } +    } +    /****************************** SCFI ******************************/ +    L     = d->SCFI_L; +    R     = d->SCFI_R; +    ResL  = d->Res_L; +    ResR  = d->Res_R; +    for (n=0; n <= Max_used_Band; ++n, ++L, ++R, ++ResL, ++ResR) { +        if (*ResL) *L = mpc_decoder_huffman_decode(d, mpc_table_HuffSCFI, 3); +        if (*ResR) *R = mpc_decoder_huffman_decode(d, mpc_table_HuffSCFI, 3); +    } + +    /**************************** SCF/DSCF ****************************/ +    ResL  = d->Res_L; +    ResR  = d->Res_R; +    L     = d->SCF_Index_L[0]; +    R     = d->SCF_Index_R[0]; +    for (n=0; n<=Max_used_Band; ++n, ++ResL, ++ResR, L+=3, R+=3) { +        if (*ResL) +        { +            switch (d->SCFI_L[n]) +            { +            case 1: +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                L[0] = (idx!=8) ? L[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                L[1] = (idx!=8) ? L[0] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                L[2] = L[1]; +                break; +            case 3: +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                L[0] = (idx!=8) ? L[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                L[1] = L[0]; +                L[2] = L[1]; +                break; +            case 2: +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                L[0] = (idx!=8) ? L[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                L[1] = L[0]; +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                L[2] = (idx!=8) ? L[1] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                break; +            case 0: +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                L[0] = (idx!=8) ? L[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                L[1] = (idx!=8) ? L[0] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                L[2] = (idx!=8) ? L[1] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                break; +            default: +                return; +            } +            if (L[0] > 1024) +                L[0] = 0x8080; +            if (L[1] > 1024) +                L[1] = 0x8080; +            if (L[2] > 1024) +                L[2] = 0x8080; +        } +        if (*ResR) +        { +            switch (d->SCFI_R[n]) +            { +            case 1: +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                R[0] = (idx!=8) ? R[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                R[1] = (idx!=8) ? R[0] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                R[2] = R[1]; +                break; +            case 3: +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                R[0] = (idx!=8) ? R[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                R[1] = R[0]; +                R[2] = R[1]; +                break; +            case 2: +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                R[0] = (idx!=8) ? R[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                R[1] = R[0]; +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                R[2] = (idx!=8) ? R[1] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                break; +            case 0: +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                R[0] = (idx!=8) ? R[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                R[1] = (idx!=8) ? R[0] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                idx  = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); +                R[2] = (idx!=8) ? R[1] + idx : (int) mpc_decoder_bitstream_read(d, 6); +                break; +            default: +                return; +            } +            if (R[0] > 1024) +                R[0] = 0x8080; +            if (R[1] > 1024) +                R[1] = 0x8080; +            if (R[2] > 1024) +                R[2] = 0x8080; +        } +    } + +    if (seeking == TRUE) +        return; + +    /***************************** Samples ****************************/ +    ResL = d->Res_L; +    ResR = d->Res_R; +    L    = d->Q[0].L; +    R    = d->Q[0].R; +    for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR, L+=36, R+=36) +    { +        /************** links **************/ +        switch (*ResL) +        { +        case  -2: case  -3: case  -4: case  -5: case  -6: case  -7: case  -8: case  -9: +        case -10: case -11: case -12: case -13: case -14: case -15: case -16: case -17: +            L += 36; +            break; +        case -1: +            for (k=0; k<36; k++ ) { +                tmp  = mpc_random_int(d); +                *L++ = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >>  8) & 0xFF) + ((tmp >>  0) & 0xFF) - 510; +            } +            break; +        case 0: +            L += 36;// increase pointer +            break; +        case 1: +            Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][1]; +            for (k=0; k<12; ++k) +            { +                idx = mpc_decoder_huffman_decode(d, Table, 9); +                *L++ = idx30[idx]; +                *L++ = idx31[idx]; +                *L++ = idx32[idx]; +            } +            break; +        case 2: +            Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][2]; +            for (k=0; k<18; ++k) +            { +                idx = mpc_decoder_huffman_decode(d, Table, 10); +                *L++ = idx50[idx]; +                *L++ = idx51[idx]; +            } +            break; +        case 3: +        case 4: +            Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResL]; +            for (k=0; k<36; ++k) +                *L++ = mpc_decoder_huffman_decode(d, Table, 5); +            break; +        case 5: +            Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResL]; +            for (k=0; k<36; ++k) +                *L++ = mpc_decoder_huffman_decode(d, Table, 8); +            break; +        case 6: +        case 7: +            Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResL]; +            for (k=0; k<36; ++k) +                *L++ = mpc_decoder_huffman_decode(d, Table, 14); +            break; +        case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: +            tmp = Dc[*ResL]; +            for (k=0; k<36; ++k) +                *L++ = (mpc_int32_t)mpc_decoder_bitstream_read(d, Res_bit[*ResL]) - tmp; +            break; +        default: +            return; +        } +        /************** rechts **************/ +        switch (*ResR) +        { +        case  -2: case  -3: case  -4: case  -5: case  -6: case  -7: case  -8: case  -9: +        case -10: case -11: case -12: case -13: case -14: case -15: case -16: case -17: +            R += 36; +            break; +        case -1: +                for (k=0; k<36; k++ ) { +                    tmp  = mpc_random_int(d); +                    *R++ = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >>  8) & 0xFF) + ((tmp >>  0) & 0xFF) - 510; +                } +                break; +            case 0: +                R += 36;// increase pointer +                break; +            case 1: +                Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][1]; +                for (k=0; k<12; ++k) +                { +                    idx = mpc_decoder_huffman_decode(d, Table, 9); +                    *R++ = idx30[idx]; +                    *R++ = idx31[idx]; +                    *R++ = idx32[idx]; +                } +                break; +            case 2: +                Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][2]; +                for (k=0; k<18; ++k) +                { +                    idx = mpc_decoder_huffman_decode(d, Table, 10); +                    *R++ = idx50[idx]; +                    *R++ = idx51[idx]; +                } +                break; +            case 3: +            case 4: +                Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResR]; +                for (k=0; k<36; ++k) +                    *R++ = mpc_decoder_huffman_decode(d, Table, 5); +                break; +            case 5: +                Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResR]; +                for (k=0; k<36; ++k) +                    *R++ = mpc_decoder_huffman_decode(d, Table, 8); +                break; +            case 6: +            case 7: +                Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResR]; +                for (k=0; k<36; ++k) +                    *R++ = mpc_decoder_huffman_decode(d, Table, 14); +                break; +            case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: +                tmp = Dc[*ResR]; +                for (k=0; k<36; ++k) +                    *R++ = (mpc_int32_t)mpc_decoder_bitstream_read(d, Res_bit[*ResR]) - tmp; +                break; +            default: +                return; +        } +    } +} + +void mpc_decoder_setup(mpc_decoder *d, mpc_reader *r) +{ +  d->r = r; + +  d->MPCHeaderPos = 0; +  d->StreamVersion = 0; +  d->MS_used = 0; +  d->FrameWasValid = 0; +  d->OverallFrames = 0; +  d->DecodedFrames = 0; +  d->TrueGaplessPresent = 0; +  d->WordsRead = 0; +  d->Max_Band = 0; +  d->SampleRate = 0; +  d->__r1 = 1; +  d->__r2 = 1; + +  d->Max_Band = 0; +  d->seeking_window = FAST_SEEKING_WINDOW; + +  mpc_decoder_reset_bitstream_decode(d); +  mpc_decoder_initialisiere_quantisierungstabellen(d, 1.0f); +#if 0 +  mpc_decoder_init_huffman_sv6(d); +  mpc_decoder_init_huffman_sv7(d); +#endif +} + +static mpc_uint32_t get_initial_fpos(mpc_decoder *d) +{ +    mpc_uint32_t fpos = 0; +    switch ( d->StreamVersion ) {   // setting position to the beginning of the data-bitstream +    case  0x04: fpos =  48; break; +    case  0x05: +    case  0x06: fpos =  64; break; +    case  0x07: +    case  0x17: fpos = 200; break; +    } +    return fpos; +} + +void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si) +{ +    mpc_decoder_reset_synthesis(d); +    mpc_decoder_reset_globals(d); + +    d->StreamVersion      = si->stream_version; +    d->MS_used            = si->ms; +    d->Max_Band           = si->max_band; +    d->OverallFrames      = si->frames; +    d->MPCHeaderPos       = si->header_position; +    d->TrueGaplessPresent = si->is_true_gapless; +    d->SampleRate         = (mpc_int32_t)si->sample_freq; + +    d->samples_to_skip = MPC_DECODER_SYNTH_DELAY; +} + +mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si)  +{ +    mpc_decoder_set_streaminfo(d, si); + +    // AB: setting position to the beginning of the data-bitstream +    mpc_decoder_seek(d, get_initial_fpos(d)); + +    d->seeking_pwr = 0; +    while( d->OverallFrames > ((mpc_int64_t) SEEKING_TABLE_SIZE << d->seeking_pwr) ) +        d->seeking_pwr++; +    d->seeking_table_frames = 0; +    d->seeking_table[0] = get_initial_fpos(d); + +    return TRUE; +} + +void mpc_decoder_set_seeking(mpc_decoder *d, mpc_streaminfo *si, mpc_bool_t fast_seeking) +{ +    d->seeking_window = FAST_SEEKING_WINDOW; +    if (si->fast_seek == 0 && fast_seeking == 0) +        d->seeking_window = SLOW_SEEKING_WINDOW; +} + +mpc_bool_t mpc_decoder_seek_seconds(mpc_decoder *d, double seconds)  +{ +    return mpc_decoder_seek_sample(d, (mpc_int64_t)(seconds * (double)d->SampleRate + 0.5)); +} + +mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample)  +{ +    mpc_uint32_t fpos; +    mpc_uint32_t fwd; + +    fwd = (mpc_uint32_t) (destsample / MPC_FRAME_LENGTH); +    d->samples_to_skip = MPC_DECODER_SYNTH_DELAY + (mpc_uint32_t)(destsample % MPC_FRAME_LENGTH); + +    // resetting synthesis filter to avoid "clicks" +    mpc_decoder_reset_synthesis(d); + +    // prevent from desired position out of allowed range +    fwd = fwd < d->OverallFrames  ?  fwd  :  d->OverallFrames; + +    if (fwd > d->DecodedFrames + d->seeking_window || fwd < d->DecodedFrames) { +        memset(d->SCF_Index_L, 1, sizeof d->SCF_Index_L ); +        memset(d->SCF_Index_R, 1, sizeof d->SCF_Index_R ); +    } + +    if (d->seeking_table_frames > d->DecodedFrames || fwd < d->DecodedFrames) { +        d->DecodedFrames = 0; +        if (fwd > d->seeking_window) +            d->DecodedFrames = (fwd - d->seeking_window) & (-1 << d->seeking_pwr); +        if (d->DecodedFrames > d->seeking_table_frames) +            d->DecodedFrames = d->seeking_table_frames; +        fpos = d->seeking_table[d->DecodedFrames >> d->seeking_pwr]; +        mpc_decoder_seek(d, fpos); +    } + +    // read the last 32 frames before the desired position to scan the scalefactors (artifactless jumping) +    for ( ; d->DecodedFrames < fwd; d->DecodedFrames++ ) { +        mpc_uint32_t RING = d->Zaehler; +        mpc_uint32_t FwdJumpInfo; + +        // add seeking info +        if (d->seeking_table_frames < d->DecodedFrames && +           (d->DecodedFrames & ((1 << d->seeking_pwr) - 1)) == 0) { +            d->seeking_table[d->DecodedFrames >> d->seeking_pwr] = mpc_decoder_bits_read(d); +            d->seeking_table_frames = d->DecodedFrames; +        } + +        // read jump-info +        FwdJumpInfo  = mpc_decoder_bitstream_read(d, 20); +        FwdJumpInfo += mpc_decoder_bits_read(d); + +        if (fwd <= d->DecodedFrames + d->seeking_window) { +            if (d->StreamVersion >= 7) { +                mpc_decoder_read_bitstream_sv7(d, TRUE); +            } else { +#ifdef MPC_SUPPORT_SV456 +                mpc_decoder_read_bitstream_sv6(d, TRUE); +#else +                return FALSE; +#endif +            } +        } +        mpc_decoder_bitstream_jump(d, FwdJumpInfo - mpc_decoder_bits_read(d)); + +        // update buffer +        mpc_decoder_update_buffer(d, RING); +    } + +    return TRUE; +} diff --git a/contrib/libmpcdec/mpc_reader.c b/contrib/libmpcdec/mpc_reader.c new file mode 100644 index 000000000..1d0accc01 --- /dev/null +++ b/contrib/libmpcdec/mpc_reader.c @@ -0,0 +1,96 @@ +/* +  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 mpc_reader.c +/// Contains implementations for simple file-based mpc_reader + +#include <mpcdec/mpcdec.h> + +/// mpc_reader callback implementations +static mpc_int32_t +read_impl(void *data, void *ptr, mpc_int32_t size) +{ +    mpc_reader_file *d = (mpc_reader_file *) data; + +    return (mpc_int32_t) fread(ptr, 1, size, d->file); +} + +static mpc_bool_t +seek_impl(void *data, mpc_int32_t offset) +{ +    mpc_reader_file *d = (mpc_reader_file *) data; + +    return d->is_seekable ? fseek(d->file, offset, SEEK_SET) == 0 : FALSE; +} + +static mpc_int32_t +tell_impl(void *data) +{ +    mpc_reader_file *d = (mpc_reader_file *) data; + +    return ftell(d->file); +} + +static mpc_int32_t +get_size_impl(void *data) +{ +    mpc_reader_file *d = (mpc_reader_file *) data; + +    return d->file_size; +} + +static mpc_bool_t +canseek_impl(void *data) +{ +    mpc_reader_file *d = (mpc_reader_file *) data; + +    return d->is_seekable; +} + +void +mpc_reader_setup_file_reader(mpc_reader_file *p_reader, FILE *input) +{ +    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); +} diff --git a/contrib/libmpcdec/mpcdec/config_types.h b/contrib/libmpcdec/mpcdec/config_types.h new file mode 100644 index 000000000..98c6cf21b --- /dev/null +++ b/contrib/libmpcdec/mpcdec/config_types.h @@ -0,0 +1,50 @@ +/* +  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__ + +#include <xine/os_types.h> + +typedef unsigned char mpc_bool_t; +#define TRUE  1 +#define FALSE 0 + +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; + +#endif // __MUSEPACK_CONFIG_TYPES_H__ diff --git a/contrib/libmpcdec/mpcdec/decoder.h b/contrib/libmpcdec/mpcdec/decoder.h new file mode 100644 index 000000000..9a737453e --- /dev/null +++ b/contrib/libmpcdec/mpcdec/decoder.h @@ -0,0 +1,124 @@ +/* +  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 decoder.h + +#ifndef _mpcdec_decoder_h_ +#define _mpcdec_decoder_h_ + +#include "huffman.h" +#include "math.h" +#include "mpcdec.h" +#include "reader.h" +#include "streaminfo.h" + +#define MPC_SUPPORT_SV456 + +#define SEEKING_TABLE_SIZE  256u +// set it to SLOW_SEEKING_WINDOW to not use fast seeking +#define FAST_SEEKING_WINDOW 32 +// set it to FAST_SEEKING_WINDOW to only use fast seeking +#define SLOW_SEEKING_WINDOW 0x80000000 + +enum { +    MPC_V_MEM = 2304, +    MPC_DECODER_MEMSIZE = 16384,  // overall buffer size +}; + +typedef struct { +    mpc_int32_t  L [36]; +    mpc_int32_t  R [36]; +} QuantTyp; + +typedef struct mpc_decoder_t { +    mpc_reader *r; + +    /// @name internal state variables +    //@{ + +    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_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 + +    // 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_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_int32_t   Res_L [32]; +    mpc_int32_t   Res_R [32];                 // holds the chosen quantizer for each subband +    mpc_bool_t    DSCF_Flag_L [32]; +    mpc_bool_t    DSCF_Flag_R [32];           // differential SCF used? +    mpc_int32_t   SCFI_L [32]; +    mpc_int32_t   SCFI_R [32];                // describes order of transmitted SCF +    mpc_bool_t    MS_Flag[32];                // MS used? +#ifdef MPC_FIXED_POINT +    unsigned char SCF_shift[256]; +#endif + +    MPC_SAMPLE_FORMAT V_L[MPC_V_MEM + 960]; +    MPC_SAMPLE_FORMAT V_R[MPC_V_MEM + 960]; +    MPC_SAMPLE_FORMAT Y_L[36][32]; +    MPC_SAMPLE_FORMAT Y_R[36][32]; +    MPC_SAMPLE_FORMAT SCF[256]; ///< holds adapted scalefactors (for clipping prevention) +    //@} + +} mpc_decoder; + +#endif // _mpc_decoder_h diff --git a/contrib/libmpcdec/mpcdec/huffman.h b/contrib/libmpcdec/mpcdec/huffman.h new file mode 100644 index 000000000..99d02ce71 --- /dev/null +++ b/contrib/libmpcdec/mpcdec/huffman.h @@ -0,0 +1,58 @@ +/* +  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 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" +#endif + +#include "decoder.h" + +struct mpc_decoder_t; // forward declare to break circular dependencies + +/// Huffman table entry. +typedef struct huffman_type_t { +    mpc_uint32_t  Code; +    mpc_uint16_t  Length; +    mpc_int16_t   Value; +} HuffmanTyp; + +#endif // _mpcdec_huffman_h_ diff --git a/contrib/libmpcdec/mpcdec/internal.h b/contrib/libmpcdec/mpcdec/internal.h new file mode 100644 index 000000000..19642a240 --- /dev/null +++ b/contrib/libmpcdec/mpcdec/internal.h @@ -0,0 +1,65 @@ +/* +  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 + diff --git a/contrib/libmpcdec/mpcdec/math.h b/contrib/libmpcdec/mpcdec/math.h new file mode 100644 index 000000000..31d078896 --- /dev/null +++ b/contrib/libmpcdec/mpcdec/math.h @@ -0,0 +1,144 @@ +/* +  Copyright (c) 2005, The Musepack Development Team +  All rights reserved. + +  Redistribution and use in source and binary forms, with or without +  modification, are permitted provided that the following conditions are +  met: + +  * Redistributions of source code must retain the above copyright +  notice, this list of conditions and the following disclaimer. + +  * Redistributions in binary form must reproduce the above +  copyright notice, this list of conditions and the following +  disclaimer in the documentation and/or other materials provided +  with the distribution. + +  * Neither the name of the The Musepack Development Team nor the +  names of its contributors may be used to endorse or promote +  products derived from this software without specific prior +  written permission. + +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/// \file math.h +/// Libmpcdec internal math routines.   + +#ifndef _mpcdec_math_h_ +#define _mpcdec_math_h_ + +//#define MPC_FIXED_POINT + +#define MPC_FIXED_POINT_SHIFT 16 + +#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) + +#define MPC_MULTIPLY_EX_NOTRUNCATE(X,Y,Z) \ +	(((MPC_SAMPLE_FORMAT_MULTIPLY)(X) * (MPC_SAMPLE_FORMAT_MULTIPLY)(Y)) >> (Z)) + +#ifdef _DEBUG +static inline MPC_SAMPLE_FORMAT MPC_MULTIPLY(MPC_SAMPLE_FORMAT item1,MPC_SAMPLE_FORMAT item2) +{ +	MPC_SAMPLE_FORMAT_MULTIPLY temp = MPC_MULTIPLY_NOTRUNCATE(item1,item2); +	assert(temp == (MPC_SAMPLE_FORMAT_MULTIPLY)(MPC_SAMPLE_FORMAT)temp); +	return (MPC_SAMPLE_FORMAT)temp; +} + +static inline MPC_SAMPLE_FORMAT MPC_MULTIPLY_EX(MPC_SAMPLE_FORMAT item1,MPC_SAMPLE_FORMAT item2,unsigned shift) +{ +	MPC_SAMPLE_FORMAT_MULTIPLY temp = MPC_MULTIPLY_EX_NOTRUNCATE(item1,item2,shift); +	assert(temp == (MPC_SAMPLE_FORMAT_MULTIPLY)(MPC_SAMPLE_FORMAT)temp); +	return (MPC_SAMPLE_FORMAT)temp; +} + +#else + +#define MPC_MULTIPLY(X,Y) ((MPC_SAMPLE_FORMAT)MPC_MULTIPLY_NOTRUNCATE(X,Y)) +#define MPC_MULTIPLY_EX(X,Y,Z) ((MPC_SAMPLE_FORMAT)MPC_MULTIPLY_EX_NOTRUNCATE(X,Y,Z)) + +#endif + +#ifdef MPC_HAVE_MULHIGH +#define MPC_MULTIPLY_FRACT(X,Y) _MulHigh(X,Y) +#else +#define MPC_MULTIPLY_FRACT(X,Y) MPC_MULTIPLY_EX(X,Y,32) +#endif + +#define MPC_MAKE_FRACT_CONST(X) (MPC_SAMPLE_FORMAT)((X) * (double)(((mpc_int64_t)1)<<32) ) +#define MPC_MULTIPLY_FRACT_CONST(X,Y) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST(Y)) +#define MPC_MULTIPLY_FRACT_CONST_FIX(X,Y,Z) ( MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y / (1<<(Z)) )) << (Z) ) +#define MPC_MULTIPLY_FRACT_CONST_SHR(X,Y,Z) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y / (1<<(Z)) )) + +#define MPC_MULTIPLY_FLOAT_INT(X,Y) ((X)*(Y)) +#define MPC_SCALE_CONST(X,Y,Z) MPC_MULTIPLY_EX(X,MAKE_MPC_SAMPLE_EX(Y,Z),(Z)) +#define MPC_SCALE_CONST_SHL(X,Y,Z,S) MPC_MULTIPLY_EX(X,MAKE_MPC_SAMPLE_EX(Y,Z),(Z)-(S)) +#define MPC_SCALE_CONST_SHR(X,Y,Z,S) MPC_MULTIPLY_EX(X,MAKE_MPC_SAMPLE_EX(Y,Z),(Z)+(S)) +#define MPC_SHR(X,Y) ((X)>>(Y)) +#define MPC_SHL(X,Y) ((X)<<(Y)) + +#else + +//in floating-point mode, decoded samples are in -1...1 range + +typedef float MPC_SAMPLE_FORMAT; + +#define MAKE_MPC_SAMPLE(X) ((MPC_SAMPLE_FORMAT)(X)) +#define MAKE_MPC_SAMPLE_EX(X,Y) ((MPC_SAMPLE_FORMAT)(X)) + +#define MPC_MULTIPLY_FRACT(X,Y) ((X)*(Y)) +#define MPC_MAKE_FRACT_CONST(X) (X) +#define MPC_MULTIPLY_FRACT_CONST(X,Y) MPC_MULTPLY_FRACT(X,MPC_MAKE_FRACT_CONST(Y)) +#define MPC_MULTIPLY_FRACT_CONST_SHR(X,Y,Z) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y )) +#define MPC_MULTIPLY_FRACT_CONST_FIX(X,Y,Z) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y )) + +#define MPC_MULTIPLY_FLOAT_INT(X,Y) ((X)*(Y)) +#define MPC_MULTIPLY(X,Y) ((X)*(Y)) +#define MPC_MULTIPLY_EX(X,Y,Z) ((X)*(Y)) +#define MPC_SCALE_CONST(X,Y,Z) ((X)*(Y)) +#define MPC_SCALE_CONST_SHL(X,Y,Z,S) ((X)*(Y)) +#define MPC_SCALE_CONST_SHR(X,Y,Z,S) ((X)*(Y)) +#define MPC_SHR(X,Y) (X) +#define MPC_SHL(X,Y) (X) + +#endif + +#endif // _mpcdec_math_h_ + diff --git a/contrib/libmpcdec/mpcdec/mpcdec.h b/contrib/libmpcdec/mpcdec/mpcdec.h new file mode 100644 index 000000000..77418fbcc --- /dev/null +++ b/contrib/libmpcdec/mpcdec/mpcdec.h @@ -0,0 +1,145 @@ +/* +  Copyright (c) 2005, The Musepack Development Team +  All rights reserved. + +  Redistribution and use in source and binary forms, with or without +  modification, are permitted provided that the following conditions are +  met: + +  * Redistributions of source code must retain the above copyright +  notice, this list of conditions and the following disclaimer. + +  * Redistributions in binary form must reproduce the above +  copyright notice, this list of conditions and the following +  disclaimer in the documentation and/or other materials provided +  with the distribution. + +  * Neither the name of the The Musepack Development Team nor the +  names of its contributors may be used to endorse or promote +  products derived from this software without specific prior +  written permission. + +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/// \file mpcdec.h +/// Top level include file for libmpcdec. + +#ifndef _mpcdec_h_ +#define _mpcdec_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <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 +}; + +// error codes +#define ERROR_CODE_OK            0 +#define ERROR_CODE_FILE         -1 +#define ERROR_CODE_SV7BETA       1 +#define ERROR_CODE_CBR           2 +#define ERROR_CODE_IS            3 +#define ERROR_CODE_BLOCKSIZE     4 +#define ERROR_CODE_INVALIDSV     5 + +/// Initializes a streaminfo structure. +/// \param si streaminfo structure to initialize +void mpc_streaminfo_init(mpc_streaminfo *si); + +/// Reads streaminfo header from the mpc stream supplied by r. +/// \param si streaminfo pointer to which info will be written +/// \param r stream reader to supply raw data +/// \return error code +mpc_int32_t mpc_streaminfo_read(mpc_streaminfo *si, mpc_reader *r); + +/// Gets length of stream si, in seconds. +/// \return length of stream in seconds +double mpc_streaminfo_get_length(mpc_streaminfo *si); + +/// Returns length of stream si, in samples. +/// \return length of stream in samples +mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si); + +/// Sets up decoder library. +/// Call this first when preparing to decode an mpc stream. +/// \param r reader that will supply raw data to the decoder +void mpc_decoder_setup(mpc_decoder *d, mpc_reader *r); + +/// Initializes mpc decoder with the supplied stream info parameters. +/// Call this next after calling mpc_decoder_setup. +/// \param si streaminfo structure indicating format of source stream +/// \return TRUE if decoder was initalized successfully, FALSE otherwise     +mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si); + +/// 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); + +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. +/// \param scale_factor multiplicative scaling factor +void mpc_decoder_scale_output(mpc_decoder *d, double scale_factor); + +/// Actually reads data from previously initialized stream.  Call +/// this iteratively to decode the mpc stream. +/// \param buffer destination buffer for decoded samples +/// \param vbr_update_acc \todo document me +/// \param vbr_update_bits \todo document me +/// \return -1 if an error is encountered +/// \return 0 if the stream has been completely decoded successfully and there are no more samples +/// \return > 0 to indicate the number of bytes that were actually read from the stream. +mpc_uint32_t mpc_decoder_decode( +    mpc_decoder *d, +    MPC_SAMPLE_FORMAT *buffer,  +    mpc_uint32_t *vbr_update_acc,  +    mpc_uint32_t *vbr_update_bits); + +mpc_uint32_t mpc_decoder_decode_frame( +    mpc_decoder *d, +    mpc_uint32_t *in_buffer, +    mpc_uint32_t in_len, +    MPC_SAMPLE_FORMAT *out_buffer); + +/// Seeks to the specified sample in the source stream. +mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample); + +/// Seeks to specified position in seconds in the source stream. +mpc_bool_t mpc_decoder_seek_seconds(mpc_decoder *d, double seconds); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // _mpcdec_h_ diff --git a/contrib/libmpcdec/mpcdec/reader.h b/contrib/libmpcdec/mpcdec/reader.h new file mode 100644 index 000000000..3d4f57edc --- /dev/null +++ b/contrib/libmpcdec/mpcdec/reader.h @@ -0,0 +1,82 @@ +/* +  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 reader.h + +#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 { +    /// Reads size bytes of data into buffer at ptr. +	mpc_int32_t (*read)(void *t, void *ptr, mpc_int32_t size); + +    /// Seeks to byte position offset. +	mpc_bool_t (*seek)(void *t, mpc_int32_t offset); + +    /// Returns the current byte offset in the stream. +	mpc_int32_t (*tell)(void *t); + +    /// Returns the total length of the source stream, in bytes. +	mpc_int32_t (*get_size)(void *t); + +    /// True if the stream is a seekable stream. +	mpc_bool_t (*canseek)(void *t); + +    /// 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); + +#endif // _mpcdec_reader_h_ diff --git a/contrib/libmpcdec/mpcdec/requant.h b/contrib/libmpcdec/mpcdec/requant.h new file mode 100644 index 000000000..a0aab981b --- /dev/null +++ b/contrib/libmpcdec/mpcdec/requant.h @@ -0,0 +1,51 @@ +/* +  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 requant.h +/// Requantization function definitions. + +#ifndef _mpcdec_requant_h +#define _mpcdec_requant_h_ + +#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 + +#define Cc      (__Cc + 1) +#define Dc      (__Dc + 1) + +#endif // _mpcdec_requant_h_ diff --git a/contrib/libmpcdec/mpcdec/streaminfo.h b/contrib/libmpcdec/mpcdec/streaminfo.h new file mode 100644 index 000000000..7cf941c47 --- /dev/null +++ b/contrib/libmpcdec/mpcdec/streaminfo.h @@ -0,0 +1,91 @@ +/* +  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 streaminfo.h + +#ifndef _mpcdec_streaminfo_h_ +#define _mpcdec_streaminfo_h_ + +typedef mpc_int32_t mpc_streaminfo_off_t; + +/// \brief mpc stream properties structure +/// +/// Structure containing all the properties of an mpc stream.  Populated +/// by the streaminfo_read function. +typedef struct mpc_streaminfo { +    /// @name core mpc stream properties +    //@{ +    mpc_uint32_t         sample_freq;        ///< sample frequency of stream +    mpc_uint32_t         channels;           ///< number of channels in stream +    mpc_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 +    //@} + +    /// @name replaygain related fields +    //@{ +    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 +    //@} + +    /// @name true gapless support data +    //@{ +    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 +    //@} + +    /// @name fast seeking support +    //@{ +    mpc_uint32_t        fast_seek;           ///< support fast seeking ? (0: no, 1: yes) +    //@} +} mpc_streaminfo; + +#endif // _mpcdec_streaminfo_h_ diff --git a/contrib/libmpcdec/requant.c b/contrib/libmpcdec/requant.c new file mode 100644 index 000000000..2e4c98b62 --- /dev/null +++ b/contrib/libmpcdec/requant.c @@ -0,0 +1,120 @@ +/* +  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 requant.c +/// Requantization function implementations. +/// \todo document me + +#include <mpcdec/mpcdec.h> +#include <mpcdec/internal.h> + +/* C O N S T A N T S */ +// bits per sample for chosen quantizer +const mpc_uint32_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 +// 65536/step bzw. 65536/(2*D+1) + +#define _(X) MAKE_MPC_SAMPLE_EX(X,14) + +const MPC_SAMPLE_FORMAT  __Cc [1 + 18] = { +      _(111.285962475327f),                                        // 32768/2/255*sqrt(3) +    _(65536.000000000000f), _(21845.333333333332f), _(13107.200000000001f), _(9362.285714285713f), +    _(7281.777777777777f),  _(4369.066666666666f),  _(2114.064516129032f), _(1040.253968253968f), +     _(516.031496062992f),  _(257.003921568627f),   _(128.250489236790f),   _(64.062561094819f), +       _(32.015632633121f),    _(16.003907203907f),     _(8.000976681723f),    _(4.000244155527f), +        _(2.000061037018f),     _(1.000015259021f) +}; + +#undef _ + +// offset for requantization +// 2*D+1 = steps of quantizer +const mpc_int32_t  __Dc [1 + 18] = { +      2, +      0,     1,     2,     3,     4,     7,    15,    31,    63, +    127,   255,   511,  1023,  2047,  4095,  8191, 16383, 32767 +}; + +#ifdef MPC_FIXED_POINT +static mpc_uint32_t find_shift(double fval) +{ +	mpc_int64_t  val = (mpc_int64_t)fval; +	mpc_uint32_t ptr = 0; +	if (val<0) val = -val; +	while(val) {val>>=1;ptr++;} + +	return ptr > 31 ? 0 : 31 - ptr; +} +#endif + +/* F U N C T I O N S */ + +#define SET_SCF(N,X) d->SCF[N] = MAKE_MPC_SAMPLE_EX(X,d->SCF_shift[N] = (unsigned char)find_shift(X)); + +void +mpc_decoder_scale_output(mpc_decoder *d, double factor)  +{ +    mpc_int32_t     n; +    double  f1; +    double  f2; +#ifndef MPC_FIXED_POINT +	factor *= 1.0 / (double)(1<<(MPC_FIXED_POINT_SHIFT-1)); +#else +	factor *= 1.0 / (double)(1<<(16 - MPC_FIXED_POINT_SHIFT)); +#endif +    f1 = f2 = factor; + +    // handles +1.58...-98.41 dB, where's scf[n] / scf[n-1] = 1.20050805774840750476 +	 +	SET_SCF(1,factor); + +	f1 *=   0.83298066476582673961; +	f2 *= 1/0.83298066476582673961; + +    for ( n = 1; n <= 128; n++ ) { +		SET_SCF((unsigned char)(1+n),f1); +		SET_SCF((unsigned char)(1-n),f2); +        f1 *=   0.83298066476582673961; +        f2 *= 1/0.83298066476582673961; +    } +} + +void +mpc_decoder_initialisiere_quantisierungstabellen(mpc_decoder *d, double scale_factor)  +{ +    mpc_decoder_scale_output(d, scale_factor); +} diff --git a/contrib/libmpcdec/streaminfo.c b/contrib/libmpcdec/streaminfo.c new file mode 100644 index 000000000..060da08d0 --- /dev/null +++ b/contrib/libmpcdec/streaminfo.c @@ -0,0 +1,281 @@ +/* +  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 streaminfo.c +/// Implementation of streaminfo reading functions. + +#include <mpcdec/mpcdec.h> +#include <mpcdec/internal.h> + +static const char * +Stringify(mpc_uint32_t 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]; +} + +void +mpc_streaminfo_init(mpc_streaminfo * si) +{ +    memset(si, 0, sizeof(mpc_streaminfo)); +} + +/// Reads streaminfo from SV7 header.  +static mpc_int32_t +streaminfo_read_header_sv7(mpc_streaminfo * si, mpc_uint32_t HeaderData[8]) +{ +    const mpc_int32_t samplefreqs[4] = { 44100, 48000, 37800, 32000 }; + +    //mpc_uint32_t    HeaderData [8]; +    mpc_uint16_t Estimatedpeak_title = 0; + +    if (si->stream_version > 0x71) { +        //        Update (si->stream_version); +        return 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; +     */ + +    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->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 )                                      // there is no correct peak_title contained within header +    //        si->peak_title = (mpc_uint16_t)(Estimatedpeak_title * 1.18); +    //    if ( si->peak_album == 0 ) +    //        si->peak_album = si->peak_title;                          // no correct peak_album, use peak_title + +    //si->sample_freq    = 44100;                                     // AB: used by all files up to SV7 +    si->channels = 2; + +    return ERROR_CODE_OK; +} + +// 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]) +{ +    //mpc_uint32_t    HeaderData [8]; + +    /* +       if ( !fp->seek (  si->header_position ) )         // seek to header start +       return ERROR_CODE_FILE; +       if ( fp->read ( HeaderData, sizeof HeaderData ) != sizeof HeaderData ) +       return ERROR_CODE_FILE; +     */ + +    si->bitrate = (HeaderData[0] >> 23) & 0x01FF;   // read the file-header (SV6 and below) +    si->is = (HeaderData[0] >> 22) & 0x0001; +    si->ms = (HeaderData[0] >> 21) & 0x0001; +    si->stream_version = (HeaderData[0] >> 11) & 0x03FF; +    si->max_band = (HeaderData[0] >> 6) & 0x001F; +    si->block_size = (HeaderData[0]) & 0x003F; +    si->profile = 0; +    si->profile_name = Stringify((mpc_uint32_t) (-1)); +    if (si->stream_version >= 5) +        si->frames = HeaderData[1]; // 32 bit +    else +        si->frames = (HeaderData[1] >> 16); // 16 bit + +    si->gain_title = 0;          // not supported +    si->peak_title = 0; +    si->gain_album = 0; +    si->peak_album = 0; + +    si->last_frame_samples = 0; +    si->is_true_gapless = 0; + +    si->encoder_version = 0; +    si->encoder[0] = '\0'; + +    if (si->stream_version == 7) +        return ERROR_CODE_SV7BETA;  // are there any unsupported parameters used? +    if (si->bitrate != 0) +        return ERROR_CODE_CBR; +    if (si->is != 0) +        return ERROR_CODE_IS; +    if (si->block_size != 1) +        return ERROR_CODE_BLOCKSIZE; + +    if (si->stream_version < 6) // Bugfix: last frame was invalid for up to SV5 +        si->frames -= 1; + +    si->sample_freq = 44100;     // AB: used by all files up to SV7 +    si->channels = 2; + +    if (si->stream_version < 4 || si->stream_version > 7) +        return ERROR_CODE_INVALIDSV; + +    return ERROR_CODE_OK; +} +#endif +// reads file header and tags +mpc_int32_t +mpc_streaminfo_read(mpc_streaminfo * si, mpc_reader * r) +{ +    mpc_uint32_t HeaderData[8]; +    mpc_int32_t Error = 0; + +    // get header position +    if ((si->header_position = JumpID3v2(r)) < 0) { +        return ERROR_CODE_FILE; +    } +    // seek to first byte of mpc data +    if (!r->seek(r->data, si->header_position)) { +        return ERROR_CODE_FILE; +    } +    if (r->read(r->data, HeaderData, 8 * 4) != 8 * 4) { +        return ERROR_CODE_FILE; +    } +    if (!r->seek(r->data, si->header_position + 6 * 4)) { +        return ERROR_CODE_FILE; +    } + +    si->total_file_length = r->get_size(r->data); +    si->tag_offset = si->total_file_length; +     +    if (memcmp(HeaderData, "MP+", 3)) 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; + +    // 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 + +    // estimation, exact value needs too much time +    si->pcm_samples = 1152 * si->frames - 576; + +    if (si->pcm_samples > 0) { +        si->average_bitrate = +            (si->tag_offset - +             si->header_position) * 8.0 * si->sample_freq / si->pcm_samples; +    } +    else { +        si->average_bitrate = 0; +    } + +    return ERROR_CODE_OK; +} + +double +mpc_streaminfo_get_length(mpc_streaminfo * si) +{ +    return (double)mpc_streaminfo_get_length_samples(si) / +        (double)si->sample_freq; +} + +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; +} diff --git a/contrib/libmpcdec/synth_filter.c b/contrib/libmpcdec/synth_filter.c new file mode 100644 index 000000000..08308005d --- /dev/null +++ b/contrib/libmpcdec/synth_filter.c @@ -0,0 +1,440 @@ +/* +  Copyright (c) 2005, The Musepack Development Team +  All rights reserved. + +  Redistribution and use in source and binary forms, with or without +  modification, are permitted provided that the following conditions are +  met: + +  * Redistributions of source code must retain the above copyright +  notice, this list of conditions and the following disclaimer. + +  * Redistributions in binary form must reproduce the above +  copyright notice, this list of conditions and the following +  disclaimer in the documentation and/or other materials provided +  with the distribution. + +  * Neither the name of the The Musepack Development Team nor the +  names of its contributors may be used to endorse or promote +  products derived from this software without specific prior +  written permission. + +  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/// \file synth_filter.c +/// Synthesis functions. +/// \todo document me + +#include <mpcdec/mpcdec.h> +#include <mpcdec/internal.h> + +/* C O N S T A N T S */ +#undef _ + +#define MPC_FIXED_POINT_SYNTH_FIX 2 + +#ifdef MPC_FIXED_POINT +#define _(value)  MPC_MAKE_FRACT_CONST((double)value/(double)(0x40000)) +#else +#define _(value)  MAKE_MPC_SAMPLE((double)value/(double)(0x10000)) +#endif + + +static const MPC_SAMPLE_FORMAT  Di_opt [32] [16] = { +    { _(  0), _( -29), _( 213), _( -459), _( 2037), _(-5153), _(  6574), _(-37489), _(75038), _(37489), _(6574), _( 5153), _(2037), _( 459), _(213), _(29) }, +    { _( -1), _( -31), _( 218), _( -519), _( 2000), _(-5517), _(  5959), _(-39336), _(74992), _(35640), _(7134), _( 4788), _(2063), _( 401), _(208), _(26) }, +    { _( -1), _( -35), _( 222), _( -581), _( 1952), _(-5879), _(  5288), _(-41176), _(74856), _(33791), _(7640), _( 4425), _(2080), _( 347), _(202), _(24) }, +    { _( -1), _( -38), _( 225), _( -645), _( 1893), _(-6237), _(  4561), _(-43006), _(74630), _(31947), _(8092), _( 4063), _(2087), _( 294), _(196), _(21) }, +    { _( -1), _( -41), _( 227), _( -711), _( 1822), _(-6589), _(  3776), _(-44821), _(74313), _(30112), _(8492), _( 3705), _(2085), _( 244), _(190), _(19) }, +    { _( -1), _( -45), _( 228), _( -779), _( 1739), _(-6935), _(  2935), _(-46617), _(73908), _(28289), _(8840), _( 3351), _(2075), _( 197), _(183), _(17) }, +    { _( -1), _( -49), _( 228), _( -848), _( 1644), _(-7271), _(  2037), _(-48390), _(73415), _(26482), _(9139), _( 3004), _(2057), _( 153), _(176), _(16) }, +    { _( -2), _( -53), _( 227), _( -919), _( 1535), _(-7597), _(  1082), _(-50137), _(72835), _(24694), _(9389), _( 2663), _(2032), _( 111), _(169), _(14) }, +    { _( -2), _( -58), _( 224), _( -991), _( 1414), _(-7910), _(    70), _(-51853), _(72169), _(22929), _(9592), _( 2330), _(2001), _(  72), _(161), _(13) }, +    { _( -2), _( -63), _( 221), _(-1064), _( 1280), _(-8209), _(  -998), _(-53534), _(71420), _(21189), _(9750), _( 2006), _(1962), _(  36), _(154), _(11) }, +    { _( -2), _( -68), _( 215), _(-1137), _( 1131), _(-8491), _( -2122), _(-55178), _(70590), _(19478), _(9863), _( 1692), _(1919), _(   2), _(147), _(10) }, +    { _( -3), _( -73), _( 208), _(-1210), _(  970), _(-8755), _( -3300), _(-56778), _(69679), _(17799), _(9935), _( 1388), _(1870), _( -29), _(139), _( 9) }, +    { _( -3), _( -79), _( 200), _(-1283), _(  794), _(-8998), _( -4533), _(-58333), _(68692), _(16155), _(9966), _( 1095), _(1817), _( -57), _(132), _( 8) }, +    { _( -4), _( -85), _( 189), _(-1356), _(  605), _(-9219), _( -5818), _(-59838), _(67629), _(14548), _(9959), _(  814), _(1759), _( -83), _(125), _( 7) }, +    { _( -4), _( -91), _( 177), _(-1428), _(  402), _(-9416), _( -7154), _(-61289), _(66494), _(12980), _(9916), _(  545), _(1698), _(-106), _(117), _( 7) }, +    { _( -5), _( -97), _( 163), _(-1498), _(  185), _(-9585), _( -8540), _(-62684), _(65290), _(11455), _(9838), _(  288), _(1634), _(-127), _(111), _( 6) }, +    { _( -5), _(-104), _( 146), _(-1567), _(  -45), _(-9727), _( -9975), _(-64019), _(64019), _( 9975), _(9727), _(   45), _(1567), _(-146), _(104), _( 5) }, +    { _( -6), _(-111), _( 127), _(-1634), _( -288), _(-9838), _(-11455), _(-65290), _(62684), _( 8540), _(9585), _( -185), _(1498), _(-163), _( 97), _( 5) }, +    { _( -7), _(-117), _( 106), _(-1698), _( -545), _(-9916), _(-12980), _(-66494), _(61289), _( 7154), _(9416), _( -402), _(1428), _(-177), _( 91), _( 4) }, +    { _( -7), _(-125), _(  83), _(-1759), _( -814), _(-9959), _(-14548), _(-67629), _(59838), _( 5818), _(9219), _( -605), _(1356), _(-189), _( 85), _( 4) }, +    { _( -8), _(-132), _(  57), _(-1817), _(-1095), _(-9966), _(-16155), _(-68692), _(58333), _( 4533), _(8998), _( -794), _(1283), _(-200), _( 79), _( 3) }, +    { _( -9), _(-139), _(  29), _(-1870), _(-1388), _(-9935), _(-17799), _(-69679), _(56778), _( 3300), _(8755), _( -970), _(1210), _(-208), _( 73), _( 3) }, +    { _(-10), _(-147), _(  -2), _(-1919), _(-1692), _(-9863), _(-19478), _(-70590), _(55178), _( 2122), _(8491), _(-1131), _(1137), _(-215), _( 68), _( 2) }, +    { _(-11), _(-154), _( -36), _(-1962), _(-2006), _(-9750), _(-21189), _(-71420), _(53534), _(  998), _(8209), _(-1280), _(1064), _(-221), _( 63), _( 2) }, +    { _(-13), _(-161), _( -72), _(-2001), _(-2330), _(-9592), _(-22929), _(-72169), _(51853), _(  -70), _(7910), _(-1414), _( 991), _(-224), _( 58), _( 2) }, +    { _(-14), _(-169), _(-111), _(-2032), _(-2663), _(-9389), _(-24694), _(-72835), _(50137), _(-1082), _(7597), _(-1535), _( 919), _(-227), _( 53), _( 2) }, +    { _(-16), _(-176), _(-153), _(-2057), _(-3004), _(-9139), _(-26482), _(-73415), _(48390), _(-2037), _(7271), _(-1644), _( 848), _(-228), _( 49), _( 1) }, +    { _(-17), _(-183), _(-197), _(-2075), _(-3351), _(-8840), _(-28289), _(-73908), _(46617), _(-2935), _(6935), _(-1739), _( 779), _(-228), _( 45), _( 1) }, +    { _(-19), _(-190), _(-244), _(-2085), _(-3705), _(-8492), _(-30112), _(-74313), _(44821), _(-3776), _(6589), _(-1822), _( 711), _(-227), _( 41), _( 1) }, +    { _(-21), _(-196), _(-294), _(-2087), _(-4063), _(-8092), _(-31947), _(-74630), _(43006), _(-4561), _(6237), _(-1893), _( 645), _(-225), _( 38), _( 1) }, +    { _(-24), _(-202), _(-347), _(-2080), _(-4425), _(-7640), _(-33791), _(-74856), _(41176), _(-5288), _(5879), _(-1952), _( 581), _(-222), _( 35), _( 1) }, +    { _(-26), _(-208), _(-401), _(-2063), _(-4788), _(-7134), _(-35640), _(-74992), _(39336), _(-5959), _(5517), _(-2000), _( 519), _(-218), _( 31), _( 1) } +}; + +#undef  _ + +static void Calculate_New_V ( const MPC_SAMPLE_FORMAT * Sample, MPC_SAMPLE_FORMAT * V ) +{ +    // 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 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]; + +    B00 = A00 + A15; +    B01 = A01 + A14; +    B02 = A02 + A13; +    B03 = A03 + A12; +    B04 = A04 + A11; +    B05 = A05 + A10; +    B06 = A06 + A09; +    B07 = A07 + A08;; +    B08 = MPC_SCALE_CONST((A00 - A15) , 0.5024192929f , 31); +    B09 = MPC_SCALE_CONST((A01 - A14) , 0.5224986076f , 31); +    B10 = MPC_SCALE_CONST((A02 - A13) , 0.5669440627f , 31); +    B11 = MPC_SCALE_CONST((A03 - A12) , 0.6468217969f , 31); +    B12 = MPC_SCALE_CONST((A04 - A11) , 0.7881546021f , 31); +    B13 = MPC_SCALE_CONST((A05 - A10) , 1.0606776476f , 30); +    B14 = MPC_SCALE_CONST((A06 - A09) , 1.7224471569f , 30); +    B15 = MPC_SCALE_CONST((A07 - A08) , 5.1011486053f , 28); + +    A00 =  B00 + B07; +    A01 =  B01 + B06; +    A02 =  B02 + B05; +    A03 =  B03 + B04; +    A04 = MPC_SCALE_CONST((B00 - B07) , 0.5097956061f , 31); +    A05 = MPC_SCALE_CONST((B01 - B06) , 0.6013448834f , 31); +    A06 = MPC_SCALE_CONST((B02 - B05) , 0.8999761939f , 31); +    A07 = MPC_SCALE_CONST((B03 - B04) , 2.5629155636f , 29); +    A08 =  B08 + B15; +    A09 =  B09 + B14; +    A10 =  B10 + B13; +    A11 =  B11 + B12; +    A12 = MPC_SCALE_CONST((B08 - B15) , 0.5097956061f , 31); +    A13 = MPC_SCALE_CONST((B09 - B14) , 0.6013448834f , 31); +    A14 = MPC_SCALE_CONST((B10 - B13) , 0.8999761939f , 31); +    A15 = MPC_SCALE_CONST((B11 - B12) , 2.5629155636f , 29); + +    B00 =  A00 + A03; +    B01 =  A01 + A02; +    B02 = MPC_MULTIPLY_FRACT_CONST_FIX((A00 - A03) , 0.5411961079f , 1); +    B03 = MPC_MULTIPLY_FRACT_CONST_FIX((A01 - A02) , 1.3065630198f , 2); +    B04 =  A04 + A07; +    B05 =  A05 + A06; +    B06 = MPC_MULTIPLY_FRACT_CONST_FIX((A04 - A07) , 0.5411961079f , 1); +    B07 = MPC_MULTIPLY_FRACT_CONST_FIX((A05 - A06) , 1.3065630198f , 2); +    B08 =  A08 + A11; +    B09 =  A09 + A10; +    B10 = MPC_MULTIPLY_FRACT_CONST_FIX((A08 - A11) , 0.5411961079f , 1); +    B11 = MPC_MULTIPLY_FRACT_CONST_FIX((A09 - A10) , 1.3065630198f , 2); +    B12 =  A12 + A15; +    B13 =  A13 + A14; +    B14 = MPC_MULTIPLY_FRACT_CONST_FIX((A12 - A15) , 0.5411961079f , 1); +    B15 = MPC_MULTIPLY_FRACT_CONST_FIX((A13 - A14) , 1.3065630198f , 2); + +    A00 =  B00 + B01; +    A01 = MPC_MULTIPLY_FRACT_CONST_FIX((B00 - B01) , 0.7071067691f , 1); +    A02 =  B02 + B03; +    A03 = MPC_MULTIPLY_FRACT_CONST_FIX((B02 - B03) , 0.7071067691f , 1); +    A04 =  B04 + B05; +    A05 = MPC_MULTIPLY_FRACT_CONST_FIX((B04 - B05) , 0.7071067691f , 1); +    A06 =  B06 + B07; +    A07 = MPC_MULTIPLY_FRACT_CONST_FIX((B06 - B07) , 0.7071067691f , 1); +    A08 =  B08 + B09; +    A09 = MPC_MULTIPLY_FRACT_CONST_FIX((B08 - B09) , 0.7071067691f , 1); +    A10 =  B10 + B11; +    A11 = MPC_MULTIPLY_FRACT_CONST_FIX((B10 - B11) , 0.7071067691f , 1); +    A12 =  B12 + B13; +    A13 = MPC_MULTIPLY_FRACT_CONST_FIX((B12 - B13) , 0.7071067691f , 1); +    A14 =  B14 + B15; +    A15 = MPC_MULTIPLY_FRACT_CONST_FIX((B14 - B15) , 0.7071067691f , 1); + +    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; + +    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); +#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); +#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); +#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); + +    B00 =  A00 + A15; +    B01 =  A01 + A14; +    B02 =  A02 + A13; +    B03 =  A03 + A12; +    B04 =  A04 + A11; +    B05 =  A05 + A10; +    B06 =  A06 + A09; +    B07 =  A07 + A08; +    B08 = MPC_SCALE_CONST((A00 - A15) , 0.5024192929f , 31); +    B09 = MPC_SCALE_CONST((A01 - A14) , 0.5224986076f , 31); +    B10 = MPC_SCALE_CONST((A02 - A13) , 0.5669440627f , 31); +    B11 = MPC_SCALE_CONST((A03 - A12) , 0.6468217969f , 31); +    B12 = MPC_SCALE_CONST((A04 - A11) , 0.7881546021f , 31); +    B13 = MPC_SCALE_CONST((A05 - A10) , 1.0606776476f , 30); +    B14 = MPC_SCALE_CONST((A06 - A09) , 1.7224471569f , 30); +    B15 = MPC_SCALE_CONST((A07 - A08) , 5.1011486053f , 28); + +    A00 =  B00 + B07; +    A01 =  B01 + B06; +    A02 =  B02 + B05; +    A03 =  B03 + B04; +    A04 = MPC_SCALE_CONST((B00 - B07) , 0.5097956061f , 31); +    A05 = MPC_SCALE_CONST((B01 - B06) , 0.6013448834f , 31); +    A06 = MPC_SCALE_CONST((B02 - B05) , 0.8999761939f , 31); +    A07 = MPC_SCALE_CONST((B03 - B04) , 2.5629155636f , 29); +    A08 =  B08 + B15; +    A09 =  B09 + B14; +    A10 =  B10 + B13; +    A11 =  B11 + B12; +    A12 = MPC_SCALE_CONST((B08 - B15) , 0.5097956061f , 31); +    A13 = MPC_SCALE_CONST((B09 - B14) , 0.6013448834f , 31); +    A14 = MPC_SCALE_CONST((B10 - B13) , 0.8999761939f , 31); +    A15 = MPC_SCALE_CONST((B11 - B12) , 2.5629155636f , 29); + +    B00 =  A00 + A03; +    B01 =  A01 + A02; +    B02 = MPC_SCALE_CONST((A00 - A03) , 0.5411961079f , 31); +    B03 = MPC_SCALE_CONST((A01 - A02) , 1.3065630198f , 30); +    B04 =  A04 + A07; +    B05 =  A05 + A06; +    B06 = MPC_SCALE_CONST((A04 - A07) , 0.5411961079f , 31); +    B07 = MPC_SCALE_CONST((A05 - A06) , 1.3065630198f , 30); +    B08 =  A08 + A11; +    B09 =  A09 + A10; +    B10 = MPC_SCALE_CONST((A08 - A11) , 0.5411961079f , 31); +    B11 = MPC_SCALE_CONST((A09 - A10) , 1.3065630198f , 30); +    B12 =  A12 + A15; +    B13 =  A13 + A14; +    B14 = MPC_SCALE_CONST((A12 - A15) , 0.5411961079f , 31); +    B15 = MPC_SCALE_CONST((A13 - A14) , 1.3065630198f , 30); + +    A00 = MPC_SHL(B00 + B01, MPC_FIXED_POINT_SYNTH_FIX); +    A01 = MPC_SCALE_CONST_SHL((B00 - B01) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); +    A02 = MPC_SHL(B02 + B03, MPC_FIXED_POINT_SYNTH_FIX); +    A03 = MPC_SCALE_CONST_SHL((B02 - B03) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); +    A04 = MPC_SHL(B04 + B05, MPC_FIXED_POINT_SYNTH_FIX); +    A05 = MPC_SCALE_CONST_SHL((B04 - B05) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); +    A06 = MPC_SHL(B06 + B07, MPC_FIXED_POINT_SYNTH_FIX); +    A07 = MPC_SCALE_CONST_SHL((B06 - B07) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); +    A08 = MPC_SHL(B08 + B09, MPC_FIXED_POINT_SYNTH_FIX); +    A09 = MPC_SCALE_CONST_SHL((B08 - B09) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); +    A10 = MPC_SHL(B10 + B11, MPC_FIXED_POINT_SYNTH_FIX); +    A11 = MPC_SCALE_CONST_SHL((B10 - B11) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); +    A12 = MPC_SHL(B12 + B13, MPC_FIXED_POINT_SYNTH_FIX); +    A13 = MPC_SCALE_CONST_SHL((B12 - B13) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); +    A14 = MPC_SHL(B14 + B15, MPC_FIXED_POINT_SYNTH_FIX); +    A15 = MPC_SCALE_CONST_SHL((B14 - B15) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); + +    // mehrfach verwendete 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 + +    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]; + +    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]; +} + +static void Synthese_Filter_float_internal(MPC_SAMPLE_FORMAT * OutData,MPC_SAMPLE_FORMAT * V,const MPC_SAMPLE_FORMAT * Y) +{ +    mpc_uint32_t n; +    for ( n = 0; n < 36; n++, Y += 32 ) { +        V -= 64; +        Calculate_New_V ( Y, V ); +        { +            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; +        } +    } +} + +void +mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT* OutData)  +{ +    /********* 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])); + +    /******** 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])); +} + +/*******************************************/ +/*                                         */ +/*            dithered synthesis           */ +/*                                         */ +/*******************************************/ + +static const unsigned char    Parity [256] = {  // parity +    0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, +    1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, +    1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, +    0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, +    1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, +    0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, +    0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, +    1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 +}; + +/* + *  This is a simple random number generator with good quality for audio purposes. + *  It consists of two polycounters with opposite rotation direction and different + *  periods. The periods are coprime, so the total period is the product of both. + * + *     ------------------------------------------------------------------------------------------------- + * +-> |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| + * |   ------------------------------------------------------------------------------------------------- + * |                                                                          |  |  |  |     |        | + * |                                                                          +--+--+--+-XOR-+--------+ + * |                                                                                      | + * +--------------------------------------------------------------------------------------+ + * + *     ------------------------------------------------------------------------------------------------- + *     |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| <-+ + *     -------------------------------------------------------------------------------------------------   | + *       |  |           |  |                                                                               | + *       +--+----XOR----+--+                                                                               | + *                |                                                                                        | + *                +----------------------------------------------------------------------------------------+ + * + * + *  The first has an period of 3*5*17*257*65537, the second of 7*47*73*178481, + *  which gives a period of 18.410.713.077.675.721.215. The result is the + *  XORed values of both generators. + */ +mpc_uint32_t +mpc_random_int(mpc_decoder *d)  +{ +#if 1 +    mpc_uint32_t  t1, t2, t3, t4; + +    t3   = t1 = d->__r1;   t4   = t2 = d->__r2;  // Parity calculation is done via table lookup, this is also available +    t1  &= 0xF5;        t2 >>= 25;               // on CPUs without parity, can be implemented in C and avoid unpredictable +    t1   = Parity [t1]; t2  &= 0x63;             // jumps and slow rotate through the carry flag operations. +    t1 <<= 31;          t2   = Parity [t2]; + +    return (d->__r1 = (t3 >> 1) | t1 ) ^ (d->__r2 = (t4 + t4) | t2 ); +#else +    return (d->__r1 = (d->__r1 >> 1) | ((mpc_uint32_t)Parity [d->__r1 & 0xF5] << 31) ) ^ +        (d->__r2 = (d->__r2 << 1) |  (mpc_uint32_t)Parity [(d->__r2 >> 25) & 0x63] ); +#endif +} | 
