diff options
Diffstat (limited to 'mpeglib/lib/splay')
41 files changed, 7764 insertions, 0 deletions
diff --git a/mpeglib/lib/splay/Makefile.am b/mpeglib/lib/splay/Makefile.am new file mode 100644 index 00000000..70fdc105 --- /dev/null +++ b/mpeglib/lib/splay/Makefile.am @@ -0,0 +1,53 @@ +# libsplay - Makefile.am + + +INCLUDES = $(all_includes) + + +EXTRA_DIST = dct64.cpp dct64_down.cpp dct36_12.cpp \ + window.cpp dct.h + + +noinst_LTLIBRARIES = libsplay.la + +noinst_HEADERS = mpegAudioHeader.h mpegAudioStream.h \ + mpegsound.h op.h \ + sigsev.c dump.h \ + dxHead.h mpeg2tables.h \ + mpegAudioBitWindow.h huffmanlookup.h \ + common.h attribute.h synthesis.h + +kmpgincludedir = $(includedir)/$(THIS_LIB_NAME)/splay + +kmpginclude_HEADERS = splayDecoder.h mpegAudioInfo.h \ + mpegAudioFrame.h + + +libsplay_la_SOURCES = mpegAudioHeader.cpp mpegAudioStream.cpp \ + huffmantable.cpp \ + mpeglayer1.cpp \ + mpeglayer2.cpp \ + mpeglayer3.cpp \ + mpegtable.cpp \ + mpegtoraw.cpp \ + dxHead.cpp \ + mpegAudioBitWindow.cpp huffmanlookup.cpp \ + splayDecoder.cpp \ + dump.cpp synth_filter.cpp \ + synthesis.cpp synth_Std.cpp synth_Down.cpp \ + mpegAudioFrame.cpp \ + mpegAudioInfo.cpp + + + +#CXXFLAGS += -fno-strength-reduce +# -funroll-all-loops -finline-functions -ffast-math -m486 + + + + + + + + + diff --git a/mpeglib/lib/splay/attribute.h b/mpeglib/lib/splay/attribute.h new file mode 100644 index 00000000..9e6bf0e6 --- /dev/null +++ b/mpeglib/lib/splay/attribute.h @@ -0,0 +1,33 @@ +/* + align attribut definition (g++) + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#ifndef __ATTRIBUTE_H +#define __ATTRIBUTE_H + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* use gcc attribs to align critical data structures */ + +#ifdef ATTRIBUTE_ALIGNED_MAX +#define ATTR_ALIGN(align) __attribute__ \ + ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX <align) ? \ + ATTRIBUTE_ALIGNED_MAX : align))) +#else +#define ATTR_ALIGN(align) +#endif + + +#endif diff --git a/mpeglib/lib/splay/common.h b/mpeglib/lib/splay/common.h new file mode 100644 index 00000000..df0945b8 --- /dev/null +++ b/mpeglib/lib/splay/common.h @@ -0,0 +1,60 @@ +/* + include header for dcts/windows + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#ifndef __COMMON_H +#define __COMMON_H + +#include "attribute.h" +#include <stdio.h> + +#define SSLIMIT 18 +#define SBLIMIT 32 + + +#define LS 0 +#define RS 1 + + +typedef float REAL; + +// The inline code works on intel only with egcs >= 1.1 +#ifdef __GNUC__ +#if (__GNUC__ < 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ < 91 ) ) +#ifndef _AIX +#warning "inline code disabled! (buggy egcs version)" +#undef __NO_MATH_INLINES +#define __NO_MATH_INLINES 1 +#endif +#endif +#endif +#include <math.h> +#include <stdlib.h> + +#ifndef M_PI +#define MY_PI 3.14159265358979323846 +#else +#define MY_PI M_PI +#endif + +#ifdef PI +#undef PI +#endif +#define PI MY_PI +#define PI_12 (PI/12.0) +#define PI_18 (PI/18.0) +#define PI_24 (PI/24.0) +#define PI_36 (PI/36.0) +#define PI_72 (PI/72.0) + + +#endif diff --git a/mpeglib/lib/splay/dct.h b/mpeglib/lib/splay/dct.h new file mode 100644 index 00000000..ad707a19 --- /dev/null +++ b/mpeglib/lib/splay/dct.h @@ -0,0 +1,33 @@ +/* + wrapper for dcts + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#ifndef __DCT_HEADER_H +#define __DCT_HEADER_H + +// one source: +extern void initialize_dct64(); + +//extern void dct64(REAL* out1,REAL* out2,REAL *fraction); + +// one source: +extern void initialize_dct64_downsample(); +//extern void dct64_downsample(REAL* out1,REAL* out2,REAL *fraction); + +// one source file: +extern void initialize_dct12_dct36(); + +//extern void dct12(REAL *in,REAL *prevblk1,REAL *prevblk2,REAL *wi,REAL *out); +//extern void dct36(REAL *inbuf,REAL *prevblk1,REAL *prevblk2,REAL *wi,REAL *out); + +extern void initialize_win(); +#endif diff --git a/mpeglib/lib/splay/dct36_12.cpp b/mpeglib/lib/splay/dct36_12.cpp new file mode 100644 index 00000000..b9978d7d --- /dev/null +++ b/mpeglib/lib/splay/dct36_12.cpp @@ -0,0 +1,288 @@ +/* + wrapper for dcts + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + +#include "dct.h" +#include "common.h" + + + +ATTR_ALIGN(64) static REAL hsec_12[3]; +ATTR_ALIGN(64) static REAL cos2_6=cos(PI/6.0*2.0); +ATTR_ALIGN(64) static REAL cos1_6=cos(PI/6.0*1.0); +ATTR_ALIGN(64) static REAL hsec_36[9]; +ATTR_ALIGN(64) static REAL cos_18[9]; + + +/** + This was some time ago a standalone dct class, + but to get more speed I made it an inline dct + int the filter classes +*/ + +static int dct36_12Init=false; + +void initialize_dct12_dct36() { + if (dct36_12Init==true) { + return; + } + dct36_12Init=true; + + + int i; + + for(i=0;i<3;i++) + hsec_12[i]=0.5/cos(double(i*2+1)* PI_12); + + for(i=0;i<9;i++) + hsec_36[i]=0.5/cos(double(i*2+1)* PI_36); + + for(i=0;i<9;i++) + cos_18[i]=cos(PI_18*double(i)); + +} + + +inline void dct36(REAL *inbuf,REAL *prevblk1, + REAL *prevblk2,REAL *wi,REAL *out){ + +#define MACRO0(v) { \ + REAL tmp; \ + out2[9+(v)]=(tmp=sum0+sum1)*wi[27+(v)]; \ + out2[8-(v)]=tmp * wi[26-(v)]; } \ + sum0-=sum1; \ + ts[SBLIMIT*(8-(v))]=out1[8-(v)]+sum0*wi[8-(v)]; \ + ts[SBLIMIT*(9+(v))]=out1[9+(v)]+sum0*wi[9+(v)]; +#define MACRO1(v) { \ + REAL sum0,sum1; \ + sum0=tmp1a+tmp2a; \ + sum1=(tmp1b+tmp2b)*hsec_36[(v)]; \ + MACRO0(v); } +#define MACRO2(v) { \ + REAL sum0,sum1; \ + sum0=tmp2a-tmp1a; \ + sum1=(tmp2b-tmp1b) * hsec_36[(v)]; \ + MACRO0(v); } + + { + REAL *in = inbuf; + + in[17]+=in[16];in[16]+=in[15];in[15]+=in[14];in[14]+=in[13]; + in[13]+=in[12];in[12]+=in[11];in[11]+=in[10];in[10]+=in[ 9]; + in[ 9]+=in[ 8];in[ 8]+=in[ 7];in[ 7]+=in[ 6];in[ 6]+=in[ 5]; + in[ 5]+=in[ 4];in[ 4]+=in[ 3];in[ 3]+=in[ 2];in[ 2]+=in[ 1]; + in[ 1]+=in[ 0]; + + + in[17]+=in[15];in[15]+=in[13];in[13]+=in[11];in[11]+=in[ 9]; + in[ 9]+=in[ 7];in[7] +=in[ 5];in[ 5]+=in[ 3];in[ 3]+=in[ 1]; + + { + REAL *c = cos_18; + REAL *out2 = prevblk2; + REAL *out1 = prevblk1; + REAL *ts = out; + + REAL ta33,ta66,tb33,tb66; + + ta33=in[2*3+0]*c[3]; + ta66=in[2*6+0]*c[6]; + tb33=in[2*3+1]*c[3]; + tb66=in[2*6+1]*c[6]; + + { + REAL tmp1a,tmp2a,tmp1b,tmp2b; + tmp1a= in[2*1+0]*c[1]+ta33 +in[2*5+0]*c[5]+in[2*7+0]*c[7]; + tmp1b= in[2*1+1]*c[1]+tb33 +in[2*5+1]*c[5]+in[2*7+1]*c[7]; + tmp2a=in[2*0+0]+in[2*2+0]*c[2]+in[2*4+0]*c[4]+ta66 +in[2*8+0]*c[8]; + tmp2b=in[2*0+1]+in[2*2+1]*c[2]+in[2*4+1]*c[4]+tb66 +in[2*8+1]*c[8]; + MACRO1(0); + MACRO2(8); + } + + { + REAL tmp1a,tmp2a,tmp1b,tmp2b; + tmp1a=(in[2*1+0]-in[2*5+0]-in[2*7+0])*c[3]; + tmp1b=(in[2*1+1]-in[2*5+1]-in[2*7+1])*c[3]; + tmp2a=(in[2*2+0]-in[2*4+0]-in[2*8+0])*c[6]-in[2*6+0]+in[2*0+0]; + tmp2b=(in[2*2+1]-in[2*4+1]-in[2*8+1])*c[6]-in[2*6+1]+in[2*0+1]; + MACRO1(1); + MACRO2(7); + } + + { + REAL tmp1a,tmp2a,tmp1b,tmp2b; + tmp1a= in[2*1+0]*c[5]-ta33 -in[2*5+0]*c[7]+in[2*7+0]*c[1]; + tmp1b= in[2*1+1]*c[5]-tb33 -in[2*5+1]*c[7]+in[2*7+1]*c[1]; + tmp2a=in[2*0+0]-in[2*2+0]*c[8]-in[2*4+0]*c[2]+ta66 +in[2*8+0]*c[4]; + tmp2b=in[2*0+1]-in[2*2+1]*c[8]-in[2*4+1]*c[2]+tb66 +in[2*8+1]*c[4]; + MACRO1(2); + MACRO2(6); + } + + { + REAL tmp1a,tmp2a,tmp1b,tmp2b; + tmp1a= in[2*1+0]*c[7]-ta33 +in[2*5+0]*c[1]-in[2*7+0]*c[5]; + tmp1b= in[2*1+1]*c[7]-tb33 +in[2*5+1]*c[1]-in[2*7+1]*c[5]; + tmp2a=in[2*0+0]-in[2*2+0]*c[4]+in[2*4+0]*c[8]+ta66 -in[2*8+0]*c[2]; + tmp2b=in[2*0+1]-in[2*2+1]*c[4]+in[2*4+1]*c[8]+tb66 -in[2*8+1]*c[2]; + MACRO1(3); + MACRO2(5); + } + + { + REAL sum0,sum1; + sum0= in[2*0+0]-in[2*2+0]+in[2*4+0]-in[2*6+0]+in[2*8+0]; + sum1=(in[2*0+1]-in[2*2+1]+in[2*4+1]-in[2*6+1]+in[2*8+1])*hsec_36[4]; + MACRO0(4); + } + } + } + + +} + + +inline void dct12(REAL *in,REAL *prevblk1,REAL *prevblk2,REAL *wi,REAL *out) { + +#define DCT12_PART1 \ + in5=in[5*3]; \ + in5+=(in4=in[4*3]); \ + in4+=(in3=in[3*3]); \ + in3+=(in2=in[2*3]); \ + in2+=(in1=in[1*3]); \ + in1+=(in0=in[0*3]); \ + \ + in5+=in3;in3+=in1; \ + \ + in2*=cos1_6; \ + in3*=cos1_6; + +#define DCT12_PART2 \ + in0+=in4*cos2_6; \ + \ + in4=in0+in2; \ + in0-=in2; \ + \ + in1+=in5*cos2_6; \ + \ + in5=(in1+in3)*hsec_12[0]; \ + in1=(in1-in3)*hsec_12[2]; \ + \ + in3=in4+in5; \ + in4-=in5; \ + \ + in2=in0+in1; \ + in0-=in1; + + { + REAL in0,in1,in2,in3,in4,in5; + register REAL *pb1=prevblk1; + out[SBLIMIT*0]=pb1[0];out[SBLIMIT*1]=pb1[1];out[SBLIMIT*2]=pb1[2]; + out[SBLIMIT*3]=pb1[3];out[SBLIMIT*4]=pb1[4];out[SBLIMIT*5]=pb1[5]; + + DCT12_PART1; + + { + REAL tmp0,tmp1=(in0-in4); + { + register REAL tmp2=(in1-in5)*hsec_12[1]; + tmp0=tmp1+tmp2; + tmp1-=tmp2; + } + out[(17-1)*SBLIMIT]=pb1[17-1]+tmp0*wi[11-1]; + out[(12+1)*SBLIMIT]=pb1[12+1]+tmp0*wi[ 6+1]; + out[(6 +1)*SBLIMIT]=pb1[6 +1]+tmp1*wi[ 1 ]; + out[(11-1)*SBLIMIT]=pb1[11-1]+tmp1*wi[ 5-1]; + } + + DCT12_PART2; + out[(17-0)*SBLIMIT]=pb1[17-0]+in2*wi[11-0]; + out[(12+0)*SBLIMIT]=pb1[12+0]+in2*wi[ 6+0]; + out[(12+2)*SBLIMIT]=pb1[12+2]+in3*wi[ 6+2]; + out[(17-2)*SBLIMIT]=pb1[17-2]+in3*wi[11-2]; + + out[( 6+0)*SBLIMIT]=pb1[ 6+0]+in0*wi[0]; + out[(11-0)*SBLIMIT]=pb1[11-0]+in0*wi[5-0]; + out[( 6+2)*SBLIMIT]=pb1[ 6+2]+in4*wi[2]; + out[(11-2)*SBLIMIT]=pb1[11-2]+in4*wi[5-2]; + } + + in++; + { + REAL in0,in1,in2,in3,in4,in5; + register REAL *pb2 = prevblk2; + + DCT12_PART1; + + { + REAL tmp0,tmp1=(in0-in4); + { + REAL tmp2=(in1-in5)*hsec_12[1]; + tmp0=tmp1+tmp2; + tmp1-=tmp2; + } + pb2[5-1]=tmp0*wi[11-1]; + pb2[0+1]=tmp0*wi[6+1]; + out[(12+1)*SBLIMIT]+=tmp1*wi[1]; + out[(17-1)*SBLIMIT]+=tmp1*wi[5-1]; + } + + DCT12_PART2; + + pb2[5-0]=in2*wi[11-0]; + pb2[0+0]=in2*wi[6+0]; + pb2[0+2]=in3*wi[6+2]; + pb2[5-2]=in3*wi[11-2]; + + out[(12+0)*SBLIMIT]+=in0*wi[0]; + out[(17-0)*SBLIMIT]+=in0*wi[5-0]; + out[(12+2)*SBLIMIT]+=in4*wi[2]; + out[(17-2)*SBLIMIT]+=in4*wi[5-2]; + } + + in++; + { + REAL in0,in1,in2,in3,in4,in5; + register REAL *pb2 = prevblk2; + pb2[12]=pb2[13]=pb2[14]=pb2[15]=pb2[16]=pb2[17]=0.0; + + DCT12_PART1; + + { + REAL tmp0,tmp1=(in0-in4); + { + REAL tmp2=(in1-in5)*hsec_12[1]; + tmp0=tmp1+tmp2; + tmp1-=tmp2; + } + pb2[11-1]=tmp0*wi[11-1]; + pb2[ 6+1]=tmp0*wi[6+1]; + pb2[ 0+1]+=tmp1*wi[1]; + pb2[ 5-1]+=tmp1*wi[5-1]; + } + + DCT12_PART2; + pb2[11-0]=in2*wi[11-0]; + pb2[ 6+0]=in2*wi[ 6+0]; + pb2[ 6+2]=in3*wi[ 6+2]; + pb2[11-2]=in3*wi[11-2]; + + pb2[ 0+0]+=in0*wi[0 ]; + pb2[ 5-0]+=in0*wi[5-0]; + pb2[ 0+2]+=in4*wi[2 ]; + pb2[ 5-2]+=in4*wi[5-2]; + } + + +} + + diff --git a/mpeglib/lib/splay/dct64.cpp b/mpeglib/lib/splay/dct64.cpp new file mode 100644 index 00000000..14241651 --- /dev/null +++ b/mpeglib/lib/splay/dct64.cpp @@ -0,0 +1,202 @@ +/* + wrapper for dcts + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + +#include "dct.h" +#include "common.h" + +ATTR_ALIGN(64) static REAL hcos_64[16]; +ATTR_ALIGN(64) static REAL hcos_32[8]; +ATTR_ALIGN(64) static REAL hcos_16[4]; +ATTR_ALIGN(64) static REAL hcos_8[2]; +ATTR_ALIGN(64) static REAL hcos_4; + +/** + This was some time ago a standalone dct class, + but to get more speed I made it an inline dct + int the filter classes +*/ + +static int dct64Init=false; + +void initialize_dct64() { + if (dct64Init==true) { + return; + } + dct64Init=true; + + int i; + + for(i=0;i<16;i++) { + hcos_64[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/64.0)); + } + for(i=0;i< 8;i++) { + hcos_32[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/32.0)); + } + for(i=0;i< 4;i++) { + hcos_16[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/16.0)); + } + for(i=0;i< 2;i++) { + hcos_8[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/ 8.0)); + } + hcos_4=1.0/(2.0*cos(MY_PI*1.0/4.0)); + +} + + + + +// +// splay dct64 , faster than mpeg123 dct. (from decode.c) +// +inline void dct64(REAL* out1,REAL* out2,REAL *fraction) { + ATTR_ALIGN(64) REAL p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pa,pb,pc,pd,pe,pf; + ATTR_ALIGN(64) REAL q0,q1,q2,q3,q4,q5,q6,q7,q8,q9,qa,qb,qc,qd,qe,qf; + +#define OUT1(v,t) out1[(32-(v))*16] =(-(out1[(v)*16]=t)) +#define OUT2(v) out2[(96-(v)-32)*16]=out2[((v)-32)*16] + + // compute new values via a fast cosine transform: + { + // put to buffer 0..15 + register REAL* x=fraction; + + p0=x[ 0]+x[31];p1=x[ 1]+x[30];p2=x[ 2]+x[29];p3=x[ 3]+x[28]; + p4=x[ 4]+x[27];p5=x[ 5]+x[26];p6=x[ 6]+x[25];p7=x[ 7]+x[24]; + p8=x[ 8]+x[23];p9=x[ 9]+x[22];pa=x[10]+x[21];pb=x[11]+x[20]; + pc=x[12]+x[19];pd=x[13]+x[18];pe=x[14]+x[17];pf=x[15]+x[16]; + } + + // put to buffer 32..39 + q0=p0+pf;q1=p1+pe;q2=p2+pd;q3=p3+pc; + q4=p4+pb;q5=p5+pa;q6=p6+p9;q7=p7+p8; + // put to buffer 40..47 + q8=hcos_32[0]*(p0-pf);q9=hcos_32[1]*(p1-pe); + qa=hcos_32[2]*(p2-pd);qb=hcos_32[3]*(p3-pc); + qc=hcos_32[4]*(p4-pb);qd=hcos_32[5]*(p5-pa); + qe=hcos_32[6]*(p6-p9);qf=hcos_32[7]*(p7-p8); + + p0=q0+q7;p1=q1+q6;p2=q2+q5;p3=q3+q4; + p4=hcos_16[0]*(q0-q7);p5=hcos_16[1]*(q1-q6); + p6=hcos_16[2]*(q2-q5);p7=hcos_16[3]*(q3-q4); + p8=q8+qf;p9=q9+qe;pa=qa+qd;pb=qb+qc; + pc=hcos_16[0]*(q8-qf);pd=hcos_16[1]*(q9-qe); + pe=hcos_16[2]*(qa-qd);pf=hcos_16[3]*(qb-qc); + + q0=p0+p3;q1=p1+p2;q2=hcos_8[0]*(p0-p3);q3=hcos_8[1]*(p1-p2); + q4=p4+p7;q5=p5+p6;q6=hcos_8[0]*(p4-p7);q7=hcos_8[1]*(p5-p6); + q8=p8+pb;q9=p9+pa;qa=hcos_8[0]*(p8-pb);qb=hcos_8[1]*(p9-pa); + qc=pc+pf;qd=pd+pe;qe=hcos_8[0]*(pc-pf);qf=hcos_8[1]*(pd-pe); + + p0=q0+q1;p1=hcos_4*(q0-q1);p2=q2+q3;p3=hcos_4*(q2-q3); + p4=q4+q5;p5=hcos_4*(q4-q5);p6=q6+q7;p7=hcos_4*(q6-q7); + p8=q8+q9;p9=hcos_4*(q8-q9);pa=qa+qb;pb=hcos_4*(qa-qb); + pc=qc+qd;pd=hcos_4*(qc-qd);pe=qe+qf;pf=hcos_4*(qe-qf); + + { + register REAL tmp; + + tmp=p6+p7; + OUT2(36)=-(p5+tmp); + OUT2(44)=-(p4+tmp); + tmp=pb+pf; + OUT1(10,tmp); + OUT1(6,pd+tmp); + tmp=pe+pf; + OUT2(46)=-(p8+pc+tmp); + OUT2(34)=-(p9+pd+tmp); + tmp+=pa+pb; + OUT2(38)=-(pd+tmp); + OUT2(42)=-(pc+tmp); + OUT1(2,p9+pd+pf); + OUT1(4,p5+p7); + OUT2(48)=-p0; + out2[0]=-(out1[0]=p1); + OUT1( 8,p3); + OUT1(12,p7); + OUT1(14,pf); + OUT2(40)=-(p2+p3); + } + + { + // put to buffer 16..31 + register REAL *x=fraction; + + p0=hcos_64[ 0]*(x[ 0]-x[31]);p1=hcos_64[ 1]*(x[ 1]-x[30]); + p2=hcos_64[ 2]*(x[ 2]-x[29]);p3=hcos_64[ 3]*(x[ 3]-x[28]); + p4=hcos_64[ 4]*(x[ 4]-x[27]);p5=hcos_64[ 5]*(x[ 5]-x[26]); + p6=hcos_64[ 6]*(x[ 6]-x[25]);p7=hcos_64[ 7]*(x[ 7]-x[24]); + p8=hcos_64[ 8]*(x[ 8]-x[23]);p9=hcos_64[ 9]*(x[ 9]-x[22]); + pa=hcos_64[10]*(x[10]-x[21]);pb=hcos_64[11]*(x[11]-x[20]); + pc=hcos_64[12]*(x[12]-x[19]);pd=hcos_64[13]*(x[13]-x[18]); + pe=hcos_64[14]*(x[14]-x[17]);pf=hcos_64[15]*(x[15]-x[16]); + } + + // put to 48..63 + q0=p0+pf;q1=p1+pe;q2=p2+pd;q3=p3+pc; + q4=p4+pb;q5=p5+pa;q6=p6+p9;q7=p7+p8; + q8=hcos_32[0]*(p0-pf);q9=hcos_32[1]*(p1-pe); + qa=hcos_32[2]*(p2-pd);qb=hcos_32[3]*(p3-pc); + qc=hcos_32[4]*(p4-pb);qd=hcos_32[5]*(p5-pa); + qe=hcos_32[6]*(p6-p9);qf=hcos_32[7]*(p7-p8); + + p0=q0+q7;p1=q1+q6;p2=q2+q5;p3=q3+q4; + p4=hcos_16[0]*(q0-q7);p5=hcos_16[1]*(q1-q6); + p6=hcos_16[2]*(q2-q5);p7=hcos_16[3]*(q3-q4); + p8=q8+qf;p9=q9+qe;pa=qa+qd;pb=qb+qc; + pc=hcos_16[0]*(q8-qf);pd=hcos_16[1]*(q9-qe); + pe=hcos_16[2]*(qa-qd);pf=hcos_16[3]*(qb-qc); + + q0=p0+p3;q1=p1+p2;q2=hcos_8[0]*(p0-p3);q3=hcos_8[1]*(p1-p2); + q4=p4+p7;q5=p5+p6;q6=hcos_8[0]*(p4-p7);q7=hcos_8[1]*(p5-p6); + q8=p8+pb;q9=p9+pa;qa=hcos_8[0]*(p8-pb);qb=hcos_8[1]*(p9-pa); + qc=pc+pf;qd=pd+pe;qe=hcos_8[0]*(pc-pf);qf=hcos_8[1]*(pd-pe); + + p0=q0+q1;p1=hcos_4*(q0-q1); + p2=q2+q3;p3=hcos_4*(q2-q3); + p4=q4+q5;p5=hcos_4*(q4-q5); + p6=q6+q7;p7=hcos_4*(q6-q7); + p8=q8+q9;p9=hcos_4*(q8-q9); + pa=qa+qb;pb=hcos_4*(qa-qb); + pc=qc+qd;pd=hcos_4*(qc-qd); + pe=qe+qf;pf=hcos_4*(qe-qf); + + { + REAL tmp; + + tmp=pd+pf; + OUT1(5,p5+p7+pb+tmp); + tmp+=p9; + OUT1(1,p1+tmp); + OUT2(33)=-(p1+pe+tmp); + tmp+=p5+p7; + OUT1(3,tmp); + OUT2(35)=-(p6+pe+tmp); + tmp=pa+pb+pc+pd+pe+pf; + OUT2(39)=-(p2+p3+tmp-pc); + OUT2(43)=-(p4+p6+p7+tmp-pd); + OUT2(37)=-(p5+p6+p7+tmp-pc); + OUT2(41)=-(p2+p3+tmp-pd); + tmp=p8+pc+pe+pf; + OUT2(47)=-(p0+tmp); + OUT2(45)=-(p4+p6+p7+tmp); + tmp=pb+pf; + OUT1(11,p7+tmp); + tmp+=p3; + OUT1( 9,tmp); + OUT1( 7,pd+tmp); + OUT1(13,p7+pf); + OUT1(15,pf); + } + +} + + diff --git a/mpeglib/lib/splay/dct64_down.cpp b/mpeglib/lib/splay/dct64_down.cpp new file mode 100644 index 00000000..7137664c --- /dev/null +++ b/mpeglib/lib/splay/dct64_down.cpp @@ -0,0 +1,215 @@ +/* + wrapper for dcts + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + +#include "dct.h" +#include "common.h" + +#include <iostream> + +using namespace std; + +ATTR_ALIGN(64) static REAL hcos_64_down[16]; +ATTR_ALIGN(64) static REAL hcos_32_down[8]; +ATTR_ALIGN(64) static REAL hcos_16_down[4]; +ATTR_ALIGN(64) static REAL hcos_8_down[2]; +ATTR_ALIGN(64) static REAL hcos_4_down; + +/** + This was some time ago a standalone dct class, + but to get more speed I made it an inline dct + int the filter classes +*/ + +static int dctInit=false; + +void initialize_dct64_downsample() { + if (dctInit==true) { + return; + } + dctInit=true; + + int i; + + for(i=0;i<16;i++) { + hcos_64_down[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/64.0)); + } + for(i=0;i< 8;i++) { + hcos_32_down[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/32.0)); + } + for(i=0;i< 4;i++) { + hcos_16_down[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/16.0)); + } + for(i=0;i< 2;i++) { + hcos_8_down[i]=1.0/(2.0*cos(MY_PI*double(i*2+1)/ 8.0)); + } + hcos_4_down=1.0/(2.0*cos(MY_PI*1.0/4.0)); + +} + +inline void dct64_downsample(REAL* out1,REAL* out2,REAL *fraction) { + REAL p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,pa,pb,pc,pd,pe,pf; + REAL q0,q1,q2,q3,q4,q5,q6,q7,q8,q9,qa,qb,qc,qd,qe,qf; + +#define OUT1(v,t) out1[(32-(v))*16] =(-(out1[(v)*16]=t)) +#define OUT2(v) out2[(96-(v)-32)*16]=out2[((v)-32)*16] + + // compute new values via a fast cosine transform: + /* { + register REAL *x=fraction; + + p0=x[ 0]+x[31];p1=x[ 1]+x[30];p2=x[ 2]+x[29];p3=x[ 3]+x[28]; + p4=x[ 4]+x[27];p5=x[ 5]+x[26];p6=x[ 6]+x[25];p7=x[ 7]+x[24]; + p8=x[ 8]+x[23];p9=x[ 9]+x[22];pa=x[10]+x[21];pb=x[11]+x[20]; + pc=x[12]+x[19];pd=x[13]+x[18];pe=x[14]+x[17];pf=x[15]+x[16]; + } + + q0=p0+pf;q1=p1+pe;q2=p2+pd;q3=p3+pc; + q4=p4+pb;q5=p5+pa;q6=p6+p9;q7=p7+p8; + q8=hcos_32_down[0]*(p0-pf);q9=hcos_32_down[1]*(p1-pe); + qa=hcos_32_down[2]*(p2-pd);qb=hcos_32_down[3]*(p3-pc); + qc=hcos_32_down[4]*(p4-pb);qd=hcos_32_down[5]*(p5-pa); + qe=hcos_32_down[6]*(p6-p9);qf=hcos_32_down[7]*(p7-p8); */ + + { + + register REAL *x=fraction; + + q0=x[ 0]+x[15];q1=x[ 1]+x[14];q2=x[ 2]+x[13];q3=x[ 3]+x[12]; + q4=x[ 4]+x[11];q5=x[ 5]+x[10];q6=x[ 6]+x[ 9];q7=x[ 7]+x[ 8]; + + q8=hcos_32_down[0]*(x[ 0]-x[15]);q9=hcos_32_down[1]*(x[ 1]-x[14]); + qa=hcos_32_down[2]*(x[ 2]-x[13]);qb=hcos_32_down[3]*(x[ 3]-x[12]); + qc=hcos_32_down[4]*(x[ 4]-x[11]);qd=hcos_32_down[5]*(x[ 5]-x[10]); + qe=hcos_32_down[6]*(x[ 6]-x[ 9]);qf=hcos_32_down[7]*(x[ 7]-x[ 8]); + } + + p0=q0+q7;p1=q1+q6;p2=q2+q5;p3=q3+q4; + p4=hcos_16_down[0]*(q0-q7);p5=hcos_16_down[1]*(q1-q6); + p6=hcos_16_down[2]*(q2-q5);p7=hcos_16_down[3]*(q3-q4); + p8=q8+qf;p9=q9+qe;pa=qa+qd;pb=qb+qc; + pc=hcos_16_down[0]*(q8-qf);pd=hcos_16_down[1]*(q9-qe); + pe=hcos_16_down[2]*(qa-qd);pf=hcos_16_down[3]*(qb-qc); + + q0=p0+p3;q1=p1+p2;q2=hcos_8_down[0]*(p0-p3);q3=hcos_8_down[1]*(p1-p2); + q4=p4+p7;q5=p5+p6;q6=hcos_8_down[0]*(p4-p7);q7=hcos_8_down[1]*(p5-p6); + q8=p8+pb;q9=p9+pa;qa=hcos_8_down[0]*(p8-pb);qb=hcos_8_down[1]*(p9-pa); + qc=pc+pf;qd=pd+pe;qe=hcos_8_down[0]*(pc-pf);qf=hcos_8_down[1]*(pd-pe); + + p0=q0+q1;p1=hcos_4_down*(q0-q1);p2=q2+q3;p3=hcos_4_down*(q2-q3); + p4=q4+q5;p5=hcos_4_down*(q4-q5);p6=q6+q7;p7=hcos_4_down*(q6-q7); + p8=q8+q9;p9=hcos_4_down*(q8-q9);pa=qa+qb;pb=hcos_4_down*(qa-qb); + pc=qc+qd;pd=hcos_4_down*(qc-qd);pe=qe+qf;pf=hcos_4_down*(qe-qf); + + { + register REAL tmp; + + tmp=p6+p7; + OUT2(36)=-(p5+tmp); + OUT2(44)=-(p4+tmp); + tmp=pb+pf; + OUT1(10,tmp); + OUT1(6,pd+tmp); + tmp=pe+pf; + OUT2(46)=-(p8+pc+tmp); + OUT2(34)=-(p9+pd+tmp); + tmp+=pa+pb; + OUT2(38)=-(pd+tmp); + OUT2(42)=-(pc+tmp); + OUT1(2,p9+pd+pf); + OUT1(4,p5+p7); + OUT2(48)=-p0; + out2[0]=-(out1[0]=p1); + OUT1( 8,p3); + OUT1(12,p7); + OUT1(14,pf); + OUT2(40)=-(p2+p3); + } + + { + register REAL *x=fraction; + + /* p0=hcos_64_down[ 0]*(x[ 0]-x[31]);p1=hcos_64_down[ 1]*(x[ 1]-x[30]); + p2=hcos_64_down[ 2]*(x[ 2]-x[29]);p3=hcos_64_down[ 3]*(x[ 3]-x[28]); + p4=hcos_64_down[ 4]*(x[ 4]-x[27]);p5=hcos_64_down[ 5]*(x[ 5]-x[26]); + p6=hcos_64_down[ 6]*(x[ 6]-x[25]);p7=hcos_64_down[ 7]*(x[ 7]-x[24]); + p8=hcos_64_down[ 8]*(x[ 8]-x[23]);p9=hcos_64_down[ 9]*(x[ 9]-x[22]); + pa=hcos_64_down[10]*(x[10]-x[21]);pb=hcos_64_down[11]*(x[11]-x[20]); + pc=hcos_64_down[12]*(x[12]-x[19]);pd=hcos_64_down[13]*(x[13]-x[18]); + pe=hcos_64_down[14]*(x[14]-x[17]);pf=hcos_64_down[15]*(x[15]-x[16]); */ + + p0=hcos_64_down[ 0]*x[ 0];p1=hcos_64_down[ 1]*x[ 1]; + p2=hcos_64_down[ 2]*x[ 2];p3=hcos_64_down[ 3]*x[ 3]; + p4=hcos_64_down[ 4]*x[ 4];p5=hcos_64_down[ 5]*x[ 5]; + p6=hcos_64_down[ 6]*x[ 6];p7=hcos_64_down[ 7]*x[ 7]; + p8=hcos_64_down[ 8]*x[ 8];p9=hcos_64_down[ 9]*x[ 9]; + pa=hcos_64_down[10]*x[10];pb=hcos_64_down[11]*x[11]; + pc=hcos_64_down[12]*x[12];pd=hcos_64_down[13]*x[13]; + pe=hcos_64_down[14]*x[14];pf=hcos_64_down[15]*x[15]; + } + + q0=p0+pf;q1=p1+pe;q2=p2+pd;q3=p3+pc; + q4=p4+pb;q5=p5+pa;q6=p6+p9;q7=p7+p8; + q8=hcos_32_down[0]*(p0-pf);q9=hcos_32_down[1]*(p1-pe); + qa=hcos_32_down[2]*(p2-pd);qb=hcos_32_down[3]*(p3-pc); + qc=hcos_32_down[4]*(p4-pb);qd=hcos_32_down[5]*(p5-pa); + qe=hcos_32_down[6]*(p6-p9);qf=hcos_32_down[7]*(p7-p8); + + p0=q0+q7;p1=q1+q6;p2=q2+q5;p3=q3+q4; + p4=hcos_16_down[0]*(q0-q7);p5=hcos_16_down[1]*(q1-q6); + p6=hcos_16_down[2]*(q2-q5);p7=hcos_16_down[3]*(q3-q4); + p8=q8+qf;p9=q9+qe;pa=qa+qd;pb=qb+qc; + pc=hcos_16_down[0]*(q8-qf);pd=hcos_16_down[1]*(q9-qe); + pe=hcos_16_down[2]*(qa-qd);pf=hcos_16_down[3]*(qb-qc); + + q0=p0+p3;q1=p1+p2;q2=hcos_8_down[0]*(p0-p3);q3=hcos_8_down[1]*(p1-p2); + q4=p4+p7;q5=p5+p6;q6=hcos_8_down[0]*(p4-p7);q7=hcos_8_down[1]*(p5-p6); + q8=p8+pb;q9=p9+pa;qa=hcos_8_down[0]*(p8-pb);qb=hcos_8_down[1]*(p9-pa); + qc=pc+pf;qd=pd+pe;qe=hcos_8_down[0]*(pc-pf);qf=hcos_8_down[1]*(pd-pe); + + p0=q0+q1;p1=hcos_4_down*(q0-q1); + p2=q2+q3;p3=hcos_4_down*(q2-q3); + p4=q4+q5;p5=hcos_4_down*(q4-q5); + p6=q6+q7;p7=hcos_4_down*(q6-q7); + p8=q8+q9;p9=hcos_4_down*(q8-q9); + pa=qa+qb;pb=hcos_4_down*(qa-qb); + pc=qc+qd;pd=hcos_4_down*(qc-qd); + pe=qe+qf;pf=hcos_4_down*(qe-qf); + + { + REAL tmp; + + tmp=pd+pf; + OUT1(5,p5+p7+pb+tmp); + tmp+=p9; + OUT1(1,p1+tmp); + OUT2(33)=-(p1+pe+tmp); + tmp+=p5+p7; + OUT1(3,tmp); + OUT2(35)=-(p6+pe+tmp); + tmp=pa+pb+pc+pd+pe+pf; + OUT2(39)=-(p2+p3+tmp-pc); + OUT2(43)=-(p4+p6+p7+tmp-pd); + OUT2(37)=-(p5+p6+p7+tmp-pc); + OUT2(41)=-(p2+p3+tmp-pd); + tmp=p8+pc+pe+pf; + OUT2(47)=-(p0+tmp); + OUT2(45)=-(p4+p6+p7+tmp); + tmp=pb+pf; + OUT1(11,p7+tmp); + tmp+=p3; + OUT1( 9,tmp); + OUT1( 7,pd+tmp); + OUT1(13,p7+pf); + OUT1(15,pf); + } +} + diff --git a/mpeglib/lib/splay/dump.cpp b/mpeglib/lib/splay/dump.cpp new file mode 100644 index 00000000..62551194 --- /dev/null +++ b/mpeglib/lib/splay/dump.cpp @@ -0,0 +1,157 @@ +/* + frame dumper + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +typedef float REAL; + +#define SSLIMIT 18 +#define SBLIMIT 32 + + + +#include "dump.h" +#include <stdio.h> + + +Dump::Dump() { + +} + + +Dump::~Dump() { +} + + +void Dump::dump(REAL out[SBLIMIT][SSLIMIT]) { + FILE* f=fopen("dump.raw","a+"); + int i; + int j; + for(i=0;i<SBLIMIT;i++) { + fprintf(f,"Line:%d\n",i); + for(j=0;j<SSLIMIT;j++) { + fprintf(f,"%.25f\n",out[i][j]); + } + } + fclose(f); +} + +void Dump::dump(REAL out[SBLIMIT*SSLIMIT]) { + FILE* f=fopen("dump.raw","a+"); + int i; + int line=0; + for(i=0;i<SBLIMIT*SSLIMIT;i++) { + if ( (i % SSLIMIT) == 0) { + fprintf(f,"Line:%d\n",line++); + } + fprintf(f,"%.25f\n",out[i]); + } + fclose(f); +} + +void Dump::dump2(REAL out[SSLIMIT*SBLIMIT]) { + FILE* f=fopen("dump.raw","a+"); + int i; + int j; + int line=0; + for(i=0;i<SSLIMIT;i++) { + fprintf(f,"Line:%d\n",line++); + for(j=0;j<SBLIMIT;j++) { + fprintf(f,"%.25f\n",out[i*SBLIMIT+j]); + } + } + fclose(f); +} + +void Dump::dump(REAL out[SSLIMIT][SBLIMIT]) { + FILE* f=fopen("dump.raw","a+"); + int i; + int j; + for(i=0;i<SBLIMIT;i++) { + fprintf(f,"Line:%d\n",i); + for(j=0;j<SSLIMIT;j++) { + fprintf(f,"%.25f\n",out[j][i]); + } + } + fclose(f); +} + +void Dump::dump(int out[SBLIMIT][SSLIMIT]) { + FILE* f=fopen("dump.raw","a+"); + int i; + int j; + for(i=0;i<SBLIMIT;i++) { + fprintf(f,"Line:%d\n",i); + for(j=0;j<SSLIMIT;j++) { + if (out[i][j] == 0) { + fprintf(f," %d ",out[i][j]); + continue; + } + if (out[i][j] < 0) { + fprintf(f," -x"); + continue; + } + fprintf(f," +x"); + + } + fprintf(f," \n"); + + } + fclose(f); +} + +void Dump::dump(char* ptr,int len,int ldelete) { + FILE* f; + if (ldelete) { + f=fopen("/tmp/dump.raw","w+"); + } else { + f=fopen("/tmp/dump.raw","a+"); + } + fwrite(ptr,len,1,f); + fclose(f); +} + + +void Dump::scale_zero(layer3scalefactor* out) { + + int i; + int j; + + for(i=0;i<23;i++) { + out->l[i]=0; + } + + for(i=0;i<3;i++) { + for(j=0;j<13;j++) { + out->s[i][j]=0; + } + } +} + + +void Dump::dump(layer3scalefactor* out) { + FILE* f=fopen("dump.raw","a+"); + int i; + int j; + + for(i=0;i<23;i++) { + fprintf(f,"l[%d]=%d\n",i,out->l[i]); + } + + for(i=0;i<3;i++) { + for(j=0;j<13;j++) { + fprintf(f,"s[%d][%d]=%d\n",i,j,out->s[i][j]); + } + } + fprintf(f,"---------\n"); + + fclose(f); +} diff --git a/mpeglib/lib/splay/dump.h b/mpeglib/lib/splay/dump.h new file mode 100644 index 00000000..47ef4d48 --- /dev/null +++ b/mpeglib/lib/splay/dump.h @@ -0,0 +1,36 @@ +/* + frame dumper + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#ifndef __DUMP_H +#define __DUMP_H + +#include "mpegsound.h" + +class Dump { + + public: + Dump(); + ~Dump(); + + void dump(REAL out[SBLIMIT][SSLIMIT]); + void dump(REAL out[SBLIMIT*SSLIMIT]); + void dump2(REAL out[SSLIMIT*SBLIMIT]); + void dump(REAL out[SSLIMIT][SBLIMIT]); + void dump(int out[SBLIMIT][SSLIMIT]); + void dump(layer3scalefactor* out); + void dump(char* prt,int len,int ldelete=false); + void scale_zero(layer3scalefactor* out); + + +}; +#endif diff --git a/mpeglib/lib/splay/dxHead.cpp b/mpeglib/lib/splay/dxHead.cpp new file mode 100644 index 00000000..a96bb553 --- /dev/null +++ b/mpeglib/lib/splay/dxHead.cpp @@ -0,0 +1,129 @@ +/*---- DXhead.c -------------------------------------------- + +decoder MPEG Layer III +handle Xing header +mod 12/7/98 add vbr scale + +Copyright 1998 Xing Technology Corp. +-----------------------------------------------------------*/ +#include <stdlib.h> +#include <stdio.h> +#include <float.h> +#include <math.h> +#include "dxHead.h" + +// 4 Xing +// 4 flags +// 4 frames +// 4 bytes +// 100 toc + +/*-------------------------------------------------------------*/ +static int ExtractI4(unsigned char *buf) +{ +int x; +// big endian extract + +x = buf[0]; +x <<= 8; +x |= buf[1]; +x <<= 8; +x |= buf[2]; +x <<= 8; +x |= buf[3]; + +return x; +} +/*-------------------------------------------------------------*/ +int GetXingHeader(XHEADDATA *X, unsigned char *buf) +{ +int i, head_flags; +int h_id, h_mode, h_sr_index; +static const int sr_table[4] = { 44100, 48000, 32000, 99999 }; + +// get Xing header data + + +X->flags = 0; // clear to null incase fail + + +// get selected MPEG header data +h_id = (buf[1] >> 3) & 1; +h_sr_index = (buf[2] >> 2) & 3; +h_mode = (buf[3] >> 6) & 3; + + +// determine offset of header +if( h_id ) { // mpeg1 + if( h_mode != 3 ) buf+=(32+4); + else buf+=(17+4); +} +else { // mpeg2 + if( h_mode != 3 ) buf+=(17+4); + else buf+=(9+4); +} + +if( buf[0] != 'X' ) return 0; // fail +if( buf[1] != 'i' ) return 0; // header not found +if( buf[2] != 'n' ) return 0; +if( buf[3] != 'g' ) return 0; +buf+=4; + +X->h_id = h_id; +X->samprate = sr_table[h_sr_index]; +if( h_id == 0 ) X->samprate >>= 1; + +head_flags = X->flags = ExtractI4(buf); buf+=4; // get flags + +if( head_flags & FRAMES_FLAG ) {X->frames = ExtractI4(buf); buf+=4;} +if( head_flags & BYTES_FLAG ) {X->bytes = ExtractI4(buf); buf+=4;} + +if( head_flags & TOC_FLAG ) { + if( X->toc != NULL ) { + for(i=0;i<100;i++) X->toc[i] = buf[i]; + } + buf+=100; +} + +X->vbr_scale = -1; +if( head_flags & VBR_SCALE_FLAG ) {X->vbr_scale = ExtractI4(buf); buf+=4;} + +//if( X->toc != NULL ) { +//for(i=0;i<100;i++) { +// if( (i%10) == 0 ) printf("\n"); +// printf(" %3d", (int)(X->toc[i])); +//} +//} + +return 1; // success +} +/*-------------------------------------------------------------*/ +int SeekPoint(unsigned char TOC[100], int file_bytes, float percent) +{ +// interpolate in TOC to get file seek point in bytes +int a, seekpoint; +float fa, fb, fx; + + +if( percent < 0.0f ) percent = 0.0f; +if( percent > 100.0f ) percent = 100.0f; + +a = (int)percent; +if( a > 99 ) a = 99; +fa = TOC[a]; +if( a < 99 ) { + fb = TOC[a+1]; +} +else { + fb = 256.0f; +} + +fx = fa + (fb-fa)*(percent-a); +//printf("%f ....... %f ...... %f\n",fa,fb,fx); + +seekpoint = (int)((1.0f/256.0f)*fx*file_bytes); + + +return seekpoint; +} +/*-------------------------------------------------------------*/ diff --git a/mpeglib/lib/splay/dxHead.h b/mpeglib/lib/splay/dxHead.h new file mode 100644 index 00000000..da0f2eff --- /dev/null +++ b/mpeglib/lib/splay/dxHead.h @@ -0,0 +1,66 @@ +/*---- DXhead.h ------------------------------------------- + + +decoder MPEG Layer III + +handle Xing header + + +Copyright 1998 Xing Technology Corp. +-----------------------------------------------------------*/ +// A Xing header may be present in the ancillary +// data field of the first frame of an mp3 bitstream +// The Xing header (optionally) contains +// frames total number of audio frames in the bitstream +// bytes total number of bytes in the bitstream +// toc table of contents + +// toc (table of contents^) gives seek points +// for random access +// the ith entry determines the seek point for +// i-percent duration +// seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes +// e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes + +#ifndef __DXHEAD_H +#define __DXHEAD_H + +#define FRAMES_FLAG 0x0001 +#define BYTES_FLAG 0x0002 +#define TOC_FLAG 0x0004 +#define VBR_SCALE_FLAG 0x0008 + +#define FRAMES_AND_BYTES (FRAMES_FLAG | BYTES_FLAG) + +// structure to receive extracted header +// toc may be NULL + +typedef struct XHEADDATA_s { + int h_id; // from MPEG header, 0=MPEG2, 1=MPEG1 + int samprate; // determined from MPEG header + int flags; // from Xing header data + int frames; // total bit stream frames from Xing header data + int bytes; // total bit stream bytes from Xing header data + int vbr_scale; // encoded vbr scale from Xing header data + unsigned char *toc; // pointer to unsigned char toc_buffer[100] + // may be NULL if toc not desired +} XHEADDATA; + +int GetXingHeader(XHEADDATA *X, unsigned char *buf); + +// return 0=fail, 1=success +// X structure to receive header data (output) +// buf bitstream input + + +int SeekPoint(unsigned char TOC[100], int file_bytes, float percent); +// return seekpoint in bytes (may be at eof if percent=100.0) +// TOC = table of contents from Xing header +// file_bytes = number of bytes in mp3 file +// percent = play time percentage of total playtime. May be +// fractional (e.g. 87.245) + + +#endif + + diff --git a/mpeglib/lib/splay/huffmanlookup.cpp b/mpeglib/lib/splay/huffmanlookup.cpp new file mode 100644 index 00000000..e4b37453 --- /dev/null +++ b/mpeglib/lib/splay/huffmanlookup.cpp @@ -0,0 +1,120 @@ + /* + + Copyright (C) 2000 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + */ + +#include "huffmanlookup.h" +#include <assert.h> + + + + +struct HuffmanLookup::decodeData HuffmanLookup::qdecode[32][256]; +/* for initialization */ +static HuffmanLookup l; + +HuffmanLookup::HuffmanLookup() +{ + int table,p,x,y; + + for(table = 0; table < 32; table++) + { + // 8 bits pattern + for(p = 0; p < 256; p++) + { + bits = 24; + pattern = (p << 16); + + huffmandecoder_1(&Mpegtoraw::ht[table], &x,&y); + + int used = 24 - bits; + qdecode[table][p].skip = (used <= 8)?used:0; + qdecode[table][p].x = x; + qdecode[table][p].y = y; + } + } +} + +int HuffmanLookup::wgetbit() +{ + return (pattern >> --bits) & 1; +} + +int HuffmanLookup::wgetbits (int b) +{ + bits -= b; + return (pattern >> bits) & ((1 << b) - 1); +} + +void HuffmanLookup::huffmandecoder_1(const HUFFMANCODETABLE *h, int *x, int *y) +{ + typedef unsigned int HUFFBITS; + + HUFFBITS level=(1<<(sizeof(HUFFBITS)*8-1)); + int point=0; + /* Lookup in Huffman table. */ + for(;;) + { + if(h->val[point][0]==0) + { /*end of tree*/ + int xx,yy; + + xx=h->val[point][1]>>4; + yy=h->val[point][1]&0xf; + + if(h->linbits) + { + if((h->xlen)==(unsigned)xx)xx+=wgetbits(h->linbits); + if(xx)if(wgetbit())xx=-xx; + if((h->ylen)==(unsigned)yy)yy+=wgetbits(h->linbits); + if(yy)if(wgetbit())yy=-yy; + } + else + { + if(xx)if(wgetbit())xx=-xx; + if(yy)if(wgetbit())yy=-yy; + } + *x=xx;*y=yy; + break; + } + + point+=h->val[point][wgetbit()]; + + level>>=1; + if(!(level || ((unsigned)point<Mpegtoraw::ht->treelen))) + { + register int xx,yy; + + xx=(h->xlen<<1);// set x and y to a medium value as a simple concealment + yy=(h->ylen<<1); + + // h->xlen and h->ylen can't be 1 under tablename 32 + // if(xx) + if(wgetbit())xx=-xx; + // if(yy) + if(wgetbit())yy=-yy; + + *x=xx;*y=yy; + break; + } + } +} + + diff --git a/mpeglib/lib/splay/huffmanlookup.h b/mpeglib/lib/splay/huffmanlookup.h new file mode 100644 index 00000000..a5bdb26c --- /dev/null +++ b/mpeglib/lib/splay/huffmanlookup.h @@ -0,0 +1,57 @@ + /* + + Copyright (C) 2000 Stefan Westerfeld + stefan@space.twc.de + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + */ + +#ifndef __HUFFMANLOOKUP_H +#define __HUFFMANLOOKUP_H +#include "mpegsound.h" + +/* + * This class speeds up the huffman table decoding by largely replacing it + * by a table lookup. It uses the fact that the huffman tables don't change, + * and that given a byte of the bitstream, we can predict what the result + * will be (without reading it bit by bit). + */ + +class HuffmanLookup { +private: + long pattern, bits; + int wgetbit(); + int wgetbits (int b); + void huffmandecoder_1(const HUFFMANCODETABLE *h,int *x, int *y); + + ATTR_ALIGN(64) static struct decodeData { + int x : 8; + int y : 8; + int skip : 16; + } qdecode[32][256]; +public: + HuffmanLookup(); + + static int decode(int table, int pattern, int* x, int* y) + { + *x = qdecode[table][pattern].x; + *y = qdecode[table][pattern].y; + return qdecode[table][pattern].skip; + } +}; + +#endif diff --git a/mpeglib/lib/splay/huffmantable.cpp b/mpeglib/lib/splay/huffmantable.cpp new file mode 100644 index 00000000..a1fe20e5 --- /dev/null +++ b/mpeglib/lib/splay/huffmantable.cpp @@ -0,0 +1,584 @@ +/* MPEG/WAVE Sound library + + (C) 1997 by Jung woo-jae */ + +// Huffmantable.cc +// It contains initialized huffman table for MPEG layer 3 + + +#include "mpegsound.h" + +static const unsigned int +htd01[ 7][2]={{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 16},{ 2, 1},{ 0, 1}, + { 0, 17}}, + +htd02[ 17][2]={{ 2, 1},{ 0, 0},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1}, + { 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32},{ 0, 33}, + { 2, 1},{ 0, 18},{ 2, 1},{ 0, 2},{ 0, 34}}, + +htd03[ 17][2]={{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 1},{ 2, 1},{ 0, 17}, + { 2, 1},{ 0, 16},{ 4, 1},{ 2, 1},{ 0, 32},{ 0, 33}, + { 2, 1},{ 0, 18},{ 2, 1},{ 0, 2},{ 0, 34}}, + +htd05[ 31][2]={{ 2, 1},{ 0, 0},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1}, + { 2, 1},{ 0, 17},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 32}, + { 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 8, 1},{ 4, 1}, + { 2, 1},{ 0, 34},{ 0, 48},{ 2, 1},{ 0, 3},{ 0, 19}, + { 2, 1},{ 0, 49},{ 2, 1},{ 0, 50},{ 2, 1},{ 0, 35}, + { 0, 51}}, + +htd06[ 31][2]={{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 16},{ 0, 17}, + { 6, 1},{ 2, 1},{ 0, 1},{ 2, 1},{ 0, 32},{ 0, 33}, + { 6, 1},{ 2, 1},{ 0, 18},{ 2, 1},{ 0, 2},{ 0, 34}, + { 4, 1},{ 2, 1},{ 0, 49},{ 0, 19},{ 4, 1},{ 2, 1}, + { 0, 48},{ 0, 50},{ 2, 1},{ 0, 35},{ 2, 1},{ 0, 3}, + { 0, 51}}, + +htd07[ 71][2]={{ 2, 1},{ 0, 0},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1}, + { 8, 1},{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32}, + { 0, 2},{ 0, 33},{ 18, 1},{ 6, 1},{ 2, 1},{ 0, 18}, + { 2, 1},{ 0, 34},{ 0, 48},{ 4, 1},{ 2, 1},{ 0, 49}, + { 0, 19},{ 4, 1},{ 2, 1},{ 0, 3},{ 0, 50},{ 2, 1}, + { 0, 35},{ 0, 4},{ 10, 1},{ 4, 1},{ 2, 1},{ 0, 64}, + { 0, 65},{ 2, 1},{ 0, 20},{ 2, 1},{ 0, 66},{ 0, 36}, + { 12, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 51},{ 0, 67}, + { 0, 80},{ 4, 1},{ 2, 1},{ 0, 52},{ 0, 5},{ 0, 81}, + { 6, 1},{ 2, 1},{ 0, 21},{ 2, 1},{ 0, 82},{ 0, 37}, + + { 4, 1},{ 2, 1},{ 0, 68},{ 0, 53},{ 4, 1},{ 2, 1}, + { 0, 83},{ 0, 84},{ 2, 1},{ 0, 69},{ 0, 85}}, + +htd08[ 71][2]={{ 6, 1},{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 16},{ 0, 1}, + { 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 33},{ 0, 18}, + { 14, 1},{ 4, 1},{ 2, 1},{ 0, 32},{ 0, 2},{ 2, 1}, + { 0, 34},{ 4, 1},{ 2, 1},{ 0, 48},{ 0, 3},{ 2, 1}, + { 0, 49},{ 0, 19},{ 14, 1},{ 8, 1},{ 4, 1},{ 2, 1}, + { 0, 50},{ 0, 35},{ 2, 1},{ 0, 64},{ 0, 4},{ 2, 1}, + { 0, 65},{ 2, 1},{ 0, 20},{ 0, 66},{ 12, 1},{ 6, 1}, + { 2, 1},{ 0, 36},{ 2, 1},{ 0, 51},{ 0, 80},{ 4, 1}, + { 2, 1},{ 0, 67},{ 0, 52},{ 0, 81},{ 6, 1},{ 2, 1}, + { 0, 21},{ 2, 1},{ 0, 5},{ 0, 82},{ 6, 1},{ 2, 1}, + + { 0, 37},{ 2, 1},{ 0, 68},{ 0, 53},{ 2, 1},{ 0, 83}, + { 2, 1},{ 0, 69},{ 2, 1},{ 0, 84},{ 0, 85}}, + +htd09[ 71][2]={{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 16},{ 2, 1}, + { 0, 1},{ 0, 17},{ 10, 1},{ 4, 1},{ 2, 1},{ 0, 32}, + { 0, 33},{ 2, 1},{ 0, 18},{ 2, 1},{ 0, 2},{ 0, 34}, + { 12, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 48},{ 0, 3}, + { 0, 49},{ 2, 1},{ 0, 19},{ 2, 1},{ 0, 50},{ 0, 35}, + { 12, 1},{ 4, 1},{ 2, 1},{ 0, 65},{ 0, 20},{ 4, 1}, + { 2, 1},{ 0, 64},{ 0, 51},{ 2, 1},{ 0, 66},{ 0, 36}, + { 10, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 4},{ 0, 80}, + { 0, 67},{ 2, 1},{ 0, 52},{ 0, 81},{ 8, 1},{ 4, 1}, + { 2, 1},{ 0, 21},{ 0, 82},{ 2, 1},{ 0, 37},{ 0, 68}, + + { 6, 1},{ 4, 1},{ 2, 1},{ 0, 5},{ 0, 84},{ 0, 83}, + { 2, 1},{ 0, 53},{ 2, 1},{ 0, 69},{ 0, 85}}, + +htd10[127][2]={{ 2, 1},{ 0, 0},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1}, + { 10, 1},{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32}, + { 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 28, 1},{ 8, 1}, + { 4, 1},{ 2, 1},{ 0, 34},{ 0, 48},{ 2, 1},{ 0, 49}, + { 0, 19},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 3},{ 0, 50}, + { 2, 1},{ 0, 35},{ 0, 64},{ 4, 1},{ 2, 1},{ 0, 65}, + { 0, 20},{ 4, 1},{ 2, 1},{ 0, 4},{ 0, 51},{ 2, 1}, + { 0, 66},{ 0, 36},{ 28, 1},{ 10, 1},{ 6, 1},{ 4, 1}, + { 2, 1},{ 0, 80},{ 0, 5},{ 0, 96},{ 2, 1},{ 0, 97}, + { 0, 22},{ 12, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 67}, + + { 0, 52},{ 0, 81},{ 2, 1},{ 0, 21},{ 2, 1},{ 0, 82}, + { 0, 37},{ 4, 1},{ 2, 1},{ 0, 38},{ 0, 54},{ 0,113}, + { 20, 1},{ 8, 1},{ 2, 1},{ 0, 23},{ 4, 1},{ 2, 1}, + { 0, 68},{ 0, 83},{ 0, 6},{ 6, 1},{ 4, 1},{ 2, 1}, + { 0, 53},{ 0, 69},{ 0, 98},{ 2, 1},{ 0,112},{ 2, 1}, + { 0, 7},{ 0,100},{ 14, 1},{ 4, 1},{ 2, 1},{ 0,114}, + { 0, 39},{ 6, 1},{ 2, 1},{ 0, 99},{ 2, 1},{ 0, 84}, + { 0, 85},{ 2, 1},{ 0, 70},{ 0,115},{ 8, 1},{ 4, 1}, + { 2, 1},{ 0, 55},{ 0,101},{ 2, 1},{ 0, 86},{ 0,116}, + { 6, 1},{ 2, 1},{ 0, 71},{ 2, 1},{ 0,102},{ 0,117}, + + { 4, 1},{ 2, 1},{ 0, 87},{ 0,118},{ 2, 1},{ 0,103}, + { 0,119}}, + +htd11[127][2]={{ 6, 1},{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 16},{ 0, 1}, + { 8, 1},{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32}, + { 0, 2},{ 0, 18},{ 24, 1},{ 8, 1},{ 2, 1},{ 0, 33}, + { 2, 1},{ 0, 34},{ 2, 1},{ 0, 48},{ 0, 3},{ 4, 1}, + { 2, 1},{ 0, 49},{ 0, 19},{ 4, 1},{ 2, 1},{ 0, 50}, + { 0, 35},{ 4, 1},{ 2, 1},{ 0, 64},{ 0, 4},{ 2, 1}, + { 0, 65},{ 0, 20},{ 30, 1},{ 16, 1},{ 10, 1},{ 4, 1}, + { 2, 1},{ 0, 66},{ 0, 36},{ 4, 1},{ 2, 1},{ 0, 51}, + { 0, 67},{ 0, 80},{ 4, 1},{ 2, 1},{ 0, 52},{ 0, 81}, + { 0, 97},{ 6, 1},{ 2, 1},{ 0, 22},{ 2, 1},{ 0, 6}, + + { 0, 38},{ 2, 1},{ 0, 98},{ 2, 1},{ 0, 21},{ 2, 1}, + { 0, 5},{ 0, 82},{ 16, 1},{ 10, 1},{ 6, 1},{ 4, 1}, + { 2, 1},{ 0, 37},{ 0, 68},{ 0, 96},{ 2, 1},{ 0, 99}, + { 0, 54},{ 4, 1},{ 2, 1},{ 0,112},{ 0, 23},{ 0,113}, + { 16, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 7},{ 0,100}, + { 0,114},{ 2, 1},{ 0, 39},{ 4, 1},{ 2, 1},{ 0, 83}, + { 0, 53},{ 2, 1},{ 0, 84},{ 0, 69},{ 10, 1},{ 4, 1}, + { 2, 1},{ 0, 70},{ 0,115},{ 2, 1},{ 0, 55},{ 2, 1}, + { 0,101},{ 0, 86},{ 10, 1},{ 6, 1},{ 4, 1},{ 2, 1}, + { 0, 85},{ 0, 87},{ 0,116},{ 2, 1},{ 0, 71},{ 0,102}, + + { 4, 1},{ 2, 1},{ 0,117},{ 0,118},{ 2, 1},{ 0,103}, + { 0,119}}, + +htd12[127][2]={{ 12, 1},{ 4, 1},{ 2, 1},{ 0, 16},{ 0, 1},{ 2, 1}, + { 0, 17},{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 32},{ 0, 2}, + { 16, 1},{ 4, 1},{ 2, 1},{ 0, 33},{ 0, 18},{ 4, 1}, + { 2, 1},{ 0, 34},{ 0, 49},{ 2, 1},{ 0, 19},{ 2, 1}, + { 0, 48},{ 2, 1},{ 0, 3},{ 0, 64},{ 26, 1},{ 8, 1}, + { 4, 1},{ 2, 1},{ 0, 50},{ 0, 35},{ 2, 1},{ 0, 65}, + { 0, 51},{ 10, 1},{ 4, 1},{ 2, 1},{ 0, 20},{ 0, 66}, + { 2, 1},{ 0, 36},{ 2, 1},{ 0, 4},{ 0, 80},{ 4, 1}, + { 2, 1},{ 0, 67},{ 0, 52},{ 2, 1},{ 0, 81},{ 0, 21}, + { 28, 1},{ 14, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 82}, + + { 0, 37},{ 2, 1},{ 0, 83},{ 0, 53},{ 4, 1},{ 2, 1}, + { 0, 96},{ 0, 22},{ 0, 97},{ 4, 1},{ 2, 1},{ 0, 98}, + { 0, 38},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 5},{ 0, 6}, + { 0, 68},{ 2, 1},{ 0, 84},{ 0, 69},{ 18, 1},{ 10, 1}, + { 4, 1},{ 2, 1},{ 0, 99},{ 0, 54},{ 4, 1},{ 2, 1}, + { 0,112},{ 0, 7},{ 0,113},{ 4, 1},{ 2, 1},{ 0, 23}, + { 0,100},{ 2, 1},{ 0, 70},{ 0,114},{ 10, 1},{ 6, 1}, + { 2, 1},{ 0, 39},{ 2, 1},{ 0, 85},{ 0,115},{ 2, 1}, + { 0, 55},{ 0, 86},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,101}, + { 0,116},{ 2, 1},{ 0, 71},{ 0,102},{ 4, 1},{ 2, 1}, + + { 0,117},{ 0, 87},{ 2, 1},{ 0,118},{ 2, 1},{ 0,103}, + { 0,119}}, + +htd13[511][2]={{ 2, 1},{ 0, 0},{ 6, 1},{ 2, 1},{ 0, 16},{ 2, 1}, + { 0, 1},{ 0, 17},{ 28, 1},{ 8, 1},{ 4, 1},{ 2, 1}, + { 0, 32},{ 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 8, 1}, + { 4, 1},{ 2, 1},{ 0, 34},{ 0, 48},{ 2, 1},{ 0, 3}, + { 0, 49},{ 6, 1},{ 2, 1},{ 0, 19},{ 2, 1},{ 0, 50}, + { 0, 35},{ 4, 1},{ 2, 1},{ 0, 64},{ 0, 4},{ 0, 65}, + { 70, 1},{ 28, 1},{ 14, 1},{ 6, 1},{ 2, 1},{ 0, 20}, + { 2, 1},{ 0, 51},{ 0, 66},{ 4, 1},{ 2, 1},{ 0, 36}, + { 0, 80},{ 2, 1},{ 0, 67},{ 0, 52},{ 4, 1},{ 2, 1}, + { 0, 81},{ 0, 21},{ 4, 1},{ 2, 1},{ 0, 5},{ 0, 82}, // 60 + + { 2, 1},{ 0, 37},{ 2, 1},{ 0, 68},{ 0, 83},{ 14, 1}, + { 8, 1},{ 4, 1},{ 2, 1},{ 0, 96},{ 0, 6},{ 2, 1}, + { 0, 97},{ 0, 22},{ 4, 1},{ 2, 1},{ 0,128},{ 0, 8}, + { 0,129},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 53}, + { 0, 98},{ 2, 1},{ 0, 38},{ 0, 84},{ 4, 1},{ 2, 1}, + { 0, 69},{ 0, 99},{ 2, 1},{ 0, 54},{ 0,112},{ 6, 1}, + { 4, 1},{ 2, 1},{ 0, 7},{ 0, 85},{ 0,113},{ 2, 1}, + { 0, 23},{ 2, 1},{ 0, 39},{ 0, 55},{ 72, 1},{ 24, 1}, + { 12, 1},{ 4, 1},{ 2, 1},{ 0, 24},{ 0,130},{ 2, 1}, + { 0, 40},{ 4, 1},{ 2, 1},{ 0,100},{ 0, 70},{ 0,114}, // 120 + + { 8, 1},{ 4, 1},{ 2, 1},{ 0,132},{ 0, 72},{ 2, 1}, + { 0,144},{ 0, 9},{ 2, 1},{ 0,145},{ 0, 25},{ 24, 1}, + { 14, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,115},{ 0,101}, + { 2, 1},{ 0, 86},{ 0,116},{ 4, 1},{ 2, 1},{ 0, 71}, + { 0,102},{ 0,131},{ 6, 1},{ 2, 1},{ 0, 56},{ 2, 1}, + { 0,117},{ 0, 87},{ 2, 1},{ 0,146},{ 0, 41},{ 14, 1}, + { 8, 1},{ 4, 1},{ 2, 1},{ 0,103},{ 0,133},{ 2, 1}, + { 0, 88},{ 0, 57},{ 2, 1},{ 0,147},{ 2, 1},{ 0, 73}, + { 0,134},{ 6, 1},{ 2, 1},{ 0,160},{ 2, 1},{ 0,104}, + { 0, 10},{ 2, 1},{ 0,161},{ 0, 26},{ 68, 1},{ 24, 1}, // 180 + + { 12, 1},{ 4, 1},{ 2, 1},{ 0,162},{ 0, 42},{ 4, 1}, + { 2, 1},{ 0,149},{ 0, 89},{ 2, 1},{ 0,163},{ 0, 58}, + { 8, 1},{ 4, 1},{ 2, 1},{ 0, 74},{ 0,150},{ 2, 1}, + { 0,176},{ 0, 11},{ 2, 1},{ 0,177},{ 0, 27},{ 20, 1}, + { 8, 1},{ 2, 1},{ 0,178},{ 4, 1},{ 2, 1},{ 0,118}, + { 0,119},{ 0,148},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,135}, + { 0,120},{ 0,164},{ 4, 1},{ 2, 1},{ 0,105},{ 0,165}, + { 0, 43},{ 12, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 90}, + { 0,136},{ 0,179},{ 2, 1},{ 0, 59},{ 2, 1},{ 0,121}, + { 0,166},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,106},{ 0,180}, // 240 + + { 0,192},{ 4, 1},{ 2, 1},{ 0, 12},{ 0,152},{ 0,193}, + { 60, 1},{ 22, 1},{ 10, 1},{ 6, 1},{ 2, 1},{ 0, 28}, + { 2, 1},{ 0,137},{ 0,181},{ 2, 1},{ 0, 91},{ 0,194}, + { 4, 1},{ 2, 1},{ 0, 44},{ 0, 60},{ 4, 1},{ 2, 1}, + { 0,182},{ 0,107},{ 2, 1},{ 0,196},{ 0, 76},{ 16, 1}, + { 8, 1},{ 4, 1},{ 2, 1},{ 0,168},{ 0,138},{ 2, 1}, + { 0,208},{ 0, 13},{ 2, 1},{ 0,209},{ 2, 1},{ 0, 75}, + { 2, 1},{ 0,151},{ 0,167},{ 12, 1},{ 6, 1},{ 2, 1}, + { 0,195},{ 2, 1},{ 0,122},{ 0,153},{ 4, 1},{ 2, 1}, + { 0,197},{ 0, 92},{ 0,183},{ 4, 1},{ 2, 1},{ 0, 29}, // 300 + + { 0,210},{ 2, 1},{ 0, 45},{ 2, 1},{ 0,123},{ 0,211}, + { 52, 1},{ 28, 1},{ 12, 1},{ 4, 1},{ 2, 1},{ 0, 61}, + { 0,198},{ 4, 1},{ 2, 1},{ 0,108},{ 0,169},{ 2, 1}, + { 0,154},{ 0,212},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,184}, + { 0,139},{ 2, 1},{ 0, 77},{ 0,199},{ 4, 1},{ 2, 1}, + { 0,124},{ 0,213},{ 2, 1},{ 0, 93},{ 0,224},{ 10, 1}, + { 4, 1},{ 2, 1},{ 0,225},{ 0, 30},{ 4, 1},{ 2, 1}, + { 0, 14},{ 0, 46},{ 0,226},{ 8, 1},{ 4, 1},{ 2, 1}, + { 0,227},{ 0,109},{ 2, 1},{ 0,140},{ 0,228},{ 4, 1}, + { 2, 1},{ 0,229},{ 0,186},{ 0,240},{ 38, 1},{ 16, 1}, // 360 + + { 4, 1},{ 2, 1},{ 0,241},{ 0, 31},{ 6, 1},{ 4, 1}, + { 2, 1},{ 0,170},{ 0,155},{ 0,185},{ 2, 1},{ 0, 62}, + { 2, 1},{ 0,214},{ 0,200},{ 12, 1},{ 6, 1},{ 2, 1}, + { 0, 78},{ 2, 1},{ 0,215},{ 0,125},{ 2, 1},{ 0,171}, + { 2, 1},{ 0, 94},{ 0,201},{ 6, 1},{ 2, 1},{ 0, 15}, + { 2, 1},{ 0,156},{ 0,110},{ 2, 1},{ 0,242},{ 0, 47}, + { 32, 1},{ 16, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,216}, + { 0,141},{ 0, 63},{ 6, 1},{ 2, 1},{ 0,243},{ 2, 1}, + { 0,230},{ 0,202},{ 2, 1},{ 0,244},{ 0, 79},{ 8, 1}, + { 4, 1},{ 2, 1},{ 0,187},{ 0,172},{ 2, 1},{ 0,231}, // 420 + + { 0,245},{ 4, 1},{ 2, 1},{ 0,217},{ 0,157},{ 2, 1}, + { 0, 95},{ 0,232},{ 30, 1},{ 12, 1},{ 6, 1},{ 2, 1}, + { 0,111},{ 2, 1},{ 0,246},{ 0,203},{ 4, 1},{ 2, 1}, + { 0,188},{ 0,173},{ 0,218},{ 8, 1},{ 2, 1},{ 0,247}, + { 4, 1},{ 2, 1},{ 0,126},{ 0,127},{ 0,142},{ 6, 1}, + { 4, 1},{ 2, 1},{ 0,158},{ 0,174},{ 0,204},{ 2, 1}, + { 0,248},{ 0,143},{ 18, 1},{ 8, 1},{ 4, 1},{ 2, 1}, + { 0,219},{ 0,189},{ 2, 1},{ 0,234},{ 0,249},{ 4, 1}, + { 2, 1},{ 0,159},{ 0,235},{ 2, 1},{ 0,190},{ 2, 1}, + { 0,205},{ 0,250},{ 14, 1},{ 4, 1},{ 2, 1},{ 0,221}, // 480 + + { 0,236},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,233},{ 0,175}, + { 0,220},{ 2, 1},{ 0,206},{ 0,251},{ 8, 1},{ 4, 1}, + { 2, 1},{ 0,191},{ 0,222},{ 2, 1},{ 0,207},{ 0,238}, + { 4, 1},{ 2, 1},{ 0,223},{ 0,239},{ 2, 1},{ 0,255}, + { 2, 1},{ 0,237},{ 2, 1},{ 0,253},{ 2, 1},{ 0,252}, + { 0,254}}, + +htd15[511][2]={{ 16, 1},{ 6, 1},{ 2, 1},{ 0, 0},{ 2, 1},{ 0, 16}, + { 0, 1},{ 2, 1},{ 0, 17},{ 4, 1},{ 2, 1},{ 0, 32}, + { 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 50, 1},{ 16, 1}, + { 6, 1},{ 2, 1},{ 0, 34},{ 2, 1},{ 0, 48},{ 0, 49}, + { 6, 1},{ 2, 1},{ 0, 19},{ 2, 1},{ 0, 3},{ 0, 64}, + { 2, 1},{ 0, 50},{ 0, 35},{ 14, 1},{ 6, 1},{ 4, 1}, + { 2, 1},{ 0, 4},{ 0, 20},{ 0, 65},{ 4, 1},{ 2, 1}, + { 0, 51},{ 0, 66},{ 2, 1},{ 0, 36},{ 0, 67},{ 10, 1}, + { 6, 1},{ 2, 1},{ 0, 52},{ 2, 1},{ 0, 80},{ 0, 5}, + { 2, 1},{ 0, 81},{ 0, 21},{ 4, 1},{ 2, 1},{ 0, 82}, // 60 + + { 0, 37},{ 4, 1},{ 2, 1},{ 0, 68},{ 0, 83},{ 0, 97}, + { 90, 1},{ 36, 1},{ 18, 1},{ 10, 1},{ 6, 1},{ 2, 1}, + { 0, 53},{ 2, 1},{ 0, 96},{ 0, 6},{ 2, 1},{ 0, 22}, + { 0, 98},{ 4, 1},{ 2, 1},{ 0, 38},{ 0, 84},{ 2, 1}, + { 0, 69},{ 0, 99},{ 10, 1},{ 6, 1},{ 2, 1},{ 0, 54}, + { 2, 1},{ 0,112},{ 0, 7},{ 2, 1},{ 0,113},{ 0, 85}, + { 4, 1},{ 2, 1},{ 0, 23},{ 0,100},{ 2, 1},{ 0,114}, + { 0, 39},{ 24, 1},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1}, + { 0, 70},{ 0,115},{ 2, 1},{ 0, 55},{ 0,101},{ 4, 1}, + { 2, 1},{ 0, 86},{ 0,128},{ 2, 1},{ 0, 8},{ 0,116}, // 120 + + { 4, 1},{ 2, 1},{ 0,129},{ 0, 24},{ 2, 1},{ 0,130}, + { 0, 40},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 71}, + { 0,102},{ 2, 1},{ 0,131},{ 0, 56},{ 4, 1},{ 2, 1}, + { 0,117},{ 0, 87},{ 2, 1},{ 0,132},{ 0, 72},{ 6, 1}, + { 4, 1},{ 2, 1},{ 0,144},{ 0, 25},{ 0,145},{ 4, 1}, + { 2, 1},{ 0,146},{ 0,118},{ 2, 1},{ 0,103},{ 0, 41}, + { 92, 1},{ 36, 1},{ 18, 1},{ 10, 1},{ 4, 1},{ 2, 1}, + { 0,133},{ 0, 88},{ 4, 1},{ 2, 1},{ 0, 9},{ 0,119}, + { 0,147},{ 4, 1},{ 2, 1},{ 0, 57},{ 0,148},{ 2, 1}, + { 0, 73},{ 0,134},{ 10, 1},{ 6, 1},{ 2, 1},{ 0,104}, // 180 + + { 2, 1},{ 0,160},{ 0, 10},{ 2, 1},{ 0,161},{ 0, 26}, + { 4, 1},{ 2, 1},{ 0,162},{ 0, 42},{ 2, 1},{ 0,149}, + { 0, 89},{ 26, 1},{ 14, 1},{ 6, 1},{ 2, 1},{ 0,163}, + { 2, 1},{ 0, 58},{ 0,135},{ 4, 1},{ 2, 1},{ 0,120}, + { 0,164},{ 2, 1},{ 0, 74},{ 0,150},{ 6, 1},{ 4, 1}, + { 2, 1},{ 0,105},{ 0,176},{ 0,177},{ 4, 1},{ 2, 1}, + { 0, 27},{ 0,165},{ 0,178},{ 14, 1},{ 8, 1},{ 4, 1}, + { 2, 1},{ 0, 90},{ 0, 43},{ 2, 1},{ 0,136},{ 0,151}, + { 2, 1},{ 0,179},{ 2, 1},{ 0,121},{ 0, 59},{ 8, 1}, + { 4, 1},{ 2, 1},{ 0,106},{ 0,180},{ 2, 1},{ 0, 75}, // 240 + + { 0,193},{ 4, 1},{ 2, 1},{ 0,152},{ 0,137},{ 2, 1}, + { 0, 28},{ 0,181},{ 80, 1},{ 34, 1},{ 16, 1},{ 6, 1}, + { 4, 1},{ 2, 1},{ 0, 91},{ 0, 44},{ 0,194},{ 6, 1}, + { 4, 1},{ 2, 1},{ 0, 11},{ 0,192},{ 0,166},{ 2, 1}, + { 0,167},{ 0,122},{ 10, 1},{ 4, 1},{ 2, 1},{ 0,195}, + { 0, 60},{ 4, 1},{ 2, 1},{ 0, 12},{ 0,153},{ 0,182}, + { 4, 1},{ 2, 1},{ 0,107},{ 0,196},{ 2, 1},{ 0, 76}, + { 0,168},{ 20, 1},{ 10, 1},{ 4, 1},{ 2, 1},{ 0,138}, + { 0,197},{ 4, 1},{ 2, 1},{ 0,208},{ 0, 92},{ 0,209}, + { 4, 1},{ 2, 1},{ 0,183},{ 0,123},{ 2, 1},{ 0, 29}, // 300 + + { 2, 1},{ 0, 13},{ 0, 45},{ 12, 1},{ 4, 1},{ 2, 1}, + { 0,210},{ 0,211},{ 4, 1},{ 2, 1},{ 0, 61},{ 0,198}, + { 2, 1},{ 0,108},{ 0,169},{ 6, 1},{ 4, 1},{ 2, 1}, + { 0,154},{ 0,184},{ 0,212},{ 4, 1},{ 2, 1},{ 0,139}, + { 0, 77},{ 2, 1},{ 0,199},{ 0,124},{ 68, 1},{ 34, 1}, + { 18, 1},{ 10, 1},{ 4, 1},{ 2, 1},{ 0,213},{ 0, 93}, + { 4, 1},{ 2, 1},{ 0,224},{ 0, 14},{ 0,225},{ 4, 1}, + { 2, 1},{ 0, 30},{ 0,226},{ 2, 1},{ 0,170},{ 0, 46}, + { 8, 1},{ 4, 1},{ 2, 1},{ 0,185},{ 0,155},{ 2, 1}, + { 0,227},{ 0,214},{ 4, 1},{ 2, 1},{ 0,109},{ 0, 62}, // 360 + + { 2, 1},{ 0,200},{ 0,140},{ 16, 1},{ 8, 1},{ 4, 1}, + { 2, 1},{ 0,228},{ 0, 78},{ 2, 1},{ 0,215},{ 0,125}, + { 4, 1},{ 2, 1},{ 0,229},{ 0,186},{ 2, 1},{ 0,171}, + { 0, 94},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,201},{ 0,156}, + { 2, 1},{ 0,241},{ 0, 31},{ 6, 1},{ 4, 1},{ 2, 1}, + { 0,240},{ 0,110},{ 0,242},{ 2, 1},{ 0, 47},{ 0,230}, + { 38, 1},{ 18, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,216}, + { 0,243},{ 2, 1},{ 0, 63},{ 0,244},{ 6, 1},{ 2, 1}, + { 0, 79},{ 2, 1},{ 0,141},{ 0,217},{ 2, 1},{ 0,187}, + { 0,202},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,172},{ 0,231}, // 420 + + { 2, 1},{ 0,126},{ 0,245},{ 8, 1},{ 4, 1},{ 2, 1}, + { 0,157},{ 0, 95},{ 2, 1},{ 0,232},{ 0,142},{ 2, 1}, + { 0,246},{ 0,203},{ 34, 1},{ 18, 1},{ 10, 1},{ 6, 1}, + { 4, 1},{ 2, 1},{ 0, 15},{ 0,174},{ 0,111},{ 2, 1}, + { 0,188},{ 0,218},{ 4, 1},{ 2, 1},{ 0,173},{ 0,247}, + { 2, 1},{ 0,127},{ 0,233},{ 8, 1},{ 4, 1},{ 2, 1}, + { 0,158},{ 0,204},{ 2, 1},{ 0,248},{ 0,143},{ 4, 1}, + { 2, 1},{ 0,219},{ 0,189},{ 2, 1},{ 0,234},{ 0,249}, + { 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,159},{ 0,220}, + { 2, 1},{ 0,205},{ 0,235},{ 4, 1},{ 2, 1},{ 0,190}, // 480 + + { 0,250},{ 2, 1},{ 0,175},{ 0,221},{ 14, 1},{ 6, 1}, + { 4, 1},{ 2, 1},{ 0,236},{ 0,206},{ 0,251},{ 4, 1}, + { 2, 1},{ 0,191},{ 0,237},{ 2, 1},{ 0,222},{ 0,252}, + { 6, 1},{ 4, 1},{ 2, 1},{ 0,207},{ 0,253},{ 0,238}, + { 4, 1},{ 2, 1},{ 0,223},{ 0,254},{ 2, 1},{ 0,239}, + { 0,255}}, + +htd16[511][2]={{ 2, 1},{ 0, 0},{ 6, 1},{ 2, 1},{ 0, 16},{ 2, 1}, + { 0, 1},{ 0, 17},{ 42, 1},{ 8, 1},{ 4, 1},{ 2, 1}, + { 0, 32},{ 0, 2},{ 2, 1},{ 0, 33},{ 0, 18},{ 10, 1}, + { 6, 1},{ 2, 1},{ 0, 34},{ 2, 1},{ 0, 48},{ 0, 3}, + { 2, 1},{ 0, 49},{ 0, 19},{ 10, 1},{ 4, 1},{ 2, 1}, + { 0, 50},{ 0, 35},{ 4, 1},{ 2, 1},{ 0, 64},{ 0, 4}, + { 0, 65},{ 6, 1},{ 2, 1},{ 0, 20},{ 2, 1},{ 0, 51}, + { 0, 66},{ 4, 1},{ 2, 1},{ 0, 36},{ 0, 80},{ 2, 1}, + { 0, 67},{ 0, 52},{138, 1},{ 40, 1},{ 16, 1},{ 6, 1}, + { 4, 1},{ 2, 1},{ 0, 5},{ 0, 21},{ 0, 81},{ 4, 1}, // 60 + + { 2, 1},{ 0, 82},{ 0, 37},{ 4, 1},{ 2, 1},{ 0, 68}, + { 0, 53},{ 0, 83},{ 10, 1},{ 6, 1},{ 4, 1},{ 2, 1}, + { 0, 96},{ 0, 6},{ 0, 97},{ 2, 1},{ 0, 22},{ 0, 98}, + { 8, 1},{ 4, 1},{ 2, 1},{ 0, 38},{ 0, 84},{ 2, 1}, + { 0, 69},{ 0, 99},{ 4, 1},{ 2, 1},{ 0, 54},{ 0,112}, + { 0,113},{ 40, 1},{ 18, 1},{ 8, 1},{ 2, 1},{ 0, 23}, + { 2, 1},{ 0, 7},{ 2, 1},{ 0, 85},{ 0,100},{ 4, 1}, + { 2, 1},{ 0,114},{ 0, 39},{ 4, 1},{ 2, 1},{ 0, 70}, + { 0,101},{ 0,115},{ 10, 1},{ 6, 1},{ 2, 1},{ 0, 55}, + { 2, 1},{ 0, 86},{ 0, 8},{ 2, 1},{ 0,128},{ 0,129}, // 120 + + { 6, 1},{ 2, 1},{ 0, 24},{ 2, 1},{ 0,116},{ 0, 71}, + { 2, 1},{ 0,130},{ 2, 1},{ 0, 40},{ 0,102},{ 24, 1}, + { 14, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,131},{ 0, 56}, + { 2, 1},{ 0,117},{ 0,132},{ 4, 1},{ 2, 1},{ 0, 72}, + { 0,144},{ 0,145},{ 6, 1},{ 2, 1},{ 0, 25},{ 2, 1}, + { 0, 9},{ 0,118},{ 2, 1},{ 0,146},{ 0, 41},{ 14, 1}, + { 8, 1},{ 4, 1},{ 2, 1},{ 0,133},{ 0, 88},{ 2, 1}, + { 0,147},{ 0, 57},{ 4, 1},{ 2, 1},{ 0,160},{ 0, 10}, + { 0, 26},{ 8, 1},{ 2, 1},{ 0,162},{ 2, 1},{ 0,103}, + { 2, 1},{ 0, 87},{ 0, 73},{ 6, 1},{ 2, 1},{ 0,148}, // 180 + + { 2, 1},{ 0,119},{ 0,134},{ 2, 1},{ 0,161},{ 2, 1}, + { 0,104},{ 0,149},{220, 1},{126, 1},{ 50, 1},{ 26, 1}, + { 12, 1},{ 6, 1},{ 2, 1},{ 0, 42},{ 2, 1},{ 0, 89}, + { 0, 58},{ 2, 1},{ 0,163},{ 2, 1},{ 0,135},{ 0,120}, + { 8, 1},{ 4, 1},{ 2, 1},{ 0,164},{ 0, 74},{ 2, 1}, + { 0,150},{ 0,105},{ 4, 1},{ 2, 1},{ 0,176},{ 0, 11}, + { 0,177},{ 10, 1},{ 4, 1},{ 2, 1},{ 0, 27},{ 0,178}, + { 2, 1},{ 0, 43},{ 2, 1},{ 0,165},{ 0, 90},{ 6, 1}, + { 2, 1},{ 0,179},{ 2, 1},{ 0,166},{ 0,106},{ 4, 1}, + { 2, 1},{ 0,180},{ 0, 75},{ 2, 1},{ 0, 12},{ 0,193}, // 240 + + { 30, 1},{ 14, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,181}, + { 0,194},{ 0, 44},{ 4, 1},{ 2, 1},{ 0,167},{ 0,195}, + { 2, 1},{ 0,107},{ 0,196},{ 8, 1},{ 2, 1},{ 0, 29}, + { 4, 1},{ 2, 1},{ 0,136},{ 0,151},{ 0, 59},{ 4, 1}, + { 2, 1},{ 0,209},{ 0,210},{ 2, 1},{ 0, 45},{ 0,211}, + { 18, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0, 30},{ 0, 46}, + { 0,226},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,121},{ 0,152}, + { 0,192},{ 2, 1},{ 0, 28},{ 2, 1},{ 0,137},{ 0, 91}, + { 14, 1},{ 6, 1},{ 2, 1},{ 0, 60},{ 2, 1},{ 0,122}, + { 0,182},{ 4, 1},{ 2, 1},{ 0, 76},{ 0,153},{ 2, 1}, // 300 + + { 0,168},{ 0,138},{ 6, 1},{ 2, 1},{ 0, 13},{ 2, 1}, + { 0,197},{ 0, 92},{ 4, 1},{ 2, 1},{ 0, 61},{ 0,198}, + { 2, 1},{ 0,108},{ 0,154},{ 88, 1},{ 86, 1},{ 36, 1}, + { 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,139},{ 0, 77}, + { 2, 1},{ 0,199},{ 0,124},{ 4, 1},{ 2, 1},{ 0,213}, + { 0, 93},{ 2, 1},{ 0,224},{ 0, 14},{ 8, 1},{ 2, 1}, + { 0,227},{ 4, 1},{ 2, 1},{ 0,208},{ 0,183},{ 0,123}, + { 6, 1},{ 4, 1},{ 2, 1},{ 0,169},{ 0,184},{ 0,212}, + { 2, 1},{ 0,225},{ 2, 1},{ 0,170},{ 0,185},{ 24, 1}, + { 10, 1},{ 6, 1},{ 4, 1},{ 2, 1},{ 0,155},{ 0,214}, // 360 + + { 0,109},{ 2, 1},{ 0, 62},{ 0,200},{ 6, 1},{ 4, 1}, + { 2, 1},{ 0,140},{ 0,228},{ 0, 78},{ 4, 1},{ 2, 1}, + { 0,215},{ 0,229},{ 2, 1},{ 0,186},{ 0,171},{ 12, 1}, + { 4, 1},{ 2, 1},{ 0,156},{ 0,230},{ 4, 1},{ 2, 1}, + { 0,110},{ 0,216},{ 2, 1},{ 0,141},{ 0,187},{ 8, 1}, + { 4, 1},{ 2, 1},{ 0,231},{ 0,157},{ 2, 1},{ 0,232}, + { 0,142},{ 4, 1},{ 2, 1},{ 0,203},{ 0,188},{ 0,158}, + { 0,241},{ 2, 1},{ 0, 31},{ 2, 1},{ 0, 15},{ 0, 47}, + { 66, 1},{ 56, 1},{ 2, 1},{ 0,242},{ 52, 1},{ 50, 1}, + { 20, 1},{ 8, 1},{ 2, 1},{ 0,189},{ 2, 1},{ 0, 94}, // 420 + + { 2, 1},{ 0,125},{ 0,201},{ 6, 1},{ 2, 1},{ 0,202}, + { 2, 1},{ 0,172},{ 0,126},{ 4, 1},{ 2, 1},{ 0,218}, + { 0,173},{ 0,204},{ 10, 1},{ 6, 1},{ 2, 1},{ 0,174}, + { 2, 1},{ 0,219},{ 0,220},{ 2, 1},{ 0,205},{ 0,190}, + { 6, 1},{ 4, 1},{ 2, 1},{ 0,235},{ 0,237},{ 0,238}, + { 6, 1},{ 4, 1},{ 2, 1},{ 0,217},{ 0,234},{ 0,233}, + { 2, 1},{ 0,222},{ 4, 1},{ 2, 1},{ 0,221},{ 0,236}, + { 0,206},{ 0, 63},{ 0,240},{ 4, 1},{ 2, 1},{ 0,243}, + { 0,244},{ 2, 1},{ 0, 79},{ 2, 1},{ 0,245},{ 0, 95}, + { 10, 1},{ 2, 1},{ 0,255},{ 4, 1},{ 2, 1},{ 0,246}, // 480 + + { 0,111},{ 2, 1},{ 0,247},{ 0,127},{ 12, 1},{ 6, 1}, + { 2, 1},{ 0,143},{ 2, 1},{ 0,248},{ 0,249},{ 4, 1}, + { 2, 1},{ 0,159},{ 0,250},{ 0,175},{ 8, 1},{ 4, 1}, + { 2, 1},{ 0,251},{ 0,191},{ 2, 1},{ 0,252},{ 0,207}, + { 4, 1},{ 2, 1},{ 0,253},{ 0,223},{ 2, 1},{ 0,254}, + { 0,239}}, + +htd24[512][2]={{ 60, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 16}, + { 2, 1},{ 0, 1},{ 0, 17},{ 14, 1},{ 6, 1},{ 4, 1}, + { 2, 1},{ 0, 32},{ 0, 2},{ 0, 33},{ 2, 1},{ 0, 18}, + { 2, 1},{ 0, 34},{ 2, 1},{ 0, 48},{ 0, 3},{ 14, 1}, + { 4, 1},{ 2, 1},{ 0, 49},{ 0, 19},{ 4, 1},{ 2, 1}, + { 0, 50},{ 0, 35},{ 4, 1},{ 2, 1},{ 0, 64},{ 0, 4}, + { 0, 65},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 20},{ 0, 51}, + { 2, 1},{ 0, 66},{ 0, 36},{ 6, 1},{ 4, 1},{ 2, 1}, + { 0, 67},{ 0, 52},{ 0, 81},{ 6, 1},{ 4, 1},{ 2, 1}, + { 0, 80},{ 0, 5},{ 0, 21},{ 2, 1},{ 0, 82},{ 0, 37}, // 60 + + {250+85, 1},{ 98, 1},{ 34, 1},{ 18, 1},{ 10, 1},{ 4, 1}, + { 2, 1},{ 0, 68},{ 0, 83},{ 2, 1},{ 0, 53},{ 2, 1}, + { 0, 96},{ 0, 6},{ 4, 1},{ 2, 1},{ 0, 97},{ 0, 22}, + { 2, 1},{ 0, 98},{ 0, 38},{ 8, 1},{ 4, 1},{ 2, 1}, + { 0, 84},{ 0, 69},{ 2, 1},{ 0, 99},{ 0, 54},{ 4, 1}, + { 2, 1},{ 0,113},{ 0, 85},{ 2, 1},{ 0,100},{ 0, 70}, + { 32, 1},{ 14, 1},{ 6, 1},{ 2, 1},{ 0,114},{ 2, 1}, + { 0, 39},{ 0, 55},{ 2, 1},{ 0,115},{ 4, 1},{ 2, 1}, + { 0,112},{ 0, 7},{ 0, 23},{ 10, 1},{ 4, 1},{ 2, 1}, + { 0,101},{ 0, 86},{ 4, 1},{ 2, 1},{ 0,128},{ 0, 8}, // 120 + + { 0,129},{ 4, 1},{ 2, 1},{ 0,116},{ 0, 71},{ 2, 1}, + { 0, 24},{ 0,130},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1}, + { 0, 40},{ 0,102},{ 2, 1},{ 0,131},{ 0, 56},{ 4, 1}, + { 2, 1},{ 0,117},{ 0, 87},{ 2, 1},{ 0,132},{ 0, 72}, + { 8, 1},{ 4, 1},{ 2, 1},{ 0,145},{ 0, 25},{ 2, 1}, + { 0,146},{ 0,118},{ 4, 1},{ 2, 1},{ 0,103},{ 0, 41}, + { 2, 1},{ 0,133},{ 0, 88},{ 92, 1},{ 34, 1},{ 16, 1}, + { 8, 1},{ 4, 1},{ 2, 1},{ 0,147},{ 0, 57},{ 2, 1}, + { 0,148},{ 0, 73},{ 4, 1},{ 2, 1},{ 0,119},{ 0,134}, + { 2, 1},{ 0,104},{ 0,161},{ 8, 1},{ 4, 1},{ 2, 1}, // 180 + + { 0,162},{ 0, 42},{ 2, 1},{ 0,149},{ 0, 89},{ 4, 1}, + { 2, 1},{ 0,163},{ 0, 58},{ 2, 1},{ 0,135},{ 2, 1}, + { 0,120},{ 0, 74},{ 22, 1},{ 12, 1},{ 4, 1},{ 2, 1}, + { 0,164},{ 0,150},{ 4, 1},{ 2, 1},{ 0,105},{ 0,177}, + { 2, 1},{ 0, 27},{ 0,165},{ 6, 1},{ 2, 1},{ 0,178}, + { 2, 1},{ 0, 90},{ 0, 43},{ 2, 1},{ 0,136},{ 0,179}, + { 16, 1},{ 10, 1},{ 6, 1},{ 2, 1},{ 0,144},{ 2, 1}, + { 0, 9},{ 0,160},{ 2, 1},{ 0,151},{ 0,121},{ 4, 1}, + { 2, 1},{ 0,166},{ 0,106},{ 0,180},{ 12, 1},{ 6, 1}, + { 2, 1},{ 0, 26},{ 2, 1},{ 0, 10},{ 0,176},{ 2, 1}, // 240 + + { 0, 59},{ 2, 1},{ 0, 11},{ 0,192},{ 4, 1},{ 2, 1}, + { 0, 75},{ 0,193},{ 2, 1},{ 0,152},{ 0,137},{ 67, 1}, + { 34, 1},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 28}, + { 0,181},{ 2, 1},{ 0, 91},{ 0,194},{ 4, 1},{ 2, 1}, + { 0, 44},{ 0,167},{ 2, 1},{ 0,122},{ 0,195},{ 10, 1}, + { 6, 1},{ 2, 1},{ 0, 60},{ 2, 1},{ 0, 12},{ 0,208}, + { 2, 1},{ 0,182},{ 0,107},{ 4, 1},{ 2, 1},{ 0,196}, + { 0, 76},{ 2, 1},{ 0,153},{ 0,168},{ 16, 1},{ 8, 1}, + { 4, 1},{ 2, 1},{ 0,138},{ 0,197},{ 2, 1},{ 0, 92}, + { 0,209},{ 4, 1},{ 2, 1},{ 0,183},{ 0,123},{ 2, 1}, // 300 + + { 0, 29},{ 0,210},{ 9, 1},{ 4, 1},{ 2, 1},{ 0, 45}, + { 0,211},{ 2, 1},{ 0, 61},{ 0,198},{ 85,250},{ 4, 1}, // 306 - + { 2, 1},{ 0,108},{ 0,169},{ 2, 1},{ 0,154},{ 0,212}, + { 32, 1},{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,184}, + { 0,139},{ 2, 1},{ 0, 77},{ 0,199},{ 4, 1},{ 2, 1}, + { 0,124},{ 0,213},{ 2, 1},{ 0, 93},{ 0,225},{ 8, 1}, + { 4, 1},{ 2, 1},{ 0, 30},{ 0,226},{ 2, 1},{ 0,170}, + { 0,185},{ 4, 1},{ 2, 1},{ 0,155},{ 0,227},{ 2, 1}, + { 0,214},{ 0,109},{ 20, 1},{ 10, 1},{ 6, 1},{ 2, 1}, + { 0, 62},{ 2, 1},{ 0, 46},{ 0, 78},{ 2, 1},{ 0,200}, // 360 + + { 0,140},{ 4, 1},{ 2, 1},{ 0,228},{ 0,215},{ 4, 1}, + { 2, 1},{ 0,125},{ 0,171},{ 0,229},{ 10, 1},{ 4, 1}, + { 2, 1},{ 0,186},{ 0, 94},{ 2, 1},{ 0,201},{ 2, 1}, + { 0,156},{ 0,110},{ 8, 1},{ 2, 1},{ 0,230},{ 2, 1}, + { 0, 13},{ 2, 1},{ 0,224},{ 0, 14},{ 4, 1},{ 2, 1}, + { 0,216},{ 0,141},{ 2, 1},{ 0,187},{ 0,202},{ 74, 1}, + { 2, 1},{ 0,255},{ 64, 1},{ 58, 1},{ 32, 1},{ 16, 1}, + { 8, 1},{ 4, 1},{ 2, 1},{ 0,172},{ 0,231},{ 2, 1}, + { 0,126},{ 0,217},{ 4, 1},{ 2, 1},{ 0,157},{ 0,232}, + { 2, 1},{ 0,142},{ 0,203},{ 8, 1},{ 4, 1},{ 2, 1}, // 420 + + { 0,188},{ 0,218},{ 2, 1},{ 0,173},{ 0,233},{ 4, 1}, + { 2, 1},{ 0,158},{ 0,204},{ 2, 1},{ 0,219},{ 0,189}, + { 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,234},{ 0,174}, + { 2, 1},{ 0,220},{ 0,205},{ 4, 1},{ 2, 1},{ 0,235}, + { 0,190},{ 2, 1},{ 0,221},{ 0,236},{ 8, 1},{ 4, 1}, + { 2, 1},{ 0,206},{ 0,237},{ 2, 1},{ 0,222},{ 0,238}, + { 0, 15},{ 4, 1},{ 2, 1},{ 0,240},{ 0, 31},{ 0,241}, + { 4, 1},{ 2, 1},{ 0,242},{ 0, 47},{ 2, 1},{ 0,243}, + { 0, 63},{ 18, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0,244}, + { 0, 79},{ 2, 1},{ 0,245},{ 0, 95},{ 4, 1},{ 2, 1}, // 480 + + { 0,246},{ 0,111},{ 2, 1},{ 0,247},{ 2, 1},{ 0,127}, + { 0,143},{ 10, 1},{ 4, 1},{ 2, 1},{ 0,248},{ 0,249}, + { 4, 1},{ 2, 1},{ 0,159},{ 0,175},{ 0,250},{ 8, 1}, + { 4, 1},{ 2, 1},{ 0,251},{ 0,191},{ 2, 1},{ 0,252}, + { 0,207},{ 4, 1},{ 2, 1},{ 0,253},{ 0,223},{ 2, 1}, + { 0,254},{ 0,239}}, + +htd32[ 31][2]={{ 2, 1},{ 0, 0},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 8}, + { 0, 4},{ 2, 1},{ 0, 1},{ 0, 2},{ 8, 1},{ 4, 1}, + { 2, 1},{ 0, 12},{ 0, 10},{ 2, 1},{ 0, 3},{ 0, 6}, + { 6, 1},{ 2, 1},{ 0, 9},{ 2, 1},{ 0, 5},{ 0, 7}, + { 4, 1},{ 2, 1},{ 0, 14},{ 0, 13},{ 2, 1},{ 0, 15}, + { 0, 11}}, + +htd33[ 31][2]={{ 16, 1},{ 8, 1},{ 4, 1},{ 2, 1},{ 0, 0},{ 0, 1}, + { 2, 1},{ 0, 2},{ 0, 3},{ 4, 1},{ 2, 1},{ 0, 4}, + { 0, 5},{ 2, 1},{ 0, 6},{ 0, 7},{ 8, 1},{ 4, 1}, + { 2, 1},{ 0, 8},{ 0, 9},{ 2, 1},{ 0, 10},{ 0, 11}, + { 4, 1},{ 2, 1},{ 0, 12},{ 0, 13},{ 2, 1},{ 0, 14}, + { 0, 15}}; + +const ATTR_ALIGN(64) HUFFMANCODETABLE Mpegtoraw::ht[HTN]= +{ + { 0, 0-1, 0-1, 0, 0, htd33}, + { 1, 2-1, 2-1, 0, 7,htd01}, + { 2, 3-1, 3-1, 0, 17,htd02}, + { 3, 3-1, 3-1, 0, 17,htd03}, + { 4, 0-1, 0-1, 0, 0, htd33}, + { 5, 4-1, 4-1, 0, 31,htd05}, + { 6, 4-1, 4-1, 0, 31,htd06}, + { 7, 6-1, 6-1, 0, 71,htd07}, + { 8, 6-1, 6-1, 0, 71,htd08}, + { 9, 6-1, 6-1, 0, 71,htd09}, + {10, 8-1, 8-1, 0,127,htd10}, + {11, 8-1, 8-1, 0,127,htd11}, + {12, 8-1, 8-1, 0,127,htd12}, + {13,16-1,16-1, 0,511,htd13}, + {14, 0-1, 0-1, 0, 0, htd33}, + {15,16-1,16-1, 0,511,htd15}, + {16,16-1,16-1, 1,511,htd16}, + {17,16-1,16-1, 2,511,htd16}, + {18,16-1,16-1, 3,511,htd16}, + {19,16-1,16-1, 4,511,htd16}, + {20,16-1,16-1, 6,511,htd16}, + {21,16-1,16-1, 8,511,htd16}, + {22,16-1,16-1,10,511,htd16}, + {23,16-1,16-1,13,511,htd16}, + {24,16-1,16-1, 4,512,htd24}, + {25,16-1,16-1, 5,512,htd24}, + {26,16-1,16-1, 6,512,htd24}, + {27,16-1,16-1, 7,512,htd24}, + {28,16-1,16-1, 8,512,htd24}, + {29,16-1,16-1, 9,512,htd24}, + {30,16-1,16-1,11,512,htd24}, + {31,16-1,16-1,13,512,htd24}, + {32, 1-1,16-1, 0, 31,htd32}, + {33, 1-1,16-1, 0, 31,htd33} +}; diff --git a/mpeglib/lib/splay/mpeg2tables.h b/mpeglib/lib/splay/mpeg2tables.h new file mode 100644 index 00000000..1430a123 --- /dev/null +++ b/mpeglib/lib/splay/mpeg2tables.h @@ -0,0 +1,432 @@ + +#ifndef __MPEG2TABLES_H +#define __MPEG2TABLES_H + + +#define MAXTABLE 3 + + +// Tables for layer 2. + +// bitalloclengthtable :0,1 supported 2. 2 ot tested & disabled +// this table merges the subbands to the longer one. +// 8 < 12 , 27 < 30 but the "length" is the same + +static const int bitalloclengthtable[MAXTABLE][MAXSUBBAND]= +{ {4,4,3,3,3,3,3,3,3,3,3,3,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3, 3,3,3,3,3,3,3,2,2,2,2,2,2,2,0,0}, + {4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0} }; + + +/* +Orignal is: +{ {4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3, 3,3,3,3,3,3,3,2,2,2,2,0,0,0,0,0}, + {4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3, 3,3,3,3,3,3,3,2,2,2,2,2,2,2,0,0}, + {4,4,3,3,3,3,3,3,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {4,4,3,3,3,3,3,3,3,3,3,3,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {4,4,4,4,3,3,3,3,3,3,3,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0} }; + +*/ + + + + + +static const REAL group5bits[27*3]= +{ + -2.0/3.0, -2.0/3.0, -2.0/3.0, + 0.0, -2.0/3.0, -2.0/3.0, + 2.0/3.0, -2.0/3.0, -2.0/3.0, + -2.0/3.0, 0.0, -2.0/3.0, + 0.0, 0.0, -2.0/3.0, + 2.0/3.0, 0.0, -2.0/3.0, + -2.0/3.0, 2.0/3.0, -2.0/3.0, + 0.0, 2.0/3.0, -2.0/3.0, + 2.0/3.0, 2.0/3.0, -2.0/3.0, + -2.0/3.0, -2.0/3.0, 0.0, + 0.0, -2.0/3.0, 0.0, + 2.0/3.0, -2.0/3.0, 0.0, + -2.0/3.0, 0.0, 0.0, + 0.0, 0.0, 0.0, + 2.0/3.0, 0.0, 0.0, + -2.0/3.0, 2.0/3.0, 0.0, + 0.0, 2.0/3.0, 0.0, + 2.0/3.0, 2.0/3.0, 0.0, + -2.0/3.0, -2.0/3.0, 2.0/3.0, + 0.0, -2.0/3.0, 2.0/3.0, + 2.0/3.0, -2.0/3.0, 2.0/3.0, + -2.0/3.0, 0.0, 2.0/3.0, + 0.0, 0.0, 2.0/3.0, + 2.0/3.0, 0.0, 2.0/3.0, + -2.0/3.0, 2.0/3.0, 2.0/3.0, + 0.0, 2.0/3.0, 2.0/3.0, + 2.0/3.0, 2.0/3.0, 2.0/3.0 +}; + +static const REAL group7bits[125*3]= +{ + -0.8,-0.8,-0.8, -0.4,-0.8,-0.8, 0.0,-0.8,-0.8, 0.4,-0.8,-0.8, 0.8,-0.8,-0.8, + -0.8,-0.4,-0.8, -0.4,-0.4,-0.8, 0.0,-0.4,-0.8, 0.4,-0.4,-0.8, 0.8,-0.4,-0.8, + -0.8, 0.0,-0.8, -0.4, 0.0,-0.8, 0.0, 0.0,-0.8, 0.4, 0.0,-0.8, 0.8, 0.0,-0.8, + -0.8, 0.4,-0.8, -0.4, 0.4,-0.8, 0.0, 0.4,-0.8, 0.4, 0.4,-0.8, 0.8, 0.4,-0.8, + -0.8, 0.8,-0.8, -0.4, 0.8,-0.8, 0.0, 0.8,-0.8, 0.4, 0.8,-0.8, 0.8, 0.8,-0.8, + -0.8,-0.8,-0.4, -0.4,-0.8,-0.4, 0.0,-0.8,-0.4, 0.4,-0.8,-0.4, 0.8,-0.8,-0.4, + -0.8,-0.4,-0.4, -0.4,-0.4,-0.4, 0.0,-0.4,-0.4, 0.4,-0.4,-0.4, 0.8,-0.4,-0.4, + -0.8, 0.0,-0.4, -0.4, 0.0,-0.4, 0.0, 0.0,-0.4, 0.4, 0.0,-0.4, 0.8, 0.0,-0.4, + -0.8, 0.4,-0.4, -0.4, 0.4,-0.4, 0.0, 0.4,-0.4, 0.4, 0.4,-0.4, 0.8, 0.4,-0.4, + -0.8, 0.8,-0.4, -0.4, 0.8,-0.4, 0.0, 0.8,-0.4, 0.4, 0.8,-0.4, 0.8, 0.8,-0.4, + -0.8,-0.8, 0.0, -0.4,-0.8, 0.0, 0.0,-0.8, 0.0, 0.4,-0.8, 0.0, 0.8,-0.8, 0.0, + -0.8,-0.4, 0.0, -0.4,-0.4, 0.0, 0.0,-0.4, 0.0, 0.4,-0.4, 0.0, 0.8,-0.4, 0.0, + -0.8, 0.0, 0.0, -0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4, 0.0, 0.0, 0.8, 0.0, 0.0, + -0.8, 0.4, 0.0, -0.4, 0.4, 0.0, 0.0, 0.4, 0.0, 0.4, 0.4, 0.0, 0.8, 0.4, 0.0, + -0.8, 0.8, 0.0, -0.4, 0.8, 0.0, 0.0, 0.8, 0.0, 0.4, 0.8, 0.0, 0.8, 0.8, 0.0, + -0.8,-0.8, 0.4, -0.4,-0.8, 0.4, 0.0,-0.8, 0.4, 0.4,-0.8, 0.4, 0.8,-0.8, 0.4, + -0.8,-0.4, 0.4, -0.4,-0.4, 0.4, 0.0,-0.4, 0.4, 0.4,-0.4, 0.4, 0.8,-0.4, 0.4, + -0.8, 0.0, 0.4, -0.4, 0.0, 0.4, 0.0, 0.0, 0.4, 0.4, 0.0, 0.4, 0.8, 0.0, 0.4, + -0.8, 0.4, 0.4, -0.4, 0.4, 0.4, 0.0, 0.4, 0.4, 0.4, 0.4, 0.4, 0.8, 0.4, 0.4, + -0.8, 0.8, 0.4, -0.4, 0.8, 0.4, 0.0, 0.8, 0.4, 0.4, 0.8, 0.4, 0.8, 0.8, 0.4, + -0.8,-0.8, 0.8, -0.4,-0.8, 0.8, 0.0,-0.8, 0.8, 0.4,-0.8, 0.8, 0.8,-0.8, 0.8, + -0.8,-0.4, 0.8, -0.4,-0.4, 0.8, 0.0,-0.4, 0.8, 0.4,-0.4, 0.8, 0.8,-0.4, 0.8, + -0.8, 0.0, 0.8, -0.4, 0.0, 0.8, 0.0, 0.0, 0.8, 0.4, 0.0, 0.8, 0.8, 0.0, 0.8, + -0.8, 0.4, 0.8, -0.4, 0.4, 0.8, 0.0, 0.4, 0.8, 0.4, 0.4, 0.8, 0.8, 0.4, 0.8, + -0.8, 0.8, 0.8, -0.4, 0.8, 0.8, 0.0, 0.8, 0.8, 0.4, 0.8, 0.8, 0.8, 0.8, 0.8 +}; + +static const REAL group10bits[729*3]= +{ + -8.0/9.0,-8.0/9.0,-8.0/9.0, -6.0/9.0,-8.0/9.0,-8.0/9.0, -4.0/9.0,-8.0/9.0,-8.0/9.0, + -2.0/9.0,-8.0/9.0,-8.0/9.0, 0.0,-8.0/9.0,-8.0/9.0, 2.0/9.0,-8.0/9.0,-8.0/9.0, + 4.0/9.0,-8.0/9.0,-8.0/9.0, 6.0/9.0,-8.0/9.0,-8.0/9.0, 8.0/9.0,-8.0/9.0,-8.0/9.0, + -8.0/9.0,-6.0/9.0,-8.0/9.0, -6.0/9.0,-6.0/9.0,-8.0/9.0, -4.0/9.0,-6.0/9.0,-8.0/9.0, + -2.0/9.0,-6.0/9.0,-8.0/9.0, 0.0,-6.0/9.0,-8.0/9.0, 2.0/9.0,-6.0/9.0,-8.0/9.0, + 4.0/9.0,-6.0/9.0,-8.0/9.0, 6.0/9.0,-6.0/9.0,-8.0/9.0, 8.0/9.0,-6.0/9.0,-8.0/9.0, + -8.0/9.0,-4.0/9.0,-8.0/9.0, -6.0/9.0,-4.0/9.0,-8.0/9.0, -4.0/9.0,-4.0/9.0,-8.0/9.0, + -2.0/9.0,-4.0/9.0,-8.0/9.0, 0.0,-4.0/9.0,-8.0/9.0, 2.0/9.0,-4.0/9.0,-8.0/9.0, + 4.0/9.0,-4.0/9.0,-8.0/9.0, 6.0/9.0,-4.0/9.0,-8.0/9.0, 8.0/9.0,-4.0/9.0,-8.0/9.0, + -8.0/9.0,-2.0/9.0,-8.0/9.0, -6.0/9.0,-2.0/9.0,-8.0/9.0, -4.0/9.0,-2.0/9.0,-8.0/9.0, + -2.0/9.0,-2.0/9.0,-8.0/9.0, 0.0,-2.0/9.0,-8.0/9.0, 2.0/9.0,-2.0/9.0,-8.0/9.0, + 4.0/9.0,-2.0/9.0,-8.0/9.0, 6.0/9.0,-2.0/9.0,-8.0/9.0, 8.0/9.0,-2.0/9.0,-8.0/9.0, + -8.0/9.0, 0.0,-8.0/9.0, -6.0/9.0, 0.0,-8.0/9.0, -4.0/9.0, 0.0,-8.0/9.0, + -2.0/9.0, 0.0,-8.0/9.0, 0.0, 0.0,-8.0/9.0, 2.0/9.0, 0.0,-8.0/9.0, + 4.0/9.0, 0.0,-8.0/9.0, 6.0/9.0, 0.0,-8.0/9.0, 8.0/9.0, 0.0,-8.0/9.0, + -8.0/9.0, 2.0/9.0,-8.0/9.0, -6.0/9.0, 2.0/9.0,-8.0/9.0, -4.0/9.0, 2.0/9.0,-8.0/9.0, + -2.0/9.0, 2.0/9.0,-8.0/9.0, 0.0, 2.0/9.0,-8.0/9.0, 2.0/9.0, 2.0/9.0,-8.0/9.0, + 4.0/9.0, 2.0/9.0,-8.0/9.0, 6.0/9.0, 2.0/9.0,-8.0/9.0, 8.0/9.0, 2.0/9.0,-8.0/9.0, + -8.0/9.0, 4.0/9.0,-8.0/9.0, -6.0/9.0, 4.0/9.0,-8.0/9.0, -4.0/9.0, 4.0/9.0,-8.0/9.0, + -2.0/9.0, 4.0/9.0,-8.0/9.0, 0.0, 4.0/9.0,-8.0/9.0, 2.0/9.0, 4.0/9.0,-8.0/9.0, + 4.0/9.0, 4.0/9.0,-8.0/9.0, 6.0/9.0, 4.0/9.0,-8.0/9.0, 8.0/9.0, 4.0/9.0,-8.0/9.0, + -8.0/9.0, 6.0/9.0,-8.0/9.0, -6.0/9.0, 6.0/9.0,-8.0/9.0, -4.0/9.0, 6.0/9.0,-8.0/9.0, + -2.0/9.0, 6.0/9.0,-8.0/9.0, 0.0, 6.0/9.0,-8.0/9.0, 2.0/9.0, 6.0/9.0,-8.0/9.0, + 4.0/9.0, 6.0/9.0,-8.0/9.0, 6.0/9.0, 6.0/9.0,-8.0/9.0, 8.0/9.0, 6.0/9.0,-8.0/9.0, + -8.0/9.0, 8.0/9.0,-8.0/9.0, -6.0/9.0, 8.0/9.0,-8.0/9.0, -4.0/9.0, 8.0/9.0,-8.0/9.0, + -2.0/9.0, 8.0/9.0,-8.0/9.0, 0.0, 8.0/9.0,-8.0/9.0, 2.0/9.0, 8.0/9.0,-8.0/9.0, + 4.0/9.0, 8.0/9.0,-8.0/9.0, 6.0/9.0, 8.0/9.0,-8.0/9.0, 8.0/9.0, 8.0/9.0,-8.0/9.0, + -8.0/9.0,-8.0/9.0,-6.0/9.0, -6.0/9.0,-8.0/9.0,-6.0/9.0, -4.0/9.0,-8.0/9.0,-6.0/9.0, + -2.0/9.0,-8.0/9.0,-6.0/9.0, 0.0,-8.0/9.0,-6.0/9.0, 2.0/9.0,-8.0/9.0,-6.0/9.0, + 4.0/9.0,-8.0/9.0,-6.0/9.0, 6.0/9.0,-8.0/9.0,-6.0/9.0, 8.0/9.0,-8.0/9.0,-6.0/9.0, + -8.0/9.0,-6.0/9.0,-6.0/9.0, -6.0/9.0,-6.0/9.0,-6.0/9.0, -4.0/9.0,-6.0/9.0,-6.0/9.0, + -2.0/9.0,-6.0/9.0,-6.0/9.0, 0.0,-6.0/9.0,-6.0/9.0, 2.0/9.0,-6.0/9.0,-6.0/9.0, + 4.0/9.0,-6.0/9.0,-6.0/9.0, 6.0/9.0,-6.0/9.0,-6.0/9.0, 8.0/9.0,-6.0/9.0,-6.0/9.0, + -8.0/9.0,-4.0/9.0,-6.0/9.0, -6.0/9.0,-4.0/9.0,-6.0/9.0, -4.0/9.0,-4.0/9.0,-6.0/9.0, + -2.0/9.0,-4.0/9.0,-6.0/9.0, 0.0,-4.0/9.0,-6.0/9.0, 2.0/9.0,-4.0/9.0,-6.0/9.0, + 4.0/9.0,-4.0/9.0,-6.0/9.0, 6.0/9.0,-4.0/9.0,-6.0/9.0, 8.0/9.0,-4.0/9.0,-6.0/9.0, + -8.0/9.0,-2.0/9.0,-6.0/9.0, -6.0/9.0,-2.0/9.0,-6.0/9.0, -4.0/9.0,-2.0/9.0,-6.0/9.0, + -2.0/9.0,-2.0/9.0,-6.0/9.0, 0.0,-2.0/9.0,-6.0/9.0, 2.0/9.0,-2.0/9.0,-6.0/9.0, + 4.0/9.0,-2.0/9.0,-6.0/9.0, 6.0/9.0,-2.0/9.0,-6.0/9.0, 8.0/9.0,-2.0/9.0,-6.0/9.0, + -8.0/9.0, 0.0,-6.0/9.0, -6.0/9.0, 0.0,-6.0/9.0, -4.0/9.0, 0.0,-6.0/9.0, + -2.0/9.0, 0.0,-6.0/9.0, 0.0, 0.0,-6.0/9.0, 2.0/9.0, 0.0,-6.0/9.0, + 4.0/9.0, 0.0,-6.0/9.0, 6.0/9.0, 0.0,-6.0/9.0, 8.0/9.0, 0.0,-6.0/9.0, + -8.0/9.0, 2.0/9.0,-6.0/9.0, -6.0/9.0, 2.0/9.0,-6.0/9.0, -4.0/9.0, 2.0/9.0,-6.0/9.0, + -2.0/9.0, 2.0/9.0,-6.0/9.0, 0.0, 2.0/9.0,-6.0/9.0, 2.0/9.0, 2.0/9.0,-6.0/9.0, + 4.0/9.0, 2.0/9.0,-6.0/9.0, 6.0/9.0, 2.0/9.0,-6.0/9.0, 8.0/9.0, 2.0/9.0,-6.0/9.0, + -8.0/9.0, 4.0/9.0,-6.0/9.0, -6.0/9.0, 4.0/9.0,-6.0/9.0, -4.0/9.0, 4.0/9.0,-6.0/9.0, + -2.0/9.0, 4.0/9.0,-6.0/9.0, 0.0, 4.0/9.0,-6.0/9.0, 2.0/9.0, 4.0/9.0,-6.0/9.0, + 4.0/9.0, 4.0/9.0,-6.0/9.0, 6.0/9.0, 4.0/9.0,-6.0/9.0, 8.0/9.0, 4.0/9.0,-6.0/9.0, + -8.0/9.0, 6.0/9.0,-6.0/9.0, -6.0/9.0, 6.0/9.0,-6.0/9.0, -4.0/9.0, 6.0/9.0,-6.0/9.0, + -2.0/9.0, 6.0/9.0,-6.0/9.0, 0.0, 6.0/9.0,-6.0/9.0, 2.0/9.0, 6.0/9.0,-6.0/9.0, + 4.0/9.0, 6.0/9.0,-6.0/9.0, 6.0/9.0, 6.0/9.0,-6.0/9.0, 8.0/9.0, 6.0/9.0,-6.0/9.0, + -8.0/9.0, 8.0/9.0,-6.0/9.0, -6.0/9.0, 8.0/9.0,-6.0/9.0, -4.0/9.0, 8.0/9.0,-6.0/9.0, + -2.0/9.0, 8.0/9.0,-6.0/9.0, 0.0, 8.0/9.0,-6.0/9.0, 2.0/9.0, 8.0/9.0,-6.0/9.0, + 4.0/9.0, 8.0/9.0,-6.0/9.0, 6.0/9.0, 8.0/9.0,-6.0/9.0, 8.0/9.0, 8.0/9.0,-6.0/9.0, + -8.0/9.0,-8.0/9.0,-4.0/9.0, -6.0/9.0,-8.0/9.0,-4.0/9.0, -4.0/9.0,-8.0/9.0,-4.0/9.0, + -2.0/9.0,-8.0/9.0,-4.0/9.0, 0.0,-8.0/9.0,-4.0/9.0, 2.0/9.0,-8.0/9.0,-4.0/9.0, + 4.0/9.0,-8.0/9.0,-4.0/9.0, 6.0/9.0,-8.0/9.0,-4.0/9.0, 8.0/9.0,-8.0/9.0,-4.0/9.0, + -8.0/9.0,-6.0/9.0,-4.0/9.0, -6.0/9.0,-6.0/9.0,-4.0/9.0, -4.0/9.0,-6.0/9.0,-4.0/9.0, + -2.0/9.0,-6.0/9.0,-4.0/9.0, 0.0,-6.0/9.0,-4.0/9.0, 2.0/9.0,-6.0/9.0,-4.0/9.0, + 4.0/9.0,-6.0/9.0,-4.0/9.0, 6.0/9.0,-6.0/9.0,-4.0/9.0, 8.0/9.0,-6.0/9.0,-4.0/9.0, + -8.0/9.0,-4.0/9.0,-4.0/9.0, -6.0/9.0,-4.0/9.0,-4.0/9.0, -4.0/9.0,-4.0/9.0,-4.0/9.0, + -2.0/9.0,-4.0/9.0,-4.0/9.0, 0.0,-4.0/9.0,-4.0/9.0, 2.0/9.0,-4.0/9.0,-4.0/9.0, + 4.0/9.0,-4.0/9.0,-4.0/9.0, 6.0/9.0,-4.0/9.0,-4.0/9.0, 8.0/9.0,-4.0/9.0,-4.0/9.0, + -8.0/9.0,-2.0/9.0,-4.0/9.0, -6.0/9.0,-2.0/9.0,-4.0/9.0, -4.0/9.0,-2.0/9.0,-4.0/9.0, + -2.0/9.0,-2.0/9.0,-4.0/9.0, 0.0,-2.0/9.0,-4.0/9.0, 2.0/9.0,-2.0/9.0,-4.0/9.0, + 4.0/9.0,-2.0/9.0,-4.0/9.0, 6.0/9.0,-2.0/9.0,-4.0/9.0, 8.0/9.0,-2.0/9.0,-4.0/9.0, + -8.0/9.0, 0.0,-4.0/9.0, -6.0/9.0, 0.0,-4.0/9.0, -4.0/9.0, 0.0,-4.0/9.0, + -2.0/9.0, 0.0,-4.0/9.0, 0.0, 0.0,-4.0/9.0, 2.0/9.0, 0.0,-4.0/9.0, + 4.0/9.0, 0.0,-4.0/9.0, 6.0/9.0, 0.0,-4.0/9.0, 8.0/9.0, 0.0,-4.0/9.0, + -8.0/9.0, 2.0/9.0,-4.0/9.0, -6.0/9.0, 2.0/9.0,-4.0/9.0, -4.0/9.0, 2.0/9.0,-4.0/9.0, + -2.0/9.0, 2.0/9.0,-4.0/9.0, 0.0, 2.0/9.0,-4.0/9.0, 2.0/9.0, 2.0/9.0,-4.0/9.0, + 4.0/9.0, 2.0/9.0,-4.0/9.0, 6.0/9.0, 2.0/9.0,-4.0/9.0, 8.0/9.0, 2.0/9.0,-4.0/9.0, + -8.0/9.0, 4.0/9.0,-4.0/9.0, -6.0/9.0, 4.0/9.0,-4.0/9.0, -4.0/9.0, 4.0/9.0,-4.0/9.0, + -2.0/9.0, 4.0/9.0,-4.0/9.0, 0.0, 4.0/9.0,-4.0/9.0, 2.0/9.0, 4.0/9.0,-4.0/9.0, + 4.0/9.0, 4.0/9.0,-4.0/9.0, 6.0/9.0, 4.0/9.0,-4.0/9.0, 8.0/9.0, 4.0/9.0,-4.0/9.0, + -8.0/9.0, 6.0/9.0,-4.0/9.0, -6.0/9.0, 6.0/9.0,-4.0/9.0, -4.0/9.0, 6.0/9.0,-4.0/9.0, + -2.0/9.0, 6.0/9.0,-4.0/9.0, 0.0, 6.0/9.0,-4.0/9.0, 2.0/9.0, 6.0/9.0,-4.0/9.0, + 4.0/9.0, 6.0/9.0,-4.0/9.0, 6.0/9.0, 6.0/9.0,-4.0/9.0, 8.0/9.0, 6.0/9.0,-4.0/9.0, + -8.0/9.0, 8.0/9.0,-4.0/9.0, -6.0/9.0, 8.0/9.0,-4.0/9.0, -4.0/9.0, 8.0/9.0,-4.0/9.0, + -2.0/9.0, 8.0/9.0,-4.0/9.0, 0.0, 8.0/9.0,-4.0/9.0, 2.0/9.0, 8.0/9.0,-4.0/9.0, + 4.0/9.0, 8.0/9.0,-4.0/9.0, 6.0/9.0, 8.0/9.0,-4.0/9.0, 8.0/9.0, 8.0/9.0,-4.0/9.0, + -8.0/9.0,-8.0/9.0,-2.0/9.0, -6.0/9.0,-8.0/9.0,-2.0/9.0, -4.0/9.0,-8.0/9.0,-2.0/9.0, + -2.0/9.0,-8.0/9.0,-2.0/9.0, 0.0,-8.0/9.0,-2.0/9.0, 2.0/9.0,-8.0/9.0,-2.0/9.0, + 4.0/9.0,-8.0/9.0,-2.0/9.0, 6.0/9.0,-8.0/9.0,-2.0/9.0, 8.0/9.0,-8.0/9.0,-2.0/9.0, + -8.0/9.0,-6.0/9.0,-2.0/9.0, -6.0/9.0,-6.0/9.0,-2.0/9.0, -4.0/9.0,-6.0/9.0,-2.0/9.0, + -2.0/9.0,-6.0/9.0,-2.0/9.0, 0.0,-6.0/9.0,-2.0/9.0, 2.0/9.0,-6.0/9.0,-2.0/9.0, + 4.0/9.0,-6.0/9.0,-2.0/9.0, 6.0/9.0,-6.0/9.0,-2.0/9.0, 8.0/9.0,-6.0/9.0,-2.0/9.0, + -8.0/9.0,-4.0/9.0,-2.0/9.0, -6.0/9.0,-4.0/9.0,-2.0/9.0, -4.0/9.0,-4.0/9.0,-2.0/9.0, + -2.0/9.0,-4.0/9.0,-2.0/9.0, 0.0,-4.0/9.0,-2.0/9.0, 2.0/9.0,-4.0/9.0,-2.0/9.0, + 4.0/9.0,-4.0/9.0,-2.0/9.0, 6.0/9.0,-4.0/9.0,-2.0/9.0, 8.0/9.0,-4.0/9.0,-2.0/9.0, + -8.0/9.0,-2.0/9.0,-2.0/9.0, -6.0/9.0,-2.0/9.0,-2.0/9.0, -4.0/9.0,-2.0/9.0,-2.0/9.0, + -2.0/9.0,-2.0/9.0,-2.0/9.0, 0.0,-2.0/9.0,-2.0/9.0, 2.0/9.0,-2.0/9.0,-2.0/9.0, + 4.0/9.0,-2.0/9.0,-2.0/9.0, 6.0/9.0,-2.0/9.0,-2.0/9.0, 8.0/9.0,-2.0/9.0,-2.0/9.0, + -8.0/9.0, 0.0,-2.0/9.0, -6.0/9.0, 0.0,-2.0/9.0, -4.0/9.0, 0.0,-2.0/9.0, + -2.0/9.0, 0.0,-2.0/9.0, 0.0, 0.0,-2.0/9.0, 2.0/9.0, 0.0,-2.0/9.0, + 4.0/9.0, 0.0,-2.0/9.0, 6.0/9.0, 0.0,-2.0/9.0, 8.0/9.0, 0.0,-2.0/9.0, + -8.0/9.0, 2.0/9.0,-2.0/9.0, -6.0/9.0, 2.0/9.0,-2.0/9.0, -4.0/9.0, 2.0/9.0,-2.0/9.0, + -2.0/9.0, 2.0/9.0,-2.0/9.0, 0.0, 2.0/9.0,-2.0/9.0, 2.0/9.0, 2.0/9.0,-2.0/9.0, + 4.0/9.0, 2.0/9.0,-2.0/9.0, 6.0/9.0, 2.0/9.0,-2.0/9.0, 8.0/9.0, 2.0/9.0,-2.0/9.0, + -8.0/9.0, 4.0/9.0,-2.0/9.0, -6.0/9.0, 4.0/9.0,-2.0/9.0, -4.0/9.0, 4.0/9.0,-2.0/9.0, + -2.0/9.0, 4.0/9.0,-2.0/9.0, 0.0, 4.0/9.0,-2.0/9.0, 2.0/9.0, 4.0/9.0,-2.0/9.0, + 4.0/9.0, 4.0/9.0,-2.0/9.0, 6.0/9.0, 4.0/9.0,-2.0/9.0, 8.0/9.0, 4.0/9.0,-2.0/9.0, + -8.0/9.0, 6.0/9.0,-2.0/9.0, -6.0/9.0, 6.0/9.0,-2.0/9.0, -4.0/9.0, 6.0/9.0,-2.0/9.0, + -2.0/9.0, 6.0/9.0,-2.0/9.0, 0.0, 6.0/9.0,-2.0/9.0, 2.0/9.0, 6.0/9.0,-2.0/9.0, + 4.0/9.0, 6.0/9.0,-2.0/9.0, 6.0/9.0, 6.0/9.0,-2.0/9.0, 8.0/9.0, 6.0/9.0,-2.0/9.0, + -8.0/9.0, 8.0/9.0,-2.0/9.0, -6.0/9.0, 8.0/9.0,-2.0/9.0, -4.0/9.0, 8.0/9.0,-2.0/9.0, + -2.0/9.0, 8.0/9.0,-2.0/9.0, 0.0, 8.0/9.0,-2.0/9.0, 2.0/9.0, 8.0/9.0,-2.0/9.0, + 4.0/9.0, 8.0/9.0,-2.0/9.0, 6.0/9.0, 8.0/9.0,-2.0/9.0, 8.0/9.0, 8.0/9.0,-2.0/9.0, + -8.0/9.0,-8.0/9.0, 0.0, -6.0/9.0,-8.0/9.0, 0.0, -4.0/9.0,-8.0/9.0, 0.0, + -2.0/9.0,-8.0/9.0, 0.0, 0.0,-8.0/9.0, 0.0, 2.0/9.0,-8.0/9.0, 0.0, + 4.0/9.0,-8.0/9.0, 0.0, 6.0/9.0,-8.0/9.0, 0.0, 8.0/9.0,-8.0/9.0, 0.0, + -8.0/9.0,-6.0/9.0, 0.0, -6.0/9.0,-6.0/9.0, 0.0, -4.0/9.0,-6.0/9.0, 0.0, + -2.0/9.0,-6.0/9.0, 0.0, 0.0,-6.0/9.0, 0.0, 2.0/9.0,-6.0/9.0, 0.0, + 4.0/9.0,-6.0/9.0, 0.0, 6.0/9.0,-6.0/9.0, 0.0, 8.0/9.0,-6.0/9.0, 0.0, + -8.0/9.0,-4.0/9.0, 0.0, -6.0/9.0,-4.0/9.0, 0.0, -4.0/9.0,-4.0/9.0, 0.0, + -2.0/9.0,-4.0/9.0, 0.0, 0.0,-4.0/9.0, 0.0, 2.0/9.0,-4.0/9.0, 0.0, + 4.0/9.0,-4.0/9.0, 0.0, 6.0/9.0,-4.0/9.0, 0.0, 8.0/9.0,-4.0/9.0, 0.0, + -8.0/9.0,-2.0/9.0, 0.0, -6.0/9.0,-2.0/9.0, 0.0, -4.0/9.0,-2.0/9.0, 0.0, + -2.0/9.0,-2.0/9.0, 0.0, 0.0,-2.0/9.0, 0.0, 2.0/9.0,-2.0/9.0, 0.0, + 4.0/9.0,-2.0/9.0, 0.0, 6.0/9.0,-2.0/9.0, 0.0, 8.0/9.0,-2.0/9.0, 0.0, + -8.0/9.0, 0.0, 0.0, -6.0/9.0, 0.0, 0.0, -4.0/9.0, 0.0, 0.0, + -2.0/9.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0/9.0, 0.0, 0.0, + 4.0/9.0, 0.0, 0.0, 6.0/9.0, 0.0, 0.0, 8.0/9.0, 0.0, 0.0, + -8.0/9.0, 2.0/9.0, 0.0, -6.0/9.0, 2.0/9.0, 0.0, -4.0/9.0, 2.0/9.0, 0.0, + -2.0/9.0, 2.0/9.0, 0.0, 0.0, 2.0/9.0, 0.0, 2.0/9.0, 2.0/9.0, 0.0, + 4.0/9.0, 2.0/9.0, 0.0, 6.0/9.0, 2.0/9.0, 0.0, 8.0/9.0, 2.0/9.0, 0.0, + -8.0/9.0, 4.0/9.0, 0.0, -6.0/9.0, 4.0/9.0, 0.0, -4.0/9.0, 4.0/9.0, 0.0, + -2.0/9.0, 4.0/9.0, 0.0, 0.0, 4.0/9.0, 0.0, 2.0/9.0, 4.0/9.0, 0.0, + 4.0/9.0, 4.0/9.0, 0.0, 6.0/9.0, 4.0/9.0, 0.0, 8.0/9.0, 4.0/9.0, 0.0, + -8.0/9.0, 6.0/9.0, 0.0, -6.0/9.0, 6.0/9.0, 0.0, -4.0/9.0, 6.0/9.0, 0.0, + -2.0/9.0, 6.0/9.0, 0.0, 0.0, 6.0/9.0, 0.0, 2.0/9.0, 6.0/9.0, 0.0, + 4.0/9.0, 6.0/9.0, 0.0, 6.0/9.0, 6.0/9.0, 0.0, 8.0/9.0, 6.0/9.0, 0.0, + -8.0/9.0, 8.0/9.0, 0.0, -6.0/9.0, 8.0/9.0, 0.0, -4.0/9.0, 8.0/9.0, 0.0, + -2.0/9.0, 8.0/9.0, 0.0, 0.0, 8.0/9.0, 0.0, 2.0/9.0, 8.0/9.0, 0.0, + 4.0/9.0, 8.0/9.0, 0.0, 6.0/9.0, 8.0/9.0, 0.0, 8.0/9.0, 8.0/9.0, 0.0, + -8.0/9.0,-8.0/9.0, 2.0/9.0, -6.0/9.0,-8.0/9.0, 2.0/9.0, -4.0/9.0,-8.0/9.0, 2.0/9.0, + -2.0/9.0,-8.0/9.0, 2.0/9.0, 0.0,-8.0/9.0, 2.0/9.0, 2.0/9.0,-8.0/9.0, 2.0/9.0, + 4.0/9.0,-8.0/9.0, 2.0/9.0, 6.0/9.0,-8.0/9.0, 2.0/9.0, 8.0/9.0,-8.0/9.0, 2.0/9.0, + -8.0/9.0,-6.0/9.0, 2.0/9.0, -6.0/9.0,-6.0/9.0, 2.0/9.0, -4.0/9.0,-6.0/9.0, 2.0/9.0, + -2.0/9.0,-6.0/9.0, 2.0/9.0, 0.0,-6.0/9.0, 2.0/9.0, 2.0/9.0,-6.0/9.0, 2.0/9.0, + 4.0/9.0,-6.0/9.0, 2.0/9.0, 6.0/9.0,-6.0/9.0, 2.0/9.0, 8.0/9.0,-6.0/9.0, 2.0/9.0, + -8.0/9.0,-4.0/9.0, 2.0/9.0, -6.0/9.0,-4.0/9.0, 2.0/9.0, -4.0/9.0,-4.0/9.0, 2.0/9.0, + -2.0/9.0,-4.0/9.0, 2.0/9.0, 0.0,-4.0/9.0, 2.0/9.0, 2.0/9.0,-4.0/9.0, 2.0/9.0, + 4.0/9.0,-4.0/9.0, 2.0/9.0, 6.0/9.0,-4.0/9.0, 2.0/9.0, 8.0/9.0,-4.0/9.0, 2.0/9.0, + -8.0/9.0,-2.0/9.0, 2.0/9.0, -6.0/9.0,-2.0/9.0, 2.0/9.0, -4.0/9.0,-2.0/9.0, 2.0/9.0, + -2.0/9.0,-2.0/9.0, 2.0/9.0, 0.0,-2.0/9.0, 2.0/9.0, 2.0/9.0,-2.0/9.0, 2.0/9.0, + 4.0/9.0,-2.0/9.0, 2.0/9.0, 6.0/9.0,-2.0/9.0, 2.0/9.0, 8.0/9.0,-2.0/9.0, 2.0/9.0, + -8.0/9.0, 0.0, 2.0/9.0, -6.0/9.0, 0.0, 2.0/9.0, -4.0/9.0, 0.0, 2.0/9.0, + -2.0/9.0, 0.0, 2.0/9.0, 0.0, 0.0, 2.0/9.0, 2.0/9.0, 0.0, 2.0/9.0, + 4.0/9.0, 0.0, 2.0/9.0, 6.0/9.0, 0.0, 2.0/9.0, 8.0/9.0, 0.0, 2.0/9.0, + -8.0/9.0, 2.0/9.0, 2.0/9.0, -6.0/9.0, 2.0/9.0, 2.0/9.0, -4.0/9.0, 2.0/9.0, 2.0/9.0, + -2.0/9.0, 2.0/9.0, 2.0/9.0, 0.0, 2.0/9.0, 2.0/9.0, 2.0/9.0, 2.0/9.0, 2.0/9.0, + 4.0/9.0, 2.0/9.0, 2.0/9.0, 6.0/9.0, 2.0/9.0, 2.0/9.0, 8.0/9.0, 2.0/9.0, 2.0/9.0, + -8.0/9.0, 4.0/9.0, 2.0/9.0, -6.0/9.0, 4.0/9.0, 2.0/9.0, -4.0/9.0, 4.0/9.0, 2.0/9.0, + -2.0/9.0, 4.0/9.0, 2.0/9.0, 0.0, 4.0/9.0, 2.0/9.0, 2.0/9.0, 4.0/9.0, 2.0/9.0, + 4.0/9.0, 4.0/9.0, 2.0/9.0, 6.0/9.0, 4.0/9.0, 2.0/9.0, 8.0/9.0, 4.0/9.0, 2.0/9.0, + -8.0/9.0, 6.0/9.0, 2.0/9.0, -6.0/9.0, 6.0/9.0, 2.0/9.0, -4.0/9.0, 6.0/9.0, 2.0/9.0, + -2.0/9.0, 6.0/9.0, 2.0/9.0, 0.0, 6.0/9.0, 2.0/9.0, 2.0/9.0, 6.0/9.0, 2.0/9.0, + 4.0/9.0, 6.0/9.0, 2.0/9.0, 6.0/9.0, 6.0/9.0, 2.0/9.0, 8.0/9.0, 6.0/9.0, 2.0/9.0, + -8.0/9.0, 8.0/9.0, 2.0/9.0, -6.0/9.0, 8.0/9.0, 2.0/9.0, -4.0/9.0, 8.0/9.0, 2.0/9.0, + -2.0/9.0, 8.0/9.0, 2.0/9.0, 0.0, 8.0/9.0, 2.0/9.0, 2.0/9.0, 8.0/9.0, 2.0/9.0, + 4.0/9.0, 8.0/9.0, 2.0/9.0, 6.0/9.0, 8.0/9.0, 2.0/9.0, 8.0/9.0, 8.0/9.0, 2.0/9.0, + -8.0/9.0,-8.0/9.0, 4.0/9.0, -6.0/9.0,-8.0/9.0, 4.0/9.0, -4.0/9.0,-8.0/9.0, 4.0/9.0, + -2.0/9.0,-8.0/9.0, 4.0/9.0, 0.0,-8.0/9.0, 4.0/9.0, 2.0/9.0,-8.0/9.0, 4.0/9.0, + 4.0/9.0,-8.0/9.0, 4.0/9.0, 6.0/9.0,-8.0/9.0, 4.0/9.0, 8.0/9.0,-8.0/9.0, 4.0/9.0, + -8.0/9.0,-6.0/9.0, 4.0/9.0, -6.0/9.0,-6.0/9.0, 4.0/9.0, -4.0/9.0,-6.0/9.0, 4.0/9.0, + -2.0/9.0,-6.0/9.0, 4.0/9.0, 0.0,-6.0/9.0, 4.0/9.0, 2.0/9.0,-6.0/9.0, 4.0/9.0, + 4.0/9.0,-6.0/9.0, 4.0/9.0, 6.0/9.0,-6.0/9.0, 4.0/9.0, 8.0/9.0,-6.0/9.0, 4.0/9.0, + -8.0/9.0,-4.0/9.0, 4.0/9.0, -6.0/9.0,-4.0/9.0, 4.0/9.0, -4.0/9.0,-4.0/9.0, 4.0/9.0, + -2.0/9.0,-4.0/9.0, 4.0/9.0, 0.0,-4.0/9.0, 4.0/9.0, 2.0/9.0,-4.0/9.0, 4.0/9.0, + 4.0/9.0,-4.0/9.0, 4.0/9.0, 6.0/9.0,-4.0/9.0, 4.0/9.0, 8.0/9.0,-4.0/9.0, 4.0/9.0, + -8.0/9.0,-2.0/9.0, 4.0/9.0, -6.0/9.0,-2.0/9.0, 4.0/9.0, -4.0/9.0,-2.0/9.0, 4.0/9.0, + -2.0/9.0,-2.0/9.0, 4.0/9.0, 0.0,-2.0/9.0, 4.0/9.0, 2.0/9.0,-2.0/9.0, 4.0/9.0, + 4.0/9.0,-2.0/9.0, 4.0/9.0, 6.0/9.0,-2.0/9.0, 4.0/9.0, 8.0/9.0,-2.0/9.0, 4.0/9.0, + -8.0/9.0, 0.0, 4.0/9.0, -6.0/9.0, 0.0, 4.0/9.0, -4.0/9.0, 0.0, 4.0/9.0, + -2.0/9.0, 0.0, 4.0/9.0, 0.0, 0.0, 4.0/9.0, 2.0/9.0, 0.0, 4.0/9.0, + 4.0/9.0, 0.0, 4.0/9.0, 6.0/9.0, 0.0, 4.0/9.0, 8.0/9.0, 0.0, 4.0/9.0, + -8.0/9.0, 2.0/9.0, 4.0/9.0, -6.0/9.0, 2.0/9.0, 4.0/9.0, -4.0/9.0, 2.0/9.0, 4.0/9.0, + -2.0/9.0, 2.0/9.0, 4.0/9.0, 0.0, 2.0/9.0, 4.0/9.0, 2.0/9.0, 2.0/9.0, 4.0/9.0, + 4.0/9.0, 2.0/9.0, 4.0/9.0, 6.0/9.0, 2.0/9.0, 4.0/9.0, 8.0/9.0, 2.0/9.0, 4.0/9.0, + -8.0/9.0, 4.0/9.0, 4.0/9.0, -6.0/9.0, 4.0/9.0, 4.0/9.0, -4.0/9.0, 4.0/9.0, 4.0/9.0, + -2.0/9.0, 4.0/9.0, 4.0/9.0, 0.0, 4.0/9.0, 4.0/9.0, 2.0/9.0, 4.0/9.0, 4.0/9.0, + 4.0/9.0, 4.0/9.0, 4.0/9.0, 6.0/9.0, 4.0/9.0, 4.0/9.0, 8.0/9.0, 4.0/9.0, 4.0/9.0, + -8.0/9.0, 6.0/9.0, 4.0/9.0, -6.0/9.0, 6.0/9.0, 4.0/9.0, -4.0/9.0, 6.0/9.0, 4.0/9.0, + -2.0/9.0, 6.0/9.0, 4.0/9.0, 0.0, 6.0/9.0, 4.0/9.0, 2.0/9.0, 6.0/9.0, 4.0/9.0, + 4.0/9.0, 6.0/9.0, 4.0/9.0, 6.0/9.0, 6.0/9.0, 4.0/9.0, 8.0/9.0, 6.0/9.0, 4.0/9.0, + -8.0/9.0, 8.0/9.0, 4.0/9.0, -6.0/9.0, 8.0/9.0, 4.0/9.0, -4.0/9.0, 8.0/9.0, 4.0/9.0, + -2.0/9.0, 8.0/9.0, 4.0/9.0, 0.0, 8.0/9.0, 4.0/9.0, 2.0/9.0, 8.0/9.0, 4.0/9.0, + 4.0/9.0, 8.0/9.0, 4.0/9.0, 6.0/9.0, 8.0/9.0, 4.0/9.0, 8.0/9.0, 8.0/9.0, 4.0/9.0, + -8.0/9.0,-8.0/9.0, 6.0/9.0, -6.0/9.0,-8.0/9.0, 6.0/9.0, -4.0/9.0,-8.0/9.0, 6.0/9.0, + -2.0/9.0,-8.0/9.0, 6.0/9.0, 0.0,-8.0/9.0, 6.0/9.0, 2.0/9.0,-8.0/9.0, 6.0/9.0, + 4.0/9.0,-8.0/9.0, 6.0/9.0, 6.0/9.0,-8.0/9.0, 6.0/9.0, 8.0/9.0,-8.0/9.0, 6.0/9.0, + -8.0/9.0,-6.0/9.0, 6.0/9.0, -6.0/9.0,-6.0/9.0, 6.0/9.0, -4.0/9.0,-6.0/9.0, 6.0/9.0, + -2.0/9.0,-6.0/9.0, 6.0/9.0, 0.0,-6.0/9.0, 6.0/9.0, 2.0/9.0,-6.0/9.0, 6.0/9.0, + 4.0/9.0,-6.0/9.0, 6.0/9.0, 6.0/9.0,-6.0/9.0, 6.0/9.0, 8.0/9.0,-6.0/9.0, 6.0/9.0, + -8.0/9.0,-4.0/9.0, 6.0/9.0, -6.0/9.0,-4.0/9.0, 6.0/9.0, -4.0/9.0,-4.0/9.0, 6.0/9.0, + -2.0/9.0,-4.0/9.0, 6.0/9.0, 0.0,-4.0/9.0, 6.0/9.0, 2.0/9.0,-4.0/9.0, 6.0/9.0, + 4.0/9.0,-4.0/9.0, 6.0/9.0, 6.0/9.0,-4.0/9.0, 6.0/9.0, 8.0/9.0,-4.0/9.0, 6.0/9.0, + -8.0/9.0,-2.0/9.0, 6.0/9.0, -6.0/9.0,-2.0/9.0, 6.0/9.0, -4.0/9.0,-2.0/9.0, 6.0/9.0, + -2.0/9.0,-2.0/9.0, 6.0/9.0, 0.0,-2.0/9.0, 6.0/9.0, 2.0/9.0,-2.0/9.0, 6.0/9.0, + 4.0/9.0,-2.0/9.0, 6.0/9.0, 6.0/9.0,-2.0/9.0, 6.0/9.0, 8.0/9.0,-2.0/9.0, 6.0/9.0, + -8.0/9.0, 0.0, 6.0/9.0, -6.0/9.0, 0.0, 6.0/9.0, -4.0/9.0, 0.0, 6.0/9.0, + -2.0/9.0, 0.0, 6.0/9.0, 0.0, 0.0, 6.0/9.0, 2.0/9.0, 0.0, 6.0/9.0, + 4.0/9.0, 0.0, 6.0/9.0, 6.0/9.0, 0.0, 6.0/9.0, 8.0/9.0, 0.0, 6.0/9.0, + -8.0/9.0, 2.0/9.0, 6.0/9.0, -6.0/9.0, 2.0/9.0, 6.0/9.0, -4.0/9.0, 2.0/9.0, 6.0/9.0, + -2.0/9.0, 2.0/9.0, 6.0/9.0, 0.0, 2.0/9.0, 6.0/9.0, 2.0/9.0, 2.0/9.0, 6.0/9.0, + 4.0/9.0, 2.0/9.0, 6.0/9.0, 6.0/9.0, 2.0/9.0, 6.0/9.0, 8.0/9.0, 2.0/9.0, 6.0/9.0, + -8.0/9.0, 4.0/9.0, 6.0/9.0, -6.0/9.0, 4.0/9.0, 6.0/9.0, -4.0/9.0, 4.0/9.0, 6.0/9.0, + -2.0/9.0, 4.0/9.0, 6.0/9.0, 0.0, 4.0/9.0, 6.0/9.0, 2.0/9.0, 4.0/9.0, 6.0/9.0, + 4.0/9.0, 4.0/9.0, 6.0/9.0, 6.0/9.0, 4.0/9.0, 6.0/9.0, 8.0/9.0, 4.0/9.0, 6.0/9.0, + -8.0/9.0, 6.0/9.0, 6.0/9.0, -6.0/9.0, 6.0/9.0, 6.0/9.0, -4.0/9.0, 6.0/9.0, 6.0/9.0, + -2.0/9.0, 6.0/9.0, 6.0/9.0, 0.0, 6.0/9.0, 6.0/9.0, 2.0/9.0, 6.0/9.0, 6.0/9.0, + 4.0/9.0, 6.0/9.0, 6.0/9.0, 6.0/9.0, 6.0/9.0, 6.0/9.0, 8.0/9.0, 6.0/9.0, 6.0/9.0, + -8.0/9.0, 8.0/9.0, 6.0/9.0, -6.0/9.0, 8.0/9.0, 6.0/9.0, -4.0/9.0, 8.0/9.0, 6.0/9.0, + -2.0/9.0, 8.0/9.0, 6.0/9.0, 0.0, 8.0/9.0, 6.0/9.0, 2.0/9.0, 8.0/9.0, 6.0/9.0, + 4.0/9.0, 8.0/9.0, 6.0/9.0, 6.0/9.0, 8.0/9.0, 6.0/9.0, 8.0/9.0, 8.0/9.0, 6.0/9.0, + -8.0/9.0,-8.0/9.0, 8.0/9.0, -6.0/9.0,-8.0/9.0, 8.0/9.0, -4.0/9.0,-8.0/9.0, 8.0/9.0, + -2.0/9.0,-8.0/9.0, 8.0/9.0, 0.0,-8.0/9.0, 8.0/9.0, 2.0/9.0,-8.0/9.0, 8.0/9.0, + 4.0/9.0,-8.0/9.0, 8.0/9.0, 6.0/9.0,-8.0/9.0, 8.0/9.0, 8.0/9.0,-8.0/9.0, 8.0/9.0, + -8.0/9.0,-6.0/9.0, 8.0/9.0, -6.0/9.0,-6.0/9.0, 8.0/9.0, -4.0/9.0,-6.0/9.0, 8.0/9.0, + -2.0/9.0,-6.0/9.0, 8.0/9.0, 0.0,-6.0/9.0, 8.0/9.0, 2.0/9.0,-6.0/9.0, 8.0/9.0, + 4.0/9.0,-6.0/9.0, 8.0/9.0, 6.0/9.0,-6.0/9.0, 8.0/9.0, 8.0/9.0,-6.0/9.0, 8.0/9.0, + -8.0/9.0,-4.0/9.0, 8.0/9.0, -6.0/9.0,-4.0/9.0, 8.0/9.0, -4.0/9.0,-4.0/9.0, 8.0/9.0, + -2.0/9.0,-4.0/9.0, 8.0/9.0, 0.0,-4.0/9.0, 8.0/9.0, 2.0/9.0,-4.0/9.0, 8.0/9.0, + 4.0/9.0,-4.0/9.0, 8.0/9.0, 6.0/9.0,-4.0/9.0, 8.0/9.0, 8.0/9.0,-4.0/9.0, 8.0/9.0, + -8.0/9.0,-2.0/9.0, 8.0/9.0, -6.0/9.0,-2.0/9.0, 8.0/9.0, -4.0/9.0,-2.0/9.0, 8.0/9.0, + -2.0/9.0,-2.0/9.0, 8.0/9.0, 0.0,-2.0/9.0, 8.0/9.0, 2.0/9.0,-2.0/9.0, 8.0/9.0, + 4.0/9.0,-2.0/9.0, 8.0/9.0, 6.0/9.0,-2.0/9.0, 8.0/9.0, 8.0/9.0,-2.0/9.0, 8.0/9.0, + -8.0/9.0, 0.0, 8.0/9.0, -6.0/9.0, 0.0, 8.0/9.0, -4.0/9.0, 0.0, 8.0/9.0, + -2.0/9.0, 0.0, 8.0/9.0, 0.0, 0.0, 8.0/9.0, 2.0/9.0, 0.0, 8.0/9.0, + 4.0/9.0, 0.0, 8.0/9.0, 6.0/9.0, 0.0, 8.0/9.0, 8.0/9.0, 0.0, 8.0/9.0, + -8.0/9.0, 2.0/9.0, 8.0/9.0, -6.0/9.0, 2.0/9.0, 8.0/9.0, -4.0/9.0, 2.0/9.0, 8.0/9.0, + -2.0/9.0, 2.0/9.0, 8.0/9.0, 0.0, 2.0/9.0, 8.0/9.0, 2.0/9.0, 2.0/9.0, 8.0/9.0, + 4.0/9.0, 2.0/9.0, 8.0/9.0, 6.0/9.0, 2.0/9.0, 8.0/9.0, 8.0/9.0, 2.0/9.0, 8.0/9.0, + -8.0/9.0, 4.0/9.0, 8.0/9.0, -6.0/9.0, 4.0/9.0, 8.0/9.0, -4.0/9.0, 4.0/9.0, 8.0/9.0, + -2.0/9.0, 4.0/9.0, 8.0/9.0, 0.0, 4.0/9.0, 8.0/9.0, 2.0/9.0, 4.0/9.0, 8.0/9.0, + 4.0/9.0, 4.0/9.0, 8.0/9.0, 6.0/9.0, 4.0/9.0, 8.0/9.0, 8.0/9.0, 4.0/9.0, 8.0/9.0, + -8.0/9.0, 6.0/9.0, 8.0/9.0, -6.0/9.0, 6.0/9.0, 8.0/9.0, -4.0/9.0, 6.0/9.0, 8.0/9.0, + -2.0/9.0, 6.0/9.0, 8.0/9.0, 0.0, 6.0/9.0, 8.0/9.0, 2.0/9.0, 6.0/9.0, 8.0/9.0, + 4.0/9.0, 6.0/9.0, 8.0/9.0, 6.0/9.0, 6.0/9.0, 8.0/9.0, 8.0/9.0, 6.0/9.0, 8.0/9.0, + -8.0/9.0, 8.0/9.0, 8.0/9.0, -6.0/9.0, 8.0/9.0, 8.0/9.0, -4.0/9.0, 8.0/9.0, 8.0/9.0, + -2.0/9.0, 8.0/9.0, 8.0/9.0, 0.0, 8.0/9.0, 8.0/9.0, 2.0/9.0, 8.0/9.0, 8.0/9.0, + 4.0/9.0, 8.0/9.0, 8.0/9.0, 6.0/9.0, 8.0/9.0, 8.0/9.0, 8.0/9.0, 8.0/9.0, 8.0/9.0 +}; + + +static const REAL *grouptableA[16] = +{ 0,group5bits,group7bits,group10bits,0,0,0,0,0,0,0,0,0,0,0,0}; +static const REAL *grouptableB1[16] = +{ 0,group5bits,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; +static const REAL *grouptableB234[16] = +{ 0,group5bits,group7bits,0,group10bits,0,0,0,0,0,0,0,0,0,0,0}; + +static const int codelengthtableA[16] = +{ 0, 5, 7, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; +static const int codelengthtableB1[16] = +{ 0, 5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; +static const int codelengthtableB2[16] = +{ 0, 5, 7, 3, 10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 }; +static const int codelengthtableB3[8] = { 0, 5, 7, 3, 10, 4, 5, 16 }; +static const int codelengthtableB4[4] = { 0, 5, 7, 16 }; + + +static const REAL factortableA[16] = +{ 0.0, 1.0/2.0, 1.0/4.0, 1.0/8.0, + 1.0/8.0, 1.0/16.0, 1.0/32.0, 1.0/64.0, + 1.0/128.0, 1.0/256.0, 1.0/512.0, 1.0/1024.0, + 1.0/2048.0, 1.0/4096.0, 1.0/8192.0, 1.0/16384.0 }; +static const REAL factortableB1[16] = +{ 0.0, 1.0/2.0, 1.0/4.0, 1.0/8.0, + 1.0/16.0, 1.0/32.0, 1.0/64.0, 1.0/128.0, + 1.0/256.0, 1.0/512.0, 1.0/1024.0, 1.0/2048.0, + 1.0/4096.0, 1.0/8192.0, 1.0/16384.0, 1.0/32768.0 }; +static const REAL factortableB2[16] = +{ 0.0, 1.0/2.0, 1.0/4.0, 1.0/4.0, + 1.0/8.0, 1.0/8.0, 1.0/16.0, 1.0/32.0, + 1.0/64.0, 1.0/128.0, 1.0/256.0, 1.0/512.0, + 1.0/1024.0, 1.0/2048.0, 1.0/4096.0, 1.0/32768.0 }; +static const REAL factortableB3[8] = +{ 0.0, 1.0/2.0, 1.0/4.0, 1.0/4.0, 1.0/8.0, 1.0/8.0, 1.0/16.0, 1.0/32768.0 }; +static const REAL factortableB4[4] = { 0.0, 1.0/2.0, 1.0/4.0, 1.0/32768.0 }; + + +static const REAL ctableA[16]= +{ 0.0, 1.33333333333, 1.60000000000, 1.77777777777, + 1.06666666666, 1.03225806452, 1.01587301587, 1.00787401575, + 1.00392156863, 1.00195694716, 1.00097751711, 1.00048851979, + 1.00024420024, 1.00012208522, 1.00006103888, 1.00003051851}; +static const REAL ctableB1[16]= +{ 0.0, 1.33333333333, 1.14285714286, 1.06666666666, + 1.03225806452, 1.01587301587, 1.00787401575, 1.00392156863, + 1.00195694716, 1.00097751711, 1.00048851979, 1.00024420024, + 1.00012208522, 1.00006103888, 1.00003051851, 1.00001525902}; +static const REAL ctableB2[16] = +{ 0.0, 1.33333333333, 1.60000000000, 1.14285714286, + 1.77777777777, 1.06666666666, 1.03225806452, 1.01587301587, + 1.00787401575, 1.00392156863, 1.00195694716, 1.00097751711, + 1.00048851979, 1.00024420024, 1.00012208522, 1.00001525902}; +static const REAL ctableB3[8] = +{ 0.0, 1.33333333333, 1.60000000000, 1.14285714286, + 1.77777777777, 1.06666666666, 1.03225806452, 1.00001525902 }; +static const REAL ctableB4[4] = +{ 0.0, 1.33333333333, 1.60000000000, 1.00001525902 }; + + +static const REAL dtableA[16]= +{ 0.0, 0.50000000000, 0.50000000000, 0.50000000000, + 0.12500000000, 0.06250000000, 0.03125000000, 0.01562500000, + 0.00781250000, 0.00390625000, 0.00195312500, 0.00097656250, + 0.00048828125, 0.00024414063, 0.00012207031, 0.00006103516}; + +static const REAL dtableB1[16]= +{ 0.0, 0.50000000000, 0.25000000000, 0.12500000000, + 0.06250000000, 0.03125000000, 0.01562500000, 0.00781250000, + 0.00390625000, 0.00195312500, 0.00097656250, 0.00048828125, + 0.00024414063, 0.00012207031, 0.00006103516, 0.00003051758}; + +static const REAL dtableB2[16]= +{ 0.0, 0.50000000000, 0.50000000000, 0.25000000000, + 0.50000000000, 0.12500000000, 0.06250000000, 0.03125000000, + 0.01562500000, 0.00781250000, 0.00390625000, 0.00195312500, + 0.00097656250, 0.00048828125, 0.00024414063, 0.00003051758}; + +static const REAL dtableB3[8]= +{ 0.0, 0.50000000000, 0.50000000000, 0.25000000000, + 0.50000000000, 0.12500000000, 0.06250000000, 0.00003051758}; + +static const REAL dtableB4[4]= +{0.0, 0.50000000000, 0.50000000000, 0.00003051758}; + + + + + + +#endif diff --git a/mpeglib/lib/splay/mpegAudioBitWindow.cpp b/mpeglib/lib/splay/mpegAudioBitWindow.cpp new file mode 100644 index 00000000..5e63f1fc --- /dev/null +++ b/mpeglib/lib/splay/mpegAudioBitWindow.cpp @@ -0,0 +1,41 @@ +/* + bitwindow class + Copyright (C) 2000 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "mpegAudioBitWindow.h" + + +#include <iostream> + +using namespace std; + +int MpegAudioBitWindow::getCanReadBits() { + int p=bitindex>>3; + int bytes=point - p; + int bits=bytes*8+(bitindex&7); + cout << "point:"<<point + << " p:"<<p + << " bytes:"<<bytes + <<" bitindex:"<<bitindex<<" can read:"<<bits<<endl; + return bits; +} + +void MpegAudioBitWindow::wrap(void) { + int p=bitindex>>3; + point&=(WINDOWSIZE-1); + + if(p>=point) { + for(register int i=4;i<point;i++) + buffer[WINDOWSIZE+i]=buffer[i]; + } + *((int *)(buffer+WINDOWSIZE))=*((int *)buffer); +} diff --git a/mpeglib/lib/splay/mpegAudioBitWindow.h b/mpeglib/lib/splay/mpegAudioBitWindow.h new file mode 100644 index 00000000..f7a2f64c --- /dev/null +++ b/mpeglib/lib/splay/mpegAudioBitWindow.h @@ -0,0 +1,141 @@ +/* + bitwindow class + Copyright (C) 2000 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#ifndef __MPEGBITWINDOW_H +#define __MPEGBITWINDOW_H + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef WORDS_BIGENDIAN +#define _KEY 0 +#else +#define _KEY 3 +#endif + + + +#define WINDOWSIZE 4096 +#define BITWINDOWSIZE (WINDOWSIZE*8) + + +class MpegAudioBitWindow { + + int point,bitindex; + char buffer[2*WINDOWSIZE]; + + public: + MpegAudioBitWindow(){bitindex=point=0;} + + inline void initialize(void) {bitindex=point=0;} + inline int gettotalbit(void) const {return bitindex;} + + inline void putbyte(int c) {buffer[point&(WINDOWSIZE-1)]=c;point++;} + void wrap(void); + inline void rewind(int bits) {bitindex-=bits;} + inline void forward(int bits) {bitindex+=bits;} + + // returns number of bits which can safley read + int getCanReadBits(); + + + // + // Ugly bitgetting inline functions for higher speed + // + + + inline int getbits(int bits) { + union + { + char store[4]; + int current; + }u; + int bi; + + if(!bits)return 0; + + u.current=0; + bi=(bitindex&7); + u.store[_KEY]=buffer[(bitindex>>3)&(WINDOWSIZE-1)]<<bi; + //u.store[_KEY]=buffer[bitindex>>3]<<bi; + bi=8-bi; + bitindex+=bi; + + while(bits) { + if(!bi) { + u.store[_KEY]=buffer[(bitindex>>3)&(WINDOWSIZE-1)]; + //u.store[_KEY]=buffer[bitindex>>3]; + bitindex+=8; + bi=8; + } + + if(bits>=bi) { + u.current<<=bi; + bits-=bi; + bi=0; + } + else { + u.current<<=bits; + bi-=bits; + bits=0; + } + } + bitindex-=bi; + + return (u.current>>8); + } + + + int getbit(void) { + register int r=(buffer[(bitindex>>3)&(WINDOWSIZE-1)]>>(7-(bitindex&7)))&1; + //register int r=(buffer[bitindex>>3]>>(7-(bitindex&7)))&1; + bitindex++; + return r; + } + + // no range check version + inline int getbits9_f(int bits) { + register unsigned short a; + { + int offset=bitindex>>3; + a=(((unsigned char)buffer[offset])<<8)|((unsigned char)buffer[offset+1]); + } + a<<=(bitindex&7); + bitindex+=bits; + return (int)((unsigned int)(a>>(16-bits))); + } + + // range check version + int getbits9(int bits) { + register unsigned short a; + { + int offset=(bitindex>>3)&(WINDOWSIZE-1); + a=(((unsigned char)buffer[offset])<<8)|((unsigned char)buffer[offset+1]); + } + + a<<=(bitindex&7); + bitindex+=bits; + return (int)((unsigned int)(a>>(16-bits))); + } + + int peek8() { + int offset = (bitindex>>3)&(WINDOWSIZE-1), a; + a=(((unsigned char)buffer[offset])<<8) | ((unsigned char)buffer[offset+1]); + return (a >> (8-(bitindex&7))) & 0xff; + } + + +}; +#endif diff --git a/mpeglib/lib/splay/mpegAudioFrame.cpp b/mpeglib/lib/splay/mpegAudioFrame.cpp new file mode 100644 index 00000000..807a23a6 --- /dev/null +++ b/mpeglib/lib/splay/mpegAudioFrame.cpp @@ -0,0 +1,200 @@ +/* + converts raw mpeg audio stream data into mpeg I encoded audio frames/packets + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "mpegAudioFrame.h" + +#define MPEGAUDIOFRAMESIZE 4096 + +#define FRAME_SYNC 0 +#define FRAME_CHECK_HEADER_1 1 +#define FRAME_CHECK_HEADER_2 2 + +#include <iostream> + +using namespace std; + +MpegAudioFrame::MpegAudioFrame():Framer(MPEGAUDIOFRAMESIZE) { + mpegAudioHeader=new MpegAudioHeader(); +} + + +MpegAudioFrame::~MpegAudioFrame() { + delete mpegAudioHeader; +} + + +void MpegAudioFrame::unsync(RawDataBuffer* store,int ) { + // invalidate header in buffer + unsigned char* start=store->ptr(); + start[0]=0x0; + start[1]=0x0; + store->setpos(0); + find_frame_state=FRAME_SYNC; + framesize=0; +} + + +/** + here we parse byte by byte the raw input, first + we search for the magic bytes: 0xfffx, then + we read the remaining 2 bytes for the header, + check if they are "wrong" in a mpeg I audio special way. + If everything is fine, we continue with the next state. + + Note: we can be sure here, that the "store" can at least + store 4 bytes. +*/ +int MpegAudioFrame::find_frame(RawDataBuffer* input_buffer, + RawDataBuffer* store_buffer) { + unsigned char* store=store_buffer->current(); + int back=false; + + if (find_frame_state == FRAME_SYNC) { + if (store_buffer->pos() != 0) { + cout << "store buffer not at beginning MpegAudioFrame::find_frame"<<endl; + cout << "current state requires this"<<endl; + exit(0); + } + } + + while(input_buffer->eof()==false) { + // search for sync bytes + unsigned char* input=input_buffer->current(); + if (find_frame_state == FRAME_SYNC) { + while(input_buffer->eof() == false) { + input=input_buffer->current(); + // shift + store[0]=store[1]; + store[1]=input[0]; + input_buffer->inc(); + + if (store[0] != 0xff) { + continue; + } + // upper 4 bit are syncword, except bit one + // which is layer 2.5 indicator. + if ( (store[1] & 0xe0) != 0xe0) { + continue; + } + + // found header, now check if other info is ok, too. + store_buffer->setpos(2); + find_frame_state=FRAME_CHECK_HEADER_1; + break; + } + // back to "main loop" + continue; + } + // ok, try to read two other bytes and then validate the header + if (find_frame_state == FRAME_CHECK_HEADER_1) { + store[2]=input[0]; + input_buffer->inc(); + find_frame_state=FRAME_CHECK_HEADER_2; + // back to main loop + continue; + } + if (find_frame_state == FRAME_CHECK_HEADER_2) { + store[3]=input[0]; + input_buffer->inc(); + } + + // ok, read 4 header bytes. Now check the validity of the + // header. + int lHeaderOk; + lHeaderOk=mpegAudioHeader->parseHeader(store); + if (lHeaderOk == false) { + find_frame_state=FRAME_SYNC; + store_buffer->setpos(0); + // go back to "sync for frame" + continue; + } + framesize=mpegAudioHeader->getFramesize(); + // if framesize > max mepg framsize its an error + if (framesize+4 >= store_buffer->size()) { + find_frame_state=FRAME_SYNC; + store_buffer->setpos(0); + // go back to "sync for frame" + continue; + } + // don't allow stupid framesizes: + if (framesize <= 4) { + find_frame_state=FRAME_SYNC; + store_buffer->setpos(0); + continue; + } + // yup! found valid header. forward states + store_buffer->setpos(4); + back=true; + break; + } + return back; +} + + +/** + here we read data until len=framesize. + Then we go to the HAS_FRAME state. +*/ +int MpegAudioFrame::read_frame(RawDataBuffer* input_buffer, + RawDataBuffer* store_buffer) { + unsigned char* store=store_buffer->current(); + + while(input_buffer->eof()==false) { + int has=store_buffer->pos(); + int need=framesize-has; + if(need == 0) { + // yup! frame fully read. forward states. + // go to end state for main_state. + return true; + } + // try to do a memcpy for speed. + int can=input_buffer->untilend(); + if(can > need) { + can=need; + } + unsigned char* input=input_buffer->current(); + memcpy(store,input,can); + store_buffer->inc(can); + input_buffer->inc(can); + } + int need=framesize-store_buffer->pos(); + + if(need == 0) { + // yup! frame fully read. forward states. + // go to end state for main_state. + return true; + } + return false; +} + + + +void MpegAudioFrame::printPrivateStates() { + cout << "MpegAudioFrame::printPrivateStates"<<endl; + switch(find_frame_state) { + case FRAME_SYNC: + cout << "frame_state: FRAME_SYNC"<<endl; + break; + case FRAME_CHECK_HEADER_1: + cout << "frame_state: FRAME_CHECK_HEADER_1"<<endl; + break; + case FRAME_CHECK_HEADER_2: + cout << "frame_state: FRAME_CHECK_HEADER_2"<<endl; + break; + default: + cout << "unknown illegal frame_state:"<<find_frame_state<<endl; + } + + +} + diff --git a/mpeglib/lib/splay/mpegAudioFrame.h b/mpeglib/lib/splay/mpegAudioFrame.h new file mode 100644 index 00000000..8b4f6c4f --- /dev/null +++ b/mpeglib/lib/splay/mpegAudioFrame.h @@ -0,0 +1,66 @@ +/* + converts raw mpeg audio stream data into mpeg I encoded audio frames/packets + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef __MPEGAUDIOFRAME_H +#define __MPEGAUDIOFRAME_H + +#include "mpegAudioHeader.h" +#include "../frame/framer.h" +#include <kdemacros.h> + +/* + Here we are framing from raw to mpeg audio. +*/ + + + + +class KDE_EXPORT MpegAudioFrame : public Framer { + + // max size of buffer is: + // header: 4 + // max bitrate: 448 + // min freq: 22050 + // padding: 1 + // ------------------ + // maxsize: 4+144000*max(bitrate)/min(freq)+1 ca: 2931 byte + // then we add a "sentinel" at the end these are 4 byte. + // so we should be ok, with a 4KB buffer. + + // internal, how much data we need to read + int framesize; + + // internall, for header searching + int find_frame_state; + + // internal use for header parsing+validating + MpegAudioHeader* mpegAudioHeader; + + public: + MpegAudioFrame(); + ~MpegAudioFrame(); + + + private: + + int find_frame(RawDataBuffer* input,RawDataBuffer* store); + int read_frame(RawDataBuffer* input,RawDataBuffer* store); + + void unsync(RawDataBuffer* store,int lReset); + void printPrivateStates(); + +}; + + +#endif diff --git a/mpeglib/lib/splay/mpegAudioHeader.cpp b/mpeglib/lib/splay/mpegAudioHeader.cpp new file mode 100644 index 00000000..7e34b212 --- /dev/null +++ b/mpeglib/lib/splay/mpegAudioHeader.cpp @@ -0,0 +1,268 @@ +/* + stores information after we found a header. + Copyright (C) 2000 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#include "mpegAudioHeader.h" + +#define DEBUG_HEADER(x) +//#define DEBUG_HEADER(x) x + + +#include <iostream> + +using namespace std; + +static const int frequencies[3][3]= { + {44100,48000,32000}, // MPEG 1 + {22050,24000,16000}, // MPEG 2 + {11025,12000,8000} // MPEG 2.5 +}; + +static int translate[3][2][16] = { { { 2,0,0,2,2,2,3,3,3,3,3,3,3,3,3,2 } , + { 2,0,0,0,0,0,0,2,2,2,3,3,3,3,3,2 } } , + { { 2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2 } , + { 2,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2 } } , + { { 2,1,1,2,2,2,3,3,3,3,3,3,3,3,3,2 } , + { 2,1,1,1,1,1,1,2,2,2,3,3,3,3,3,2 } } }; + + +static int sblims[5] = { 8 , 12 , 27, 30 , 30 }; + + +static const int bitrate[2][3][15]= { + // MPEG 1 + {{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448}, + {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384}, + {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320}}, + + // MPEG 2 + {{0,32,48,56,64,80,96,112,128,144,160,176,192,224,256}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160}} +}; + + +MpegAudioHeader::MpegAudioHeader() { + +} + + +MpegAudioHeader::~MpegAudioHeader() { +} + + +int MpegAudioHeader::getChannelbitrate() { + cout << "getChannelbitrate not implemented"<<endl; + return 0; +} + +int MpegAudioHeader::parseHeader(unsigned char* buf){ + + int c; + int mpeg25=false; + + + // Analyzing + header[0]=buf[0]; + header[1]=buf[1]; + header[2]=buf[2]; + header[3]=buf[3]; + + c=buf[1]; + lmpeg25=false; + if ( (c&0xf0) == 0xe0) { + lmpeg25=true; + } + + c&=0xf; + protection=c&1; + layer=4-((c>>1)&3); + // we catch the layer==4 error later, for now go on with parsing + version=(int)(((c>>3)&1)^1); + if ((version==0) && lmpeg25) { + DEBUG_HEADER(cout << "wrong lsf/mpeg25 combination"<<endl;) + return false; + } + c=buf[2]; + + c=((c))>>1; + padding=(c&1); + c>>=1; + frequency=(int)(c&3); + c>>=2; + bitrateindex=(int)c; + if(bitrateindex>=15) { + DEBUG_HEADER(cout << "bitrateindex error"<<endl;) + return false; + } + c=buf[3]; + + c=((unsigned int)(c))>>4; + extendedmode=c&3; + mode=(int)(c>>2); + + + // Making information + inputstereo= (mode==_MODE_SINGLE)?0:1; + + // + // frequency can be 0,1 or 2 but the mask above allows 3 as well + // check now. + if (frequency > 2) { + DEBUG_HEADER(cout << "frequency value out of range"<<endl;) + return false; + } + + // + // does not belong here should be in the layer specific parts. [START] + // + + switch(layer) { + case 3: + subbandnumber=0; + stereobound=0; + tableindex=0; + break; + case 2: + tableindex = translate[frequency][inputstereo][bitrateindex]; + subbandnumber = sblims[tableindex]; + stereobound = subbandnumber; + /* + Now merge the tableindex, for the bitalloclengthtable + */ + tableindex=tableindex>>1; + if(mode==_MODE_SINGLE)stereobound=0; + if(mode==_MODE_JOINT)stereobound=(extendedmode+1)<<2; + + break; + case 1: + subbandnumber=MAXSUBBAND; + stereobound=subbandnumber; + tableindex=0; + if(mode==_MODE_SINGLE)stereobound=0; + if(mode==_MODE_JOINT)stereobound=(extendedmode+1)<<2; + break; + default: + DEBUG_HEADER(cout <<"unknown layer"<<endl;) + return false; + } + + // + // does not belong here should be in the layer specific parts. [END] + // + frequencyHz=frequencies[version+lmpeg25][frequency]; + // framesize & slots + if(layer==1) { + if (frequencyHz <= 0) { + return false; + } + framesize=(12000*bitrate[version][0][bitrateindex])/frequencyHz; + + if(frequency==_FREQUENCY_44100 && padding)framesize++; + framesize<<=2; + } else { + int freq=frequencyHz<<version; + if (freq <= 0) { + return false; + } + framesize=(144000*bitrate[version][layer-1][bitrateindex])/freq; + + if(padding)framesize++; + if(layer==3) { + if(version) + layer3slots=framesize-((mode==_MODE_SINGLE)?9:17) + -(protection?0:2) + -4; + else + layer3slots=framesize-((mode==_MODE_SINGLE)?17:32) + -(protection?0:2) + -4; + } + } + if (framesize <= 0) { + DEBUG_HEADER(cout << "framesize negative"<<endl;) + return false; + } + return true; + +} + + +int MpegAudioHeader::getpcmperframe() { + int s; + + s=32; + if(layer==3) { + s*=18; + if(version==0)s*=2; + } + else { + s*=SCALEBLOCK; + if(layer==2)s*=3; + } + + return s; +} + + +void MpegAudioHeader::copyTo(MpegAudioHeader* dest) { + dest->protection=protection; + dest->layer=layer; + dest->version=version; + dest->padding=padding; + dest->frequency=frequency; + dest->frequencyHz=frequencyHz; + dest->bitrateindex=bitrateindex; + dest->extendedmode=extendedmode; + dest->mode=mode; + dest->inputstereo=inputstereo; + dest->channelbitrate=channelbitrate; + dest->tableindex=tableindex; + dest->subbandnumber=subbandnumber; + dest->stereobound=stereobound; + dest->framesize=framesize; + dest->layer3slots=layer3slots; + dest->lmpeg25=lmpeg25; +} + + +void MpegAudioHeader::print(const char* name) { + cout << "MpegAudioHeader [START]:"<<name<<endl; + printf("header:%1x%1x%1x%1x\n",header[0],header[1],header[2],header[3]); + cout << "getProtection:"<<getProtection()<<endl; + cout << "getLayer:"<<getLayer()<<endl; + cout << "getVersion:"<<getVersion()<<endl; + cout << "getPadding:"<<getPadding()<<endl; + cout << "getFrequency:"<<getFrequency()<<endl; + cout << "getFrequencyHz:"<<getFrequencyHz()<<endl; + cout << "getBitrateindex:"<<getBitrateindex()<<endl; + cout << "getExtendedmode:"<<getExtendedmode()<<endl; + cout << "getMode():"<<getMode()<<endl; + cout << "getInputstereo:"<<getInputstereo()<<endl; + cout << "getChannelbitrate:"<<getChannelbitrate()<<endl; + cout << "getTableindex:"<<getTableindex()<<endl; + cout << "getSubbandnumber:"<<getSubbandnumber()<<endl; + cout << "getStereobound:"<<getStereobound()<<endl; + cout << "getFramesize:"<<getFramesize()<<endl; + cout << "getLayer3slots:"<<getLayer3slots()<<endl; + cout << "getpcmperframe:"<<getpcmperframe()<<endl; + cout << "MpegAudioHeader [END]:"<<name<<endl; + +} + + + + + + + diff --git a/mpeglib/lib/splay/mpegAudioHeader.h b/mpeglib/lib/splay/mpegAudioHeader.h new file mode 100644 index 00000000..ff5b885a --- /dev/null +++ b/mpeglib/lib/splay/mpegAudioHeader.h @@ -0,0 +1,101 @@ +/* + stores information after we found a header. + Copyright (C) 2000 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef __MPEGHEADERINFO_H +#define __MPEGHEADERINFO_H + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define _FREQUENCY_44100 0 +#define _FREQUENCY_48000 1 +#define _FREQUENCY_32000 2 + +#define _MODE_FULLSTEREO 0 +#define _MODE_JOINT 1 +#define _MODE_DUAL 2 +#define _MODE_SINGLE 3 + +#define _VERSION_1 0 +#define _VERSION_2 1 + + +#define MAXSUBBAND 32 +#define SCALEBLOCK 12 + + + +class MpegAudioHeader { + + int protection; + int layer; + int version; + int padding; + int frequency; + int frequencyHz; + int bitrateindex; + int extendedmode; + int mode; + int inputstereo; + int channelbitrate; + int tableindex; + int subbandnumber; + int stereobound; + int framesize; + int layer3slots; + int lmpeg25; + unsigned char header[4]; + + public: + MpegAudioHeader(); + ~MpegAudioHeader(); + + int parseHeader(unsigned char* buf); + + inline int getProtection() { return protection; } + inline int getLayer() { return layer; } + inline int getVersion() { return version; } + inline int getPadding() { return padding; } + inline int getFrequency() { return frequency; } + inline int getFrequencyHz() { return frequencyHz; } + inline int getBitrateindex() { return bitrateindex; } + inline int getExtendedmode() { return extendedmode; } + inline int getMode() { return mode; } + inline int getInputstereo() { return inputstereo; } + inline int getFramesize() { return framesize; } + inline int getLayer25() { return lmpeg25; } + + // MPEG layer 2 + inline int getTableindex() { return tableindex; } + // MPEG layer 1/2 + inline int getSubbandnumber() { return subbandnumber; } + inline int getStereobound() { return stereobound; } + // MPEG layer 3 + inline int getLayer3slots() { return layer3slots; } + + int getChannelbitrate(); + + + inline unsigned char* getHeader() { return header; } + int getpcmperframe(); + + + void copyTo(MpegAudioHeader* dest); + + void print(const char* name); + void printStates(const char* name); +}; +#endif diff --git a/mpeglib/lib/splay/mpegAudioInfo.cpp b/mpeglib/lib/splay/mpegAudioInfo.cpp new file mode 100644 index 00000000..981b5bd6 --- /dev/null +++ b/mpeglib/lib/splay/mpegAudioInfo.cpp @@ -0,0 +1,262 @@ +/* + length detection etc.. for mpeg audio + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + +#ifndef _FROM_SOURCE +#define _FROM_SOURCE 1 +#endif +#include "dxHead.h" +#include <string.h> +#include "mpegAudioInfo.h" +#include "mpegAudioHeader.h" +#include "mpegAudioStream.h" +#include "mpegAudioFrame.h" + +#include <iostream> + +using namespace std; + +#define _NEED_LENGTH 1 +#define _NEED_ID3 2 +#define _NEED_NOTHING 3 + + +MpegAudioInfo::MpegAudioInfo(FileAccess* input) { + xHeadData=new XHEADDATA(); + xHeadData->toc=new unsigned char[101]; + lXingVBR=false; + id3=new ID3TAG(); + this->input=input; + mpegAudioFrame =new MpegAudioFrame(); + mpegAudioStream=new MpegAudioStream(); + mpegAudioHeader=new MpegAudioHeader(); + reset(); +} + + +MpegAudioInfo::~MpegAudioInfo() { + delete[] (xHeadData->toc); + delete xHeadData; + delete id3; + delete mpegAudioStream; + delete mpegAudioHeader; + delete mpegAudioFrame; +} + + +int MpegAudioInfo::getByteDirect() { + unsigned char byte; + if (input->read((char*)&byte,1) != 1) { + leof=true; + return -1; + } + return (int)byte; +} + +void MpegAudioInfo::reset() { + length=0; + initState=_NEED_LENGTH; + lNeedInit=true; +} + + +int MpegAudioInfo::getNeedInit() { + return lNeedInit; +} + +void MpegAudioInfo::setNeedInit(int lNeedInit) { + this->lNeedInit=lNeedInit; +} + + +int MpegAudioInfo::initialize() { + long fileSize=input->getByteLength(); + switch(initState) { + case _NEED_NOTHING: + return true; + break; + case _NEED_LENGTH: + if (initializeLength(fileSize) == true) { + initState=_NEED_ID3; + } + return false; + case _NEED_ID3: + if (initializeID3(fileSize) == true) { + initState=_NEED_NOTHING; + return true; + } + return false; + default: + cout << "unknown initState in MpegAudioInfo::initialize"<<endl; + exit(0); + } + // never happens + return true; +} + + +int MpegAudioInfo::initializeLength(long fileSize) { + // if we are streaming don't touch the stream for length detection + if (fileSize == 0) { + return true; + } + int back=getFrame(mpegAudioFrame); + if (back != true) { + return back; + } + // found a valid frame (back == true) + // store information in header. + if (mpegAudioHeader->parseHeader(mpegAudioFrame->outdata()) == false) { + cout << "parse header false"<<endl; + return false; + } + calculateLength(fileSize); + return back; +} + +int MpegAudioInfo::initializeID3(long fileSize) { + int pos=input->getBytePosition(); + if (input->seek(fileSize-128)<0) { + return true; + } + parseID3(); + input->seek(pos); + return true; +} + + +long MpegAudioInfo::getLength() { + return length; +} + + +void MpegAudioInfo::calculateLength(long fileSize) { + + int totalframe=0; + int framesize=mpegAudioHeader->getFramesize(); + if (framesize > 0) { + totalframe=fileSize/framesize; + + if (parseXing(mpegAudioFrame->outdata(),mpegAudioFrame->len()) == true) { + lXingVBR=true; + totalframe=xHeadData->frames; + } + } + + float pcm=mpegAudioHeader->getpcmperframe(); + float wavfilesize=(totalframe*pcm); + float frequence=(float)mpegAudioHeader->getFrequencyHz(); + length=0; + if (frequence != 0) { + length=(int)(wavfilesize/frequence); + } +} + + +int MpegAudioInfo::parseXing(unsigned char* frame,int size) { + + int back=false; + if (size < 152) { + return false; + } + back=GetXingHeader(xHeadData,(unsigned char*)frame); + return back; + +} + + + +long MpegAudioInfo::getSeekPosition(int second) { + float length=getLength(); + long fileSize=input->getByteLength(); + long pos=0; + if (length<1.0) { + return 0; + } + float percent=(float)second/length; + + if (lXingVBR) { + pos=SeekPoint(xHeadData->toc,(int)fileSize,100.0*percent); + return pos; + } + pos=(long)(percent*(float)fileSize); + return pos; +} + + +void MpegAudioInfo::parseID3() { + + id3->name [0]=0; + id3->artist [0]=0; + id3->album [0]=0; + id3->year [0]=0; + id3->comment [0]=0; + id3->genre =0; + + leof=false; + + while(leof == false) { + if(getByteDirect()==0x54) + if(getByteDirect()==0x41) + if(getByteDirect()==0x47) { + input->read((char*)&id3->name ,30);id3->name[30]=0; + input->read((char*)&id3->artist ,30);id3->artist[30]=0; + input->read((char*)&id3->album ,30);id3->album[30]=0; + input->read((char*)&id3->year , 4);id3->year[4]=0; + input->read((char*)&id3->comment ,30);id3->comment[30]=0; + input->read((char*)&id3->genre ,1); + return; + } + } +} + + + +void MpegAudioInfo::print(const char* msg) { + cout << "MpegAudioInfo:"<<msg<<endl; + cout << "Length (sec):"<<length<<endl; + cout << "VBR:"<<lXingVBR<<endl; + cout << "ID3: Name:"<<id3->name<<endl; + cout << "ID3: Artist:"<<id3->artist<<endl; + cout << "ID3: Album:"<<id3->album<<endl; + cout << "ID3: year:"<<id3->year<<endl; + cout << "ID3: genre:"<<(int)(id3->genre)<<endl; + cout << "ID3: comment:"<<id3->comment<<endl; + +} + + +int MpegAudioInfo::getFrame(MpegAudioFrame* frame) { + int state=frame->getState(); + switch(state) { + case FRAME_NEED: { + int bytes=frame->canStore(); + int read=input->read((char*)inputbuffer,bytes); + if (read <= 0) { + // read error. reset framer + frame->reset(); + break; + } + frame->store(inputbuffer,bytes); + break; + } + case FRAME_WORK: + frame->work(); + break; + case FRAME_HAS: + return true; + break; + default: + cout << "unknown state in mpeg audio framing"<<endl; + exit(0); + } + return false; +} diff --git a/mpeglib/lib/splay/mpegAudioInfo.h b/mpeglib/lib/splay/mpegAudioInfo.h new file mode 100644 index 00000000..65298ca6 --- /dev/null +++ b/mpeglib/lib/splay/mpegAudioInfo.h @@ -0,0 +1,95 @@ +/* + length detection etc.. for mpeg audio + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + +#ifndef __MPEGAUDIOINFO_H +#define __MPEGAUDIOINFO_H + +#include "../util/file/fileAccess.h" + +class MpegAudioStream; +class MpegAudioHeader; +class MpegAudioFrame; + +typedef struct { + char name [30+1]; + char artist [30+1]; + char album [30+1]; + char year [ 4+1]; + char comment[30+1]; + unsigned char genre; +} ID3TAG; + + +class MpegAudioInfo { + + long length; + int lXingVBR; + ID3TAG* id3; + MpegAudioStream* mpegAudioStream; + MpegAudioHeader* mpegAudioHeader; + MpegAudioFrame * mpegAudioFrame; + FileAccess* input; + int leof; + + int initState; + unsigned char inputbuffer[8192]; + int lNeedInit; + public: + MpegAudioInfo(FileAccess* input); + ~MpegAudioInfo(); + + void reset(); + int initialize(); + + // store info wheter init need or not here.(after reset its true) + int getNeedInit(); + void setNeedInit(int lNeedInit); + + + // returns byte positions + long getSeekPosition(int second); + // returns length in seconds + long getLength(); + + // for id3 parsing you need to seek -128 bytes before the end of strem + // after parseID3 you must jump back to 0. This method is blocking + int initializeID3(); + ID3TAG* getID3(); + + void print(const char* msg); + + private: + // non-blocking init. return true,false,or -1==eof + int initializeLength(long fileSize); + int initializeID3(long fileSize); + + + + void calculateLength(long fileSize); + int parseXing(unsigned char* frame,int size); + + // used for seek + void parseID3(); + int getByteDirect(); + + // extension for xing vbr +#ifdef _FROM_SOURCE + XHEADDATA* xHeadData; +#else + void* xHeadData; +#endif + + private: + int getFrame(MpegAudioFrame* frame); + +}; +#endif diff --git a/mpeglib/lib/splay/mpegAudioStream.cpp b/mpeglib/lib/splay/mpegAudioStream.cpp new file mode 100644 index 00000000..b3061224 --- /dev/null +++ b/mpeglib/lib/splay/mpegAudioStream.cpp @@ -0,0 +1,43 @@ +/* + initializer/resyncer/frame detection etc.. for mpeg audio + Copyright (C) 2000 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#include "mpegAudioStream.h" + +#include <stdlib.h> + +MpegAudioStream::MpegAudioStream() { + buffer=NULL; +} + + +MpegAudioStream::~MpegAudioStream() { +} + + + +void MpegAudioStream::setFrame(unsigned char* ptr,int len) { + this->buffer=(char*)ptr; + this->len=len; + bitindex=0; +} + + + + + + + + + + diff --git a/mpeglib/lib/splay/mpegAudioStream.h b/mpeglib/lib/splay/mpegAudioStream.h new file mode 100644 index 00000000..9e4accc3 --- /dev/null +++ b/mpeglib/lib/splay/mpegAudioStream.h @@ -0,0 +1,139 @@ +/* + initializer/resyncer/frame detection etc.. for mpeg audio + Copyright (C) 2000 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef __MPEGAUDIOSTREAM_H +#define __MPEGAUDIOSTREAM_H + +// we include this for the big_endian define + +#include "mpegAudioBitWindow.h" + +#define _MAX_MPEG_BUFFERSIZE 4096 + + +/** + Here we go from the frame to the bitlevel. + + +*/ + +class MpegAudioStream { + + char* buffer; + int len; + int bitindex; + + public: + MpegAudioStream(); + ~MpegAudioStream(); + + void setFrame(unsigned char* prt,int len); + + // Bit functions + + inline char* getBuffer() { return buffer; } + inline int getBufferSize() { return _MAX_MPEG_BUFFERSIZE ;} + inline void sync() { bitindex=(bitindex+7)&0xFFFFFFF8; } + inline int issync() { return (bitindex&7);}; + + /** + Now follow ugly inline function. The performance gain is 1.5 % + on a 400 MHz AMD + */ + + inline int getbyte() { + int r=(unsigned char)buffer[bitindex>>3]; + bitindex+=8; + return r; + } + + inline int getbits9(int bits) { + register unsigned short a; + { + int offset=bitindex>>3; + + a=(((unsigned char)buffer[offset])<<8) | + ((unsigned char)buffer[offset+1]); + } + + a<<=(bitindex&7); + bitindex+=bits; + return (int)((unsigned int)(a>>(16-bits))); + } + + inline int getbits8() { + register unsigned short a; + + { + int offset=bitindex>>3; + + a=(((unsigned char)buffer[offset])<<8) | + ((unsigned char)buffer[offset+1]); + } + + a<<=(bitindex&7); + bitindex+=8; + return (int)((unsigned int)(a>>8)); + } + + inline int getbit() { + register int r=(buffer[bitindex>>3]>>(7-(bitindex&7)))&1; + + bitindex++; + return r; + } + + inline int getbits(int bits) { + union + { + char store[4]; + int current; + }u; + int bi; + + if(!bits)return 0; + + u.current=0; + bi=(bitindex&7); + u.store[_KEY]=buffer[bitindex>>3]<<bi; + bi=8-bi; + bitindex+=bi; + + while(bits) { + if(!bi) { + u.store[_KEY]=buffer[bitindex>>3]; + bitindex+=8; + bi=8; + } + if(bits>=bi) { + u.current<<=bi; + bits-=bi; + bi=0; + } else { + u.current<<=bits; + bi-=bits; + bits=0; + } + } + bitindex-=bi; + return (u.current>>8); + } + + + + +}; + + +#endif diff --git a/mpeglib/lib/splay/mpeglayer1.cpp b/mpeglib/lib/splay/mpeglayer1.cpp new file mode 100644 index 00000000..a32951c4 --- /dev/null +++ b/mpeglib/lib/splay/mpeglayer1.cpp @@ -0,0 +1,109 @@ +/* MPEG/WAVE Sound library + + (C) 1997 by Jung woo-jae */ + +// Mpeglayer1.cc +// It's for MPEG Layer 1 + + + +#include "mpegsound.h" +#include "synthesis.h" + +// Tables for layer 1 +static const REAL factortable[15] = +{ + 0.0, + (1.0/2.0) * (4.0/3.0), (1.0/4.0) * (8.0/7.0), + (1.0/8.0) * (16.0/15.0), (1.0/16.0) * (32.0/31.0), + (1.0/32.0) * (64.0/63.0), (1.0/64.0) * (128.0/127.0), + (1.0/128.0) * (256.0/255.0), (1.0/256.0) * (512.0/511.0), + (1.0/512.0) * (1024.0/1023.0), (1.0/1024.0) * (2048.0/2047.0), + (1.0/2048.0) * (4096.0/4095.0), (1.0/4096.0) * (8192.0/8191.0), + (1.0/8192.0) * (16384.0/16383.0), (1.0/16384.0) * (32768.0/32767.0) +}; + +static const REAL offsettable[15] = +{ + 0.0, + ((1.0/2.0)-1.0) * (4.0/3.0), ((1.0/4.0)-1.0) * (8.0/7.0), + ((1.0/8.0)-1.0) * (16.0/15.0), ((1.0/16.0)-1.0) * (32.0/31.0), + ((1.0/32.0)-1.0) * (64.0/63.0), ((1.0/64.0)-1.0) * (128.0/127.0), + ((1.0/128.0)-1.0) * (256.0/255.0), ((1.0/256.0)-1.0) * (512.0/511.0), + ((1.0/512.0)-1.0) * (1024.0/1023.0), ((1.0/1024.0)-1.0) * (2048.0/2047.0), + ((1.0/2048.0)-1.0) * (4096.0/4095.0), ((1.0/4096.0)-1.0) * (8192.0/8191.0), + ((1.0/8192.0)-1.0) * (16384.0/16383.0), ((1.0/16384.0)-1.0) * (32768.0/32767.0) +}; + +// Mpeg layer 1 +void Mpegtoraw::extractlayer1(void) +{ + int inputstereo=mpegAudioHeader->getInputstereo(); + int stereobound=mpegAudioHeader->getStereobound(); + REAL fraction[MAXCHANNEL][MAXSUBBAND]; + REAL scalefactor[MAXCHANNEL][MAXSUBBAND]; + + int bitalloc[MAXCHANNEL][MAXSUBBAND], + sample[MAXCHANNEL][MAXSUBBAND]; + + register int i,j; + int s=stereobound,l; + + +// Bitalloc + for(i=0;i<s;i++) + { + bitalloc[LS][i]=getbits(4); + bitalloc[RS][i]=getbits(4); + } + for(;i<MAXSUBBAND;i++) + bitalloc[LS][i]= + bitalloc[RS][i]=getbits(4); + +// Scale index + if(inputstereo) + for(i=0;i<MAXSUBBAND;i++) + { + if(bitalloc[LS][i])scalefactor[LS][i]=scalefactorstable[getbits(6)]; + if(bitalloc[RS][i])scalefactor[RS][i]=scalefactorstable[getbits(6)]; + } + else + for(i=0;i<MAXSUBBAND;i++) + if(bitalloc[LS][i])scalefactor[LS][i]=scalefactorstable[getbits(6)]; + + for(l=0;l<SCALEBLOCK;l++) + { + // Sample + for(i=0;i<s;i++) + { + if((j=bitalloc[LS][i]))sample[LS][i]=getbits(j+1); + if((j=bitalloc[RS][i]))sample[RS][i]=getbits(j+1); + } + for(;i<MAXSUBBAND;i++) + if((j=bitalloc[LS][i]))sample[LS][i]=sample[RS][i]=getbits(j+1); + + + // Fraction + if(lOutputStereo) + for(i=0;i<MAXSUBBAND;i++) + { + if((j=bitalloc[LS][i])) + fraction[LS][i]=(REAL(sample[LS][i])*factortable[j]+offsettable[j]) + *scalefactor[LS][i]; + else fraction[LS][i]=0.0; + if((j=bitalloc[RS][i])) + fraction[RS][i]=(REAL(sample[RS][i])*factortable[j]+offsettable[j]) + *scalefactor[RS][i]; + else fraction[RS][i]=0.0; + } + else + for(i=0;i<MAXSUBBAND;i++) + if((j=bitalloc[LS][i])) + fraction[LS][i]=(REAL(sample[LS][i])*factortable[j]+offsettable[j]) + *scalefactor[LS][i]; + else fraction[LS][i]=0.0; + + synthesis->doSynth(lDownSample,lOutputStereo, + fraction[LS],fraction[RS]); + } +} diff --git a/mpeglib/lib/splay/mpeglayer2.cpp b/mpeglib/lib/splay/mpeglayer2.cpp new file mode 100644 index 00000000..4012ff27 --- /dev/null +++ b/mpeglib/lib/splay/mpeglayer2.cpp @@ -0,0 +1,449 @@ +/* MPEG/WAVE Sound library + + (C) 1997 by Jung woo-jae */ + +// Mpeglayer2.cc +// It's for MPEG Layer 2 + + +#include "mpegsound.h" +#include "synthesis.h" + +#include <iostream> + +using namespace std; + +#define BUGFIX +#include "mpeg2tables.h" + + +// workaround for buggy mpeg2 streams. +// tested with 12 monkey cdi, worgked fine. +// problem was: the stream produced ints +// with access out of the tables +// if we have such an access we set it to a zero entry +#ifdef BUGFIX +static int checkCodeRange(int code,const REAL* group) { + int back=0; + if (group == NULL) { + cout << "group null"<<endl; + return 0; + } + back=code; + + if (group == group5bits) { + if (back > 27*3) { + // redirect to zero value + back=3; + } + return back; + } + if (group == group7bits) { + if (back > 125*3) { + back=6; + } + return back; + } + if (group == group10bits) { + if (back > 729*3) { + back=12; + } + return back; + } + DEBUG_LAYER(cout << "unknown group found!"<<endl;) + return -1; +} + + +#endif + + + + + + + + +// Mpeg layer 2 +void Mpegtoraw::extractlayer2(void) { + int inputstereo=mpegAudioHeader->getInputstereo(); + int tableindex=mpegAudioHeader->getTableindex(); + int subbandnumber=mpegAudioHeader->getSubbandnumber(); + int stereobound=mpegAudioHeader->getStereobound(); + + REAL fraction[MAXCHANNEL][3][MAXSUBBAND]; + unsigned int bitalloc[MAXCHANNEL][MAXSUBBAND], + scaleselector[MAXCHANNEL][MAXSUBBAND]; + REAL scalefactor[2][3][MAXSUBBAND]; + + const REAL *group[MAXCHANNEL][MAXSUBBAND]; + unsigned int codelength[MAXCHANNEL][MAXSUBBAND]; + REAL factor[MAXCHANNEL][MAXSUBBAND]; + REAL c[MAXCHANNEL][MAXSUBBAND],d[MAXCHANNEL][MAXSUBBAND]; + + int s=stereobound,n=subbandnumber; + + + // Bitalloc + { + register int i; + register const int *t=bitalloclengthtable[tableindex]; + for(i=0;i<s;i++,t++) + { + bitalloc[LS][i]=getbits(*t); + bitalloc[RS][i]=getbits(*t); + } + for(;i<n;i++,t++) { + bitalloc[LS][i]=bitalloc[RS][i]=getbits(*t); + } + } + + + + // Scale selector + if(inputstereo) + for(register int i=0;i<n;i++) + { + if(bitalloc[LS][i])scaleselector[LS][i]=getbits(2); + if(bitalloc[RS][i])scaleselector[RS][i]=getbits(2); + } + else + for(register int i=0;i<n;i++) + if(bitalloc[LS][i])scaleselector[LS][i]=getbits(2); + + // Scale index + { + register int i,j; + + + for(i=0;i<n;i++) + { + if((j=bitalloc[LS][i])) + { + if(!tableindex) + { + group[LS][i]=grouptableA[j]; + codelength[LS][i]=codelengthtableA[j]; + factor[LS][i]=factortableA[j]; + c[LS][i]=ctableA[j]; + d[LS][i]=dtableA[j]; + } + else + { + if(i<=2) + { + group[LS][i]=grouptableB1[j]; + codelength[LS][i]=codelengthtableB1[j]; + factor[LS][i]=factortableB1[j]; + c[LS][i]=ctableB1[j]; + d[LS][i]=dtableB1[j]; + } + else + { + group[LS][i]=grouptableB234[j]; + if(i<=10) + { + codelength[LS][i]=codelengthtableB2[j]; + factor[LS][i]=factortableB2[j]; + c[LS][i]=ctableB2[j]; + d[LS][i]=dtableB2[j]; + } + else if(i<=22) + { + codelength[LS][i]=codelengthtableB3[j]; + factor[LS][i]=factortableB3[j]; + c[LS][i]=ctableB3[j]; + d[LS][i]=dtableB3[j]; + } + else + { + codelength[LS][i]=codelengthtableB4[j]; + factor[LS][i]=factortableB4[j]; + c[LS][i]=ctableB4[j]; + d[LS][i]=dtableB4[j]; + } + } + } + + + switch(scaleselector[LS][i]) + { + case 0:scalefactor[LS][0][i]=scalefactorstable[getbits(6)]; + scalefactor[LS][1][i]=scalefactorstable[getbits(6)]; + scalefactor[LS][2][i]=scalefactorstable[getbits(6)]; + break; + case 1:scalefactor[LS][0][i]= + scalefactor[LS][1][i]=scalefactorstable[getbits(6)]; + scalefactor[LS][2][i]=scalefactorstable[getbits(6)]; + break; + case 2:scalefactor[LS][0][i]= + scalefactor[LS][1][i]= + scalefactor[LS][2][i]=scalefactorstable[getbits(6)]; + break; + case 3:scalefactor[LS][0][i]=scalefactorstable[getbits(6)]; + scalefactor[LS][1][i]= + scalefactor[LS][2][i]=scalefactorstable[getbits(6)]; + break; + default: + cout << "scaleselector left default never happens"<<endl; + break; + } + } + + + if(inputstereo && (j=bitalloc[RS][i])) + { + if(!tableindex) + { + group[RS][i]=grouptableA[j]; + codelength[RS][i]=codelengthtableA[j]; + factor[RS][i]=factortableA[j]; + c[RS][i]=ctableA[j]; + d[RS][i]=dtableA[j]; + } + else + { + if(i<=2) + { + group[RS][i]=grouptableB1[j]; + codelength[RS][i]=codelengthtableB1[j]; + factor[RS][i]=factortableB1[j]; + c[RS][i]=ctableB1[j]; + d[RS][i]=dtableB1[j]; + } + else + { + group[RS][i]=grouptableB234[j]; + if(i<=10) + { + codelength[RS][i]=codelengthtableB2[j]; + factor[RS][i]=factortableB2[j]; + c[RS][i]=ctableB2[j]; + d[RS][i]=dtableB2[j]; + } + else if(i<=22) + { + codelength[RS][i]=codelengthtableB3[j]; + factor[RS][i]=factortableB3[j]; + c[RS][i]=ctableB3[j]; + d[RS][i]=dtableB3[j]; + } + else + { + codelength[RS][i]=codelengthtableB4[j]; + factor[RS][i]=factortableB4[j]; + c[RS][i]=ctableB4[j]; + d[RS][i]=dtableB4[j]; + } + } + } + + + switch(scaleselector[RS][i]) + { + case 0 : scalefactor[RS][0][i]=scalefactorstable[getbits(6)]; + scalefactor[RS][1][i]=scalefactorstable[getbits(6)]; + scalefactor[RS][2][i]=scalefactorstable[getbits(6)]; + break; + case 1 : scalefactor[RS][0][i]= + scalefactor[RS][1][i]=scalefactorstable[getbits(6)]; + scalefactor[RS][2][i]=scalefactorstable[getbits(6)]; + break; + case 2 : scalefactor[RS][0][i]= + scalefactor[RS][1][i]= + scalefactor[RS][2][i]=scalefactorstable[getbits(6)]; + break; + case 3 : scalefactor[RS][0][i]=scalefactorstable[getbits(6)]; + scalefactor[RS][1][i]= + scalefactor[RS][2][i]=scalefactorstable[getbits(6)]; + break; + default: + cout << "scaleselector right default never happens"<<endl; + break; + } + + + } + } + } + + + +// Read Sample + { + register int i; + + for(int l=0;l<SCALEBLOCK;l++) + { + // Read Sample + for(i=0;i<s;i++) + { + if(bitalloc[LS][i]) + { + if(group[LS][i]) + { + register const REAL *s; + int code=getbits(codelength[LS][i]); + + + + code+=code<<1; +#ifdef BUGFIX + // bugfix for bad streams + code=checkCodeRange(code,group[LS][i]); + if (code == -1) return; +#endif + s=group[LS][i]+code; + + fraction[LS][0][i]=s[0]; + fraction[LS][1][i]=s[1]; + fraction[LS][2][i]=s[2]; + } + else + { + fraction[LS][0][i]= + REAL(getbits(codelength[LS][i]))*factor[LS][i]-1.0; + fraction[LS][1][i]= + REAL(getbits(codelength[LS][i]))*factor[LS][i]-1.0; + fraction[LS][2][i]= + REAL(getbits(codelength[LS][i]))*factor[LS][i]-1.0; + } + } + else fraction[LS][0][i]=fraction[LS][1][i]=fraction[LS][2][i]=0.0; + + + if(inputstereo && bitalloc[RS][i]) + { + if(group[RS][i]) + { + const REAL *s; + int code=getbits(codelength[RS][i]); + + code+=code<<1; +#ifdef BUGFIX + // bugfix for bad streams + code=checkCodeRange(code,group[RS][i]); + if (code == -1) return; +#endif + s=group[RS][i]+code; + + fraction[RS][0][i]=s[0]; + fraction[RS][1][i]=s[1]; + fraction[RS][2][i]=s[2]; + } + else + { + fraction[RS][0][i]= + REAL(getbits(codelength[RS][i]))*factor[RS][i]-1.0; + fraction[RS][1][i]= + REAL(getbits(codelength[RS][i]))*factor[RS][i]-1.0; + fraction[RS][2][i]= + REAL(getbits(codelength[RS][i]))*factor[RS][i]-1.0; + } + } + else fraction[RS][0][i]=fraction[RS][1][i]=fraction[RS][2][i]=0.0; + } + + + for(;i<n;i++) + { + if(bitalloc[LS][i]) + { + if(group[LS][i]) + { + register const REAL *s; + int code=getbits(codelength[LS][i]); + + code+=code<<1; +#ifdef BUGFIX + // bugfix for bad streams + code=checkCodeRange(code,group[LS][i]); + if (code == -1) return; +#endif + s=group[LS][i]+code; + + fraction[LS][0][i]=fraction[RS][0][i]=s[0]; + fraction[LS][1][i]=fraction[RS][1][i]=s[1]; + fraction[LS][2][i]=fraction[RS][2][i]=s[2]; + } + else + { + fraction[LS][0][i]=fraction[RS][0][i]= + REAL(getbits(codelength[LS][i]))*factor[LS][i]-1.0; + fraction[LS][1][i]=fraction[RS][1][i]= + REAL(getbits(codelength[LS][i]))*factor[LS][i]-1.0; + fraction[LS][2][i]=fraction[RS][2][i]= + REAL(getbits(codelength[LS][i]))*factor[LS][i]-1.0; + } + } + else fraction[LS][0][i]=fraction[LS][1][i]=fraction[LS][2][i]= + fraction[RS][0][i]=fraction[RS][1][i]=fraction[RS][2][i]=0.0; + } + + + + + //Fraction + if(lOutputStereo) + for(i=0;i<n;i++) + { + if(bitalloc[LS][i]) + { + if(!group[LS][i]) + { + fraction[LS][0][i]=(fraction[LS][0][i]+d[LS][i])*c[LS][i]; + fraction[LS][1][i]=(fraction[LS][1][i]+d[LS][i])*c[LS][i]; + fraction[LS][2][i]=(fraction[LS][2][i]+d[LS][i])*c[LS][i]; + } + + register REAL t=scalefactor[LS][l>>2][i]; + fraction[LS][0][i]*=t; + fraction[LS][1][i]*=t; + fraction[LS][2][i]*=t; + } + + if(bitalloc[RS][i]) + { + if(!group[RS][i]) + { + fraction[RS][0][i]=(fraction[RS][0][i]+d[RS][i])*c[LS][i]; + fraction[RS][1][i]=(fraction[RS][1][i]+d[RS][i])*c[LS][i]; + fraction[RS][2][i]=(fraction[RS][2][i]+d[RS][i])*c[LS][i]; + } + + register REAL t=scalefactor[RS][l>>2][i]; + fraction[RS][0][i]*=t; + fraction[RS][1][i]*=t; + fraction[RS][2][i]*=t; + } + } + else + for(i=0;i<n;i++) + if(bitalloc[LS][i]) + { + if(!group[LS][i]) + { + fraction[LS][0][i]=(fraction[LS][0][i]+d[LS][i])*c[LS][i]; + fraction[LS][1][i]=(fraction[LS][1][i]+d[LS][i])*c[LS][i]; + fraction[LS][2][i]=(fraction[LS][2][i]+d[LS][i])*c[LS][i]; + } + + register REAL t=scalefactor[LS][l>>2][i]; + fraction[LS][0][i]*=t; + fraction[LS][1][i]*=t; + fraction[LS][2][i]*=t; + } + + + for(;i<MAXSUBBAND;i++) + fraction[LS][0][i]=fraction[LS][1][i]=fraction[LS][2][i]= + fraction[RS][0][i]=fraction[RS][1][i]=fraction[RS][2][i]=0.0; + + for(i=0;i<3;i++) { + synthesis->doSynth(lDownSample,lOutputStereo, + fraction[LS][i],fraction[RS][i]); + } + + } + } +} diff --git a/mpeglib/lib/splay/mpeglayer3.cpp b/mpeglib/lib/splay/mpeglayer3.cpp new file mode 100644 index 00000000..eeb09697 --- /dev/null +++ b/mpeglib/lib/splay/mpeglayer3.cpp @@ -0,0 +1,1761 @@ +/* MPEG/WAVE Sound library + + (C) 1997 by Jung woo-jae */ + +// Mpeglayer3.cc +// It's for MPEG Layer 3 +// I've made array of superior functions for speed. +// Extend TO_FOUR_THIRDS to negative. +// Bug fix : maplay 1.2+ have wrong TO_FOUR_THIRDS ranges. +// Force to mono!! +// MPEG-2 is implemented +// Speed up in fixstereo (maybe buggy) + + + +#include "mpegsound.h" +#include "huffmanlookup.h" +#include "dump.h" +#include "synthesis.h" + +inline int Mpegtoraw::wgetbit (void) {return bitwindow.getbit (); } +inline int Mpegtoraw::wgetbits9(int bits){return bitwindow.getbits9(bits);} +inline int Mpegtoraw::wgetbits (int bits){return bitwindow.getbits (bits);} +inline int Mpegtoraw::wgetCanReadBits () {return bitwindow.getCanReadBits();} + + +#define MUL3(a) (((a)<<1)+(a)) + +#define REAL0 0 + +// 576 +#define ARRAYSIZE (SBLIMIT*SSLIMIT) +#define REALSIZE (sizeof(REAL)) + + +#define MAPLAY_OPT 1 + + +#ifdef NATIVE_ASSEMBLY +inline void long_memset(void * s,unsigned int c,int count) +{ +__asm__ __volatile__( + "cld\n\t" + "rep ; stosl\n\t" + : /* no output */ + :"a" (c), "c" (count/4), "D" ((long) s) + :"cx","di","memory"); +} +#endif + +#define FOURTHIRDSTABLENUMBER (8250) +static int initializedlayer3=false; + +static REAL two_to_negative_half_pow[70]; +static REAL TO_FOUR_THIRDSTABLE[FOURTHIRDSTABLENUMBER*2]; +static REAL POW2[256]; +static REAL POW2_1[8][2][16]; +static REAL ca[8],cs[8]; + + + + +typedef struct +{ + REAL l,r; +}RATIOS; + +static RATIOS rat_1[16],rat_2[2][64]; + +void Mpegtoraw::layer3initialize(void) +{ + + int i,j,k,l; + + //maplay opt. + nonzero[0] = nonzero[1] = nonzero[2]=ARRAYSIZE; + + layer3framestart=0; + currentprevblock=0; + + for(l=0;l<2;l++) + for(i=0;i<2;i++) + for(j=0;j<SBLIMIT;j++) + for(k=0;k<SSLIMIT;k++) + prevblck[l][i][j][k]=0.0f; + + bitwindow.initialize(); + + if(initializedlayer3) { + return; + } + + + + for(i=0;i<256;i++) { + POW2[i]=(REAL)pow((double)2.0,(0.25* (double) (i-210.0))); + } + REAL *TO_FOUR_THIRDS=TO_FOUR_THIRDSTABLE+FOURTHIRDSTABLENUMBER; + + for(i=1;i<FOURTHIRDSTABLENUMBER;i++) + TO_FOUR_THIRDS[-i]= + -(TO_FOUR_THIRDS[i]=(REAL)pow((double)i,(double)4.0/3.0)); + // now set the zero value for both (otherwise it would be -0.0) + TO_FOUR_THIRDS[0]=(REAL)0; + + + for(i=0;i<8;i++) { + static double Ci[8]= {-0.6,-0.535,-0.33,-0.185, + -0.095,-0.041,-0.0142,-0.0037}; + double sq=sqrt(1.0f+Ci[i]*Ci[i]); + cs[i]=1.0f/sq; + ca[i]=Ci[i]/sq; + } + + initialize_win(); + initialize_dct12_dct36(); + for(i=0;i<70;i++) { + two_to_negative_half_pow[i]=(REAL)pow(2.0,-0.5*(double)i); + } + + + for(i=0;i<8;i++) + for(j=0;j<2;j++) + for(k=0;k<16;k++)POW2_1[i][j][k]=pow(2.0,(-2.0*i)-(0.5*(1.0+j)*k)); + + + /* + + for(i=0;i<8;i++) + for(k=0;k<16;k++) { + for(j=0;j<2;j++) { + REAL base=pow(2.0,-0.25*(j+1.0)); + REAL val=1.0; + + if (k>0) { + if ( k & 1) { + val=pow(base,(k+1.0)*0.5); + } else { + val=pow(base,k*0.5); + } + } + + POW2_MV[i][j][k]=val; + } + } + + for(i=0;i<8;i++) + for(j=0;j<2;j++) + for(k=0;k<16;k++) { + REAL a=POW2_1[i][j][k]; + REAL b=POW2_MV[i][j][k]; + printf("i:%d j%d k%d",i,j,k); + if (a != b) { + cout << "a:"<<a<<" b:"<<b<<endl; + } else { + cout << "same:"<<a<<endl; + } + } + */ + + + for(i=0;i<16;i++) { + double t = tan( (double) i * MY_PI / 12.0 ); + rat_1[i].l=t / (1.0+t); + rat_1[i].r=1.0 /(1.0+t); + } + + +#define IO0 ((double)0.840896415256) +#define IO1 ((double)0.707106781188) + rat_2[0][0].l=rat_2[0][0].r= + rat_2[1][0].l=rat_2[1][0].r=1.; + + for(i=1;i<64;i++) { + if((i%2)==1) { + rat_2[0][i].l=pow(IO0,(i+1)/2); + rat_2[1][i].l=pow(IO1,(i+1)/2); + rat_2[0][i].r= + rat_2[1][i].r=1.; + } + else { + rat_2[0][i].l= + rat_2[1][i].l=1.; + rat_2[0][i].r=pow(IO0,i/2); + rat_2[1][i].r=pow(IO1,i/2); + } + } + + initializedlayer3=true; +} + +bool Mpegtoraw::layer3getsideinfo(void) { + int inputstereo=mpegAudioHeader->getInputstereo(); + + + sideinfo.main_data_begin=getbits(9); + if(!inputstereo)sideinfo.private_bits=getbits(5); + else sideinfo.private_bits=getbits(3); + + sideinfo.ch[LS].scfsi[0]=getbit(); + sideinfo.ch[LS].scfsi[1]=getbit(); + sideinfo.ch[LS].scfsi[2]=getbit(); + sideinfo.ch[LS].scfsi[3]=getbit(); + if(inputstereo) { + sideinfo.ch[RS].scfsi[0]=getbit(); + sideinfo.ch[RS].scfsi[1]=getbit(); + sideinfo.ch[RS].scfsi[2]=getbit(); + sideinfo.ch[RS].scfsi[3]=getbit(); + } + + for(int gr=0,ch;gr<2;gr++) + for(ch=0;;ch++) { + layer3grinfo *gi=&(sideinfo.ch[ch].gr[gr]); + + gi->part2_3_length =getbits(12); + gi->big_values =getbits(9); + if(gi->big_values > 288) { + DEBUG_LAYER(fprintf(stderr,"big_values too large!\n");) + gi->big_values = 288; + return false; + } + + gi->global_gain =getbits(8); + gi->scalefac_compress =getbits(4); + gi->window_switching_flag=getbit(); + if(gi->window_switching_flag) { + gi->block_type =getbits(2); + gi->mixed_block_flag=getbit(); + + gi->table_select[0] =getbits(5); + gi->table_select[1] =getbits(5); + + gi->subblock_gain[0]=getbits(3); + gi->subblock_gain[1]=getbits(3); + gi->subblock_gain[2]=getbits(3); + + /* Set region_count parameters since they are implicit in this case. */ + if(gi->block_type==0) + { + DEBUG_LAYER(printf("Side info bad: block_type==0 split block.\n");) + return false; + } + else if (gi->block_type==2 && gi->mixed_block_flag==0) + gi->region0_count=8; /* MI 9; */ + else gi->region0_count=7; /* MI 8; */ + gi->region1_count=20-(gi->region0_count); + } + else + { + gi->table_select[0] =getbits(5); + gi->table_select[1] =getbits(5); + gi->table_select[2] =getbits(5); + gi->region0_count =getbits(4); + gi->region1_count =getbits(3); + gi->block_type =0; + } + gi->preflag =getbit(); + gi->scalefac_scale =getbit(); + gi->count1table_select=getbit(); + + gi->generalflag=gi->window_switching_flag && (gi->block_type==2); + + if(!inputstereo || ch)break; + } + + return true; +} + +bool Mpegtoraw::layer3getsideinfo_2(void) { + int inputstereo=mpegAudioHeader->getInputstereo(); + sideinfo.main_data_begin=getbits(8); + + if(!inputstereo)sideinfo.private_bits=getbit(); + else sideinfo.private_bits=getbits(2); + + for(int ch=0;;ch++) + { + layer3grinfo *gi=&(sideinfo.ch[ch].gr[0]); + + gi->part2_3_length =getbits(12); + gi->big_values =getbits(9); + if(gi->big_values > 288) { + DEBUG_LAYER(fprintf(stderr,"big_values too large!\n");) + gi->big_values = 288; + return false; + } + + gi->global_gain =getbits(8); + gi->scalefac_compress =getbits(9); + gi->window_switching_flag=getbit(); + if(gi->window_switching_flag) + { + gi->block_type =getbits(2); + gi->mixed_block_flag=getbit(); + + gi->table_select[0] =getbits(5); + gi->table_select[1] =getbits(5); + + gi->subblock_gain[0]=getbits(3); + gi->subblock_gain[1]=getbits(3); + gi->subblock_gain[2]=getbits(3); + + /* Set region_count parameters since they are implicit in this case. */ + if(gi->block_type==0) + { + DEBUG_LAYER(printf("Side info bad: block_type==0 split block.\n");) + return false; + } + else if (gi->block_type==2 && gi->mixed_block_flag==0) + gi->region0_count=8; /* MI 9; */ + else gi->region0_count=7; /* MI 8; */ + gi->region1_count=20-(gi->region0_count); + } + else + { + gi->table_select[0] =getbits(5); + gi->table_select[1] =getbits(5); + gi->table_select[2] =getbits(5); + gi->region0_count =getbits(4); + gi->region1_count =getbits(3); + gi->block_type =0; + } + gi->scalefac_scale =getbit(); + gi->count1table_select=getbit(); + + gi->generalflag=gi->window_switching_flag && (gi->block_type==2); + + if(!inputstereo || ch)break; + } + + return true; +} + +void Mpegtoraw::layer3getscalefactors(int ch,int gr) +{ + static int slen[2][16]={{0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4}, + {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3}}; + + layer3grinfo *gi=&(sideinfo.ch[ch].gr[gr]); + register layer3scalefactor *sf=(&scalefactors[ch]); + int l0,l1; + + { + int scale_comp=gi->scalefac_compress; + + l0=slen[0][scale_comp]; + l1=slen[1][scale_comp]; + } + /* + wgetCanReadBits(); + cout << "lo:"<<l0<<" l1:"<<l1<<endl; + */ + if(gi->generalflag) + { + if(gi->mixed_block_flag) + { /* MIXED */ /* NEW-ag 11/25 */ + sf->l[0]=wgetbits9(l0);sf->l[1]=wgetbits9(l0); + sf->l[2]=wgetbits9(l0);sf->l[3]=wgetbits9(l0); + sf->l[4]=wgetbits9(l0);sf->l[5]=wgetbits9(l0); + sf->l[6]=wgetbits9(l0);sf->l[7]=wgetbits9(l0); + + sf->s[0][ 3]=wgetbits9(l0);sf->s[1][ 3]=wgetbits9(l0); + sf->s[2][ 3]=wgetbits9(l0); + sf->s[0][ 4]=wgetbits9(l0);sf->s[1][ 4]=wgetbits9(l0); + sf->s[2][ 4]=wgetbits9(l0); + sf->s[0][ 5]=wgetbits9(l0);sf->s[1][ 5]=wgetbits9(l0); + sf->s[2][ 5]=wgetbits9(l0); + + sf->s[0][ 6]=wgetbits9(l1);sf->s[1][ 6]=wgetbits9(l1); + sf->s[2][ 6]=wgetbits9(l1); + sf->s[0][ 7]=wgetbits9(l1);sf->s[1][ 7]=wgetbits9(l1); + sf->s[2][ 7]=wgetbits9(l1); + sf->s[0][ 8]=wgetbits9(l1);sf->s[1][ 8]=wgetbits9(l1); + sf->s[2][ 8]=wgetbits9(l1); + sf->s[0][ 9]=wgetbits9(l1);sf->s[1][ 9]=wgetbits9(l1); + sf->s[2][ 9]=wgetbits9(l1); + sf->s[0][10]=wgetbits9(l1);sf->s[1][10]=wgetbits9(l1); + sf->s[2][10]=wgetbits9(l1); + sf->s[0][11]=wgetbits9(l1);sf->s[1][11]=wgetbits9(l1); + sf->s[2][11]=wgetbits9(l1); + + sf->s[0][12]=sf->s[1][12]=sf->s[2][12]=0; + } + else + { /* SHORT*/ + sf->s[0][ 0]=wgetbits9(l0);sf->s[1][ 0]=wgetbits9(l0); + sf->s[2][ 0]=wgetbits9(l0); + sf->s[0][ 1]=wgetbits9(l0);sf->s[1][ 1]=wgetbits9(l0); + sf->s[2][ 1]=wgetbits9(l0); + sf->s[0][ 2]=wgetbits9(l0);sf->s[1][ 2]=wgetbits9(l0); + sf->s[2][ 2]=wgetbits9(l0); + sf->s[0][ 3]=wgetbits9(l0);sf->s[1][ 3]=wgetbits9(l0); + sf->s[2][ 3]=wgetbits9(l0); + sf->s[0][ 4]=wgetbits9(l0);sf->s[1][ 4]=wgetbits9(l0); + sf->s[2][ 4]=wgetbits9(l0); + sf->s[0][ 5]=wgetbits9(l0);sf->s[1][ 5]=wgetbits9(l0); + sf->s[2][ 5]=wgetbits9(l0); + + sf->s[0][ 6]=wgetbits9(l1);sf->s[1][ 6]=wgetbits9(l1); + sf->s[2][ 6]=wgetbits9(l1); + sf->s[0][ 7]=wgetbits9(l1);sf->s[1][ 7]=wgetbits9(l1); + sf->s[2][ 7]=wgetbits9(l1); + sf->s[0][ 8]=wgetbits9(l1);sf->s[1][ 8]=wgetbits9(l1); + sf->s[2][ 8]=wgetbits9(l1); + sf->s[0][ 9]=wgetbits9(l1);sf->s[1][ 9]=wgetbits9(l1); + sf->s[2][ 9]=wgetbits9(l1); + sf->s[0][10]=wgetbits9(l1);sf->s[1][10]=wgetbits9(l1); + sf->s[2][10]=wgetbits9(l1); + sf->s[0][11]=wgetbits9(l1);sf->s[1][11]=wgetbits9(l1); + sf->s[2][11]=wgetbits9(l1); + + sf->s[0][12]=sf->s[1][12]=sf->s[2][12]=0; + } + } + else + { /* LONG types 0,1,3 */ + if(gr==0) + { + sf->l[ 0]=wgetbits9(l0);sf->l[ 1]=wgetbits9(l0); + sf->l[ 2]=wgetbits9(l0);sf->l[ 3]=wgetbits9(l0); + sf->l[ 4]=wgetbits9(l0);sf->l[ 5]=wgetbits9(l0); + sf->l[ 6]=wgetbits9(l0);sf->l[ 7]=wgetbits9(l0); + sf->l[ 8]=wgetbits9(l0);sf->l[ 9]=wgetbits9(l0); + sf->l[10]=wgetbits9(l0); + sf->l[11]=wgetbits9(l1);sf->l[12]=wgetbits9(l1); + sf->l[13]=wgetbits9(l1);sf->l[14]=wgetbits9(l1); + sf->l[15]=wgetbits9(l1); + sf->l[16]=wgetbits9(l1);sf->l[17]=wgetbits9(l1); + sf->l[18]=wgetbits9(l1);sf->l[19]=wgetbits9(l1); + sf->l[20]=wgetbits9(l1); + } + else + { + if(sideinfo.ch[ch].scfsi[0]==0) + { + sf->l[ 0]=wgetbits9(l0);sf->l[ 1]=wgetbits9(l0); + sf->l[ 2]=wgetbits9(l0);sf->l[ 3]=wgetbits9(l0); + sf->l[ 4]=wgetbits9(l0);sf->l[ 5]=wgetbits9(l0); + } + if(sideinfo.ch[ch].scfsi[1]==0) + { + sf->l[ 6]=wgetbits9(l0);sf->l[ 7]=wgetbits9(l0); + sf->l[ 8]=wgetbits9(l0);sf->l[ 9]=wgetbits9(l0); + sf->l[10]=wgetbits9(l0); + } + if(sideinfo.ch[ch].scfsi[2]==0) + { + sf->l[11]=wgetbits9(l1);sf->l[12]=wgetbits9(l1); + sf->l[13]=wgetbits9(l1);sf->l[14]=wgetbits9(l1); + sf->l[15]=wgetbits9(l1); + } + if(sideinfo.ch[ch].scfsi[3]==0) + { + sf->l[16]=wgetbits9(l1);sf->l[17]=wgetbits9(l1); + sf->l[18]=wgetbits9(l1);sf->l[19]=wgetbits9(l1); + sf->l[20]=wgetbits9(l1); + } + } + sf->l[21]=sf->l[22]=0; + } + /* + cout << "end parse:"<<endl; + wgetCanReadBits(); + */ +} + +void Mpegtoraw::layer3getscalefactors_2(int ch) +{ + static int sfbblockindex[6][3][4]= + { + {{ 6, 5, 5, 5},{ 9, 9, 9, 9},{ 6, 9, 9, 9}}, + {{ 6, 5, 7, 3},{ 9, 9,12, 6},{ 6, 9,12, 6}}, + {{11,10, 0, 0},{18,18, 0, 0},{15,18, 0, 0}}, + {{ 7, 7, 7, 0},{12,12,12, 0},{ 6,15,12, 0}}, + {{ 6, 6, 6, 3},{12, 9, 9, 6},{ 6,12, 9, 6}}, + {{ 8, 8, 5, 0},{15,12, 9, 0},{ 6,18, 9, 0}} + }; + + int sb[54]; + int extendedmode=mpegAudioHeader->getExtendedmode(); + layer3grinfo *gi=&(sideinfo.ch[ch].gr[0]); + register layer3scalefactor *sf=(&scalefactors[ch]); + + { + int blocktypenumber,sc; + int blocknumber; + int slen[4]; + + if(gi->block_type==2)blocktypenumber=1+gi->mixed_block_flag; + else blocktypenumber=0; + + sc=gi->scalefac_compress; + if(!((extendedmode==1 || extendedmode==3) && (ch==1))) + { + if(sc<400) + { + slen[0]=(sc>>4)/5; + slen[1]=(sc>>4)%5; + slen[2]=(sc%16)>>2; + slen[3]=(sc%4); + gi->preflag=0; + blocknumber=0; + } + else if(sc<500) + { + sc-=400; + slen[0]=(sc>>2)/5; + slen[1]=(sc>>2)%5; + slen[2]=sc%4; + slen[3]=0; + gi->preflag=0; + blocknumber=1; + } + else // if(sc<512) + { + sc-=500; + slen[0]=sc/3; + slen[1]=sc%3; + slen[2]=0; + slen[3]=0; + gi->preflag=1; + blocknumber=2; + } + } + else + { + sc>>=1; + if(sc<180) + { + slen[0]=sc/36; + slen[1]=(sc%36)/6; + slen[2]=(sc%36)%6; + slen[3]=0; + gi->preflag=0; + blocknumber=3; + } + else if(sc<244) + { + sc-=180; + slen[0]=(sc%64)>>4; + slen[1]=(sc%16)>>2; + slen[2]=sc%4; + slen[3]=0; + gi->preflag=0; + blocknumber=4; + } + else // if(sc<255) + { + sc-=244; + slen[0]=sc/3; + slen[1]=sc%3; + slen[2]= + slen[3]=0; + gi->preflag=0; + blocknumber=5; + } + } + + { + int i,j,k,*si; + + si=sfbblockindex[blocknumber][blocktypenumber]; + for(i=0;i<45;i++)sb[i]=0; + + for(k=i=0;i<4;i++) + for(j=0;j<si[i];j++,k++) + if(slen[i]==0)sb[k]=0; + else sb[k]=wgetbits(slen[i]); + } + } + + + { + int sfb,window; + int k=0; + + if(gi->window_switching_flag && (gi->block_type==2)) + { + if(gi->mixed_block_flag) + { + for(sfb=0;sfb<8;sfb++)sf->l[sfb]=sb[k++]; + sfb=3; + } + else sfb=0; + + for(;sfb<12;sfb++) + for(window=0;window<3;window++) + sf->s[window][sfb]=sb[k++]; + + sf->s[0][12]=sf->s[1][12]=sf->s[2][12]=0; + } + else + { + for(sfb=0;sfb<21;sfb++) + sf->l[sfb]=sb[k++]; + sf->l[21]=sf->l[22]=0; + } + } +} + + +typedef unsigned int HUFFBITS; +#define MXOFF 250 + +/* do the huffman-decoding */ +/* note! for counta,countb -the 4 bit value is returned in y, discard x */ +// Huffman decoder for tablename<32 +inline void Mpegtoraw::huffmandecoder_1(const HUFFMANCODETABLE *h,int *x,int *y) +{ + HUFFBITS level=(1<<(sizeof(HUFFBITS)*8-1)); + int point=0; + + /* Lookup in Huffman table. */ + for(;;) + { + if(h->val[point][0]==0) + { /*end of tree*/ + int xx,yy; + + xx=h->val[point][1]>>4; + yy=h->val[point][1]&0xf; + + if(h->linbits) + { + if((h->xlen)==(unsigned)xx)xx+=wgetbits(h->linbits); + if(xx)if(wgetbit())xx=-xx; + if((h->ylen)==(unsigned)yy)yy+=wgetbits(h->linbits); + if(yy)if(wgetbit())yy=-yy; + } + else + { + if(xx)if(wgetbit())xx=-xx; + if(yy)if(wgetbit())yy=-yy; + } + *x=xx;*y=yy; + break; + } + + point+=h->val[point][wgetbit()]; + + level>>=1; + if(!(level || ((unsigned)point<ht->treelen))) + { + register int xx,yy; + + xx=(h->xlen<<1);// set x and y to a medium value as a simple concealment + yy=(h->ylen<<1); + + // h->xlen and h->ylen can't be 1 under tablename 32 + // if(xx) + if(wgetbit())xx=-xx; + // if(yy) + if(wgetbit())yy=-yy; + + *x=xx;*y=yy; + break; + } + } +} + +// Huffman decoder tablenumber>=32 +inline void Mpegtoraw::huffmandecoder_2(const HUFFMANCODETABLE *h, + int *x,int *y,int *v,int *w) +{ + HUFFBITS level=(1<<(sizeof(HUFFBITS)*8-1)); + int point=0; + + /* Lookup in Huffman table. */ + for(;;) + { + if(h->val[point][0]==0) + { /*end of tree*/ + register int t=h->val[point][1]; + + if(t&8)*v=1-(wgetbit()<<1); else *v=0; + if(t&4)*w=1-(wgetbit()<<1); else *w=0; + if(t&2)*x=1-(wgetbit()<<1); else *x=0; + if(t&1)*y=1-(wgetbit()<<1); else *y=0; + break; + } + point+=h->val[point][wgetbit()]; + level>>=1; + if(!(level || ((unsigned)point<ht->treelen))) + { + *v=1-(wgetbit()<<1); + *w=1-(wgetbit()<<1); + *x=1-(wgetbit()<<1); + *y=1-(wgetbit()<<1); + break; + } + } +} + +typedef struct +{ + int l[23]; + int s[14]; +}SFBANDINDEX; + +static SFBANDINDEX sfBandIndextable[3][3]= +{ + // MPEG 1 + {{{0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576}, + {0,4,8,12,16,22,30,40,52,66,84,106,136,192}}, + {{0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576}, + {0,4,8,12,16,22,28,38,50,64,80,100,126,192}}, + {{0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576}, + {0,4,8,12,16,22,30,42,58,78,104,138,180,192}}}, + + // MPEG 2 + {{{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, + {0,4,8,12,18,24,32,42,56,74,100,132,174,192}}, + {{0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576}, + {0,4,8,12,18,26,36,48,62,80,104,136,180,192}}, + {{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, + {0,4,8,12,18,26,36,48,62,80,104,134,174,192}}}, + // MPEG 2.5 + {{{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, + {0,4,8,12,18,26,36,48,62,80,104,134,174,192}}, + {{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, + {0,4,8,12,18,26,36,48,62,80,104,134,174,192}}, + {{0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576}, + {0,8,16,24,36,52,72,96,124,160,162,164,166,192}}} +}; + + +void Mpegtoraw::layer3huffmandecode(int ch,int gr,int out[SBLIMIT][SSLIMIT]) +{ + layer3grinfo *gi=&(sideinfo.ch[ch].gr[gr]); + int part2_3_end=layer3part2start+(gi->part2_3_length); + int region1Start,region2Start; + int i,e=gi->big_values<<1; + int version=mpegAudioHeader->getVersion(); + int frequency=mpegAudioHeader->getFrequency(); + int mpeg25=mpegAudioHeader->getLayer25(); + + /* Find region boundary for short block case. */ + if(gi->generalflag) { + /* Region2. */ + region1Start= + sfBandIndextable[mpeg25?2:version][frequency].s[3]*3; + /* MPEG1:sfb[9/3]*3=36 */ + region2Start=576;/* No Region2 for short block case. */ + } else { + /* Find region boundary for long block case. */ + region1Start= + sfBandIndextable[mpeg25?2:version][frequency].l[gi->region0_count+1]; + region2Start= + sfBandIndextable[mpeg25?2:version][frequency].l[gi->region0_count+ + gi->region1_count+2]; + } + + /* Read bigvalues area. */ + for(i=0;i<e;) + { + const HUFFMANCODETABLE *h; + register int end; + + if (i<region1Start) + { + h=&ht[gi->table_select[0]]; + if(region1Start>e)end=e; else end=region1Start; + } + else if(i<region2Start) + { + h=&ht[gi->table_select[1]]; + if(region2Start>e)end=e; else end=region2Start; + } + else + { + h=&ht[gi->table_select[2]]; + end=e; + } + + if(h->treelen) { + while(i<end) + { + + int skip = HuffmanLookup::decode(h->tablename, bitwindow.peek8(), + &out[0][i], &out[0][i+1]); + + if(skip) + bitwindow.forward(skip); + else + huffmandecoder_1(h,&out[0][i],&out[0][i+1]); + i+=2; + } + } else { + for(;i<end;i+=2) + out[0][i] = + out[0][i+1]=0; + } + } + + /* Read count1 area. */ + const HUFFMANCODETABLE *h=&ht[gi->count1table_select+32]; + while(bitwindow.gettotalbit()<part2_3_end) + { + huffmandecoder_2(h,&out[0][i+2],&out[0][i+3], + &out[0][i ],&out[0][i+1]); + i+=4; + + if(i>=ARRAYSIZE) + { + break; + } + } + + // nonzero is the _size_ of the array with the last nonzero value + if (i < ARRAYSIZE) { + nonzero[ch] = i; + } else { + // catch bugs + nonzero[ch] = ARRAYSIZE; + } + + // debug start +#ifndef MAPLAY_OPT + nonzero[ch]=ARRAYSIZE; + for(;i<ARRAYSIZE;i++)out[0][i]=0; +#endif + // debug end + + bitwindow.rewind(bitwindow.gettotalbit()-part2_3_end); +} + + +static int pretab[22]={0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0}; + +inline REAL Mpegtoraw::layer3twopow2(int scale,int preflag, + int pretab_offset,int l) +{ + int index=l; + + if(preflag)index+=pretab_offset; + + return(two_to_negative_half_pow[index<<scale]); +} + +inline REAL Mpegtoraw::layer3twopow2_1(int a,int b,int c) +{ + return POW2_1[a][b][c]; +} + + +void Mpegtoraw::layer3dequantizesample(int ch,int gr, + int in[SBLIMIT][SSLIMIT], + REAL out[SBLIMIT][SSLIMIT]) +{ + int version=mpegAudioHeader->getVersion(); + int frequency=mpegAudioHeader->getFrequency(); + int mpeg25=mpegAudioHeader->getLayer25(); + layer3grinfo *gi=&(sideinfo.ch[ch].gr[gr]); + SFBANDINDEX *sfBandIndex=&(sfBandIndextable[mpeg25?2:version][frequency]); + REAL globalgain=POW2[gi->global_gain]; + REAL *TO_FOUR_THIRDS=TO_FOUR_THIRDSTABLE+FOURTHIRDSTABLENUMBER; + int arrayEnd=nonzero[ch]; + /* choose correct scalefactor band per block type, initialize boundary */ + /* and apply formula per block type */ + if(!gi->generalflag) { + /* LONG blocks: 0,1,3 */ + int next_cb_boundary; + int cb=-1,index=0; + REAL factor; + + + do + { + + next_cb_boundary=sfBandIndex->l[(++cb)+1]; + REAL val=layer3twopow2(gi->scalefac_scale,gi->preflag, + pretab[cb],scalefactors[ch].l[cb]); + factor=globalgain*val; + // maplay opt + if (arrayEnd < next_cb_boundary) { + next_cb_boundary=arrayEnd; + } + + for(;index<next_cb_boundary;) + { + out[0][index]=factor*TO_FOUR_THIRDS[in[0][index]];index++; + out[0][index]=factor*TO_FOUR_THIRDS[in[0][index]];index++; + } + + }while(index<arrayEnd); + } else if(!gi->mixed_block_flag) { + int cb=0,index=0; + int cb_width; + do + { + cb_width=(sfBandIndex->s[cb+1]-sfBandIndex->s[cb])>>1; + + for(register int k=0;k<3;k++) + { + register REAL factor; + register int count=cb_width; + // maplay12 opt. + if(index+(count<<1) > arrayEnd) { + if (index >= arrayEnd) break; + count=(arrayEnd-index)>>1; + } + + factor=globalgain* + layer3twopow2_1(gi->subblock_gain[k],gi->scalefac_scale, + scalefactors[ch].s[k][cb]); + + + do{ + out[0][index]=factor*TO_FOUR_THIRDS[in[0][index]];index++; + out[0][index]=factor*TO_FOUR_THIRDS[in[0][index]];index++; + }while(--count); + } + cb++; + }while(index<arrayEnd); + } else { + int cb_begin=0,cb_width=0; + int cb=0; + int next_cb_boundary=sfBandIndex->l[1]; /* LONG blocks: 0,1,3 */ + int index; + // I do not have an mp3 with this format, + // so we restore the "make rest of array zero" + // in this case + // to use the maplay opt here, we must make sure, that + // arrayEnd==ArraySize. + for(int i=arrayEnd;i<ARRAYSIZE;i++)in[0][i]=0; + + /* Compute overall (global) scaling. */ + { + for(int sb=0;sb<SBLIMIT;sb++) + { + int *i=in[sb]; + REAL *o=out[sb]; + + o[ 0]=globalgain*TO_FOUR_THIRDS[i[ 0]]; + o[ 1]=globalgain*TO_FOUR_THIRDS[i[ 1]]; + o[ 2]=globalgain*TO_FOUR_THIRDS[i[ 2]]; + o[ 3]=globalgain*TO_FOUR_THIRDS[i[ 3]]; + o[ 4]=globalgain*TO_FOUR_THIRDS[i[ 4]]; + o[ 5]=globalgain*TO_FOUR_THIRDS[i[ 5]]; + o[ 6]=globalgain*TO_FOUR_THIRDS[i[ 6]]; + o[ 7]=globalgain*TO_FOUR_THIRDS[i[ 7]]; + o[ 8]=globalgain*TO_FOUR_THIRDS[i[ 8]]; + o[ 9]=globalgain*TO_FOUR_THIRDS[i[ 9]]; + o[10]=globalgain*TO_FOUR_THIRDS[i[10]]; + o[11]=globalgain*TO_FOUR_THIRDS[i[11]]; + o[12]=globalgain*TO_FOUR_THIRDS[i[12]]; + o[13]=globalgain*TO_FOUR_THIRDS[i[13]]; + o[14]=globalgain*TO_FOUR_THIRDS[i[14]]; + o[15]=globalgain*TO_FOUR_THIRDS[i[15]]; + o[16]=globalgain*TO_FOUR_THIRDS[i[16]]; + o[17]=globalgain*TO_FOUR_THIRDS[i[17]]; + } + } + for(index=0;index<SSLIMIT*2;index++) + { + if(index==next_cb_boundary) + { + if(index==sfBandIndex->l[8]) + { + next_cb_boundary=sfBandIndex->s[4]; + next_cb_boundary=MUL3(next_cb_boundary); + cb=3; + cb_width=sfBandIndex->s[4]-sfBandIndex->s[3]; + cb_begin=sfBandIndex->s[3]; + cb_begin=MUL3(cb_begin); + } + else if(index<sfBandIndex->l[8]) + next_cb_boundary=sfBandIndex->l[(++cb)+1]; + else + { + next_cb_boundary=sfBandIndex->s[(++cb)+1]; + next_cb_boundary=MUL3(next_cb_boundary); + cb_begin=sfBandIndex->s[cb]; + cb_width=sfBandIndex->s[cb+1]-cb_begin; + cb_begin=MUL3(cb_begin); + } + } + /* LONG block types 0,1,3 & 1st 2 subbands of switched blocks */ + out[0][index]*=layer3twopow2(gi->scalefac_scale,gi->preflag, + pretab[cb],scalefactors[ch].l[cb]); + + } + + for(;index<ARRAYSIZE;index++) { + if(index==next_cb_boundary) { + if(index==sfBandIndex->l[8]) { + next_cb_boundary=sfBandIndex->s[4]; + next_cb_boundary=MUL3(next_cb_boundary); + cb=3; + cb_width=sfBandIndex->s[4]-sfBandIndex->s[3]; + cb_begin=sfBandIndex->s[3]; + cb_begin=(cb_begin<<2)-cb_begin; + } else if(index<sfBandIndex->l[8]) + next_cb_boundary=sfBandIndex->l[(++cb)+1]; + else { + next_cb_boundary=sfBandIndex->s[(++cb)+1]; + next_cb_boundary=MUL3(next_cb_boundary); + cb_begin=sfBandIndex->s[cb]; + cb_width=sfBandIndex->s[cb+1]-cb_begin; + cb_begin=MUL3(cb_begin); + } + } + { + /** + Here we check if we do a division by zero + and if the resulting t_index points + outside the array. (Needed for better robustness + of the mp3 decoder) + */ + unsigned int t_index=0; + if (cb_width) { + t_index=(unsigned int)((index-cb_begin)/cb_width); + if (t_index > 2) { + t_index=0; + } + } + + out[0][index]*=layer3twopow2_1(gi->subblock_gain[t_index], + gi->scalefac_scale, + scalefactors[ch].s[t_index][cb]); + } + } + } + /* + int i; + for(i=arrayEnd;i<ARRAYSIZE;i++) { + out[0][i]=(REAL) 0.0; + } + */ +} +// make the input to nonzero[2] zero +inline void Mpegtoraw::adjustNonZero(REAL in[2][SBLIMIT][SSLIMIT]) { + if ((nonzero[0] == 0) && (nonzero[1]==0)) { + in[RS][0][0]=(REAL) 0.0; + in[LS][0][0]=(REAL) 0.0; + nonzero[0]=1; + nonzero[1]=1; + nonzero[2]=1; + return; + } + + while(nonzero[0] > nonzero[1]) { + in[RS][0][nonzero[1]]=(REAL) 0.0; + nonzero[1]++; + } + while(nonzero[1] > nonzero[0]) { + in[LS][0][nonzero[0]]=(REAL) 0.0; + nonzero[0]++; + } + // now they are the same + // put this into the "max" var. + nonzero[2]=nonzero[1]; + +} + + +inline void Mpegtoraw::layer3fixtostereo(int gr,REAL in[2][SBLIMIT][SSLIMIT]) +{ + int version=mpegAudioHeader->getVersion(); + int frequency=mpegAudioHeader->getFrequency(); + int extendedmode=mpegAudioHeader->getExtendedmode(); + int mode=mpegAudioHeader->getMode(); + int inputstereo=mpegAudioHeader->getInputstereo(); + int mpeg25=mpegAudioHeader->getLayer25(); + layer3grinfo *gi=&(sideinfo.ch[0].gr[gr]); + SFBANDINDEX *sfBandIndex=&(sfBandIndextable[mpeg25?2:version][frequency]); + + int ms_stereo=(mode==_MODE_JOINT) && (extendedmode & 0x2); + int i_stereo =(mode==_MODE_JOINT) && (extendedmode & 0x1); + + + if(!inputstereo) + { /* mono , bypass xr[0][][] to lr[0][][]*/ + // memcpy(out[0][0],in[0][0],ARRAYSIZE*REALSIZE); + for(int i=nonzero[0];i<ARRAYSIZE;i++) { + in[LS][0][i]=(REAL) 0.0; + } + return; + } + // maplay opt. + adjustNonZero(in); + int maxArray=nonzero[2]; + + if(i_stereo) + { + + // not maplay optimised make defaults + int i; + for(i=maxArray;i<ARRAYSIZE;i++) { + in[LS][0][i]=in[RS][0][i]=(REAL) 0.0; + } + + + int is_pos[ARRAYSIZE]; + RATIOS is_ratio[ARRAYSIZE]; + RATIOS *ratios; + if(version)ratios=rat_2[gi->scalefac_compress%2]; + else ratios=rat_1; + + /* initialization */ + for(i=0;i<ARRAYSIZE;i+=2)is_pos[i]=is_pos[i+1]=7; + + if(gi->generalflag) + { + if(gi->mixed_block_flag) // Part I + { + int max_sfb=0; + + for(int j=0;j<3;j++) + { + int sfb,sfbcnt=2; + + for(sfb=12;sfb>=3;sfb--) + { + int lines; + + i=sfBandIndex->s[sfb]; + lines=sfBandIndex->s[sfb+1]-i; + i=MUL3(i)+(j+1)*lines-1; + for(;lines>0;lines--,i--) + if(in[1][0][i]!=0.0f) + { + sfbcnt=sfb; + sfb=0;break; // quit loop + } + } + sfb=sfbcnt+1; + + if(sfb>max_sfb)max_sfb=sfb; + + for(;sfb<12;sfb++) + { + int k,t; + + t=sfBandIndex->s[sfb]; + k=sfBandIndex->s[sfb+1]-t; + i=MUL3(t)+j*k; + + t=scalefactors[1].s[j][sfb]; + if(t!=7) + { + RATIOS r=ratios[t]; + + for(;k>0;k--,i++){ + is_pos[i]=t;is_ratio[i]=r;} + } + else + for(;k>0;k--,i++)is_pos[i]=t; + } + sfb=sfBandIndex->s[10]; + sfb=MUL3(sfb)+j*(sfBandIndex->s[11]-sfb); + + { + int k,t; + + t=sfBandIndex->s[11]; + k=sfBandIndex->s[12]-t; + i=MUL3(t)+j*k; + + t=is_pos[sfb]; + if(t!=7) + { + RATIOS r=is_ratio[sfb]; + + for(;k>0;k--,i++){ + is_pos[i]=t;is_ratio[i]=r;} + } + else + for(;k>0;k--,i++)is_pos[i]=t; + } + } + + if(max_sfb<=3) + { + { + REAL temp; + int k; + + temp=in[1][0][0];in[1][0][0]=1.0; + for(k=3*SSLIMIT-1;in[1][0][k]==0.0;k--); + in[1][0][0]=temp; + for(i=0;sfBandIndex->l[i]<=k;i++); + } + { + int sfb=i; + + i=sfBandIndex->l[i]; + for(;sfb<8;sfb++) + { + int t=scalefactors[1].l[sfb]; + int k=sfBandIndex->l[sfb+1]-sfBandIndex->l[sfb]; + + if(t!=7) + { + RATIOS r=ratios[t]; + + for(;k>0;k--,i++){ + is_pos[i]=t;is_ratio[i]=r;} + } + else for(;k>0;k--,i++)is_pos[i]=t; + } + } + } + } + else // Part II + { + for(int j=0;j<3;j++) + { + int sfbcnt=-1; + int sfb; + for(sfb=12;sfb>=0;sfb--) + { + int lines; + + { + int t; + + t=sfBandIndex->s[sfb]; + lines=sfBandIndex->s[sfb+1]-t; + i=MUL3(t)+(j+1)*lines-1; + } + + for(;lines>0;lines--,i--) + if(in[1][0][i]!=0.0f) + { + sfbcnt=sfb; + sfb=0;break; // quit loop + } + } + + for(sfb=sfbcnt+1;sfb<12;sfb++) + { + int k,t; + + t=sfBandIndex->s[sfb]; + k=sfBandIndex->s[sfb+1]-t; + i=MUL3(t)+j*k; + + t=scalefactors[1].s[j][sfb]; + if(t!=7) + { + RATIOS r=ratios[t]; + + for(;k>0;k--,i++){ + is_pos[i]=t;is_ratio[i]=r;} + } + else for(;k>0;k--,i++)is_pos[i]=t; + } + + { + int t1=sfBandIndex->s[10], + t2=sfBandIndex->s[11]; + int k,tt; + + tt=MUL3(t1)+j*(t2-t1); + k =sfBandIndex->s[12]-t2; + if(is_pos[tt]!=7) + { + RATIOS r=is_ratio[tt]; + int t=is_pos[tt]; + + i =MUL3(t1)+j*k; + for(;k>0;k--,i++){ + is_pos[i]=t;is_ratio[i]=r;} + } + else + for(;k>0;k--,i++)is_pos[i]=7; + } + } + } + } + else // ms-stereo (Part III) + { + { + REAL temp; + int k; + + temp=in[1][0][0];in[1][0][0]=1.0; + for(k=ARRAYSIZE-1;in[1][0][k]==0.0;k--); + in[1][0][0]=temp; + for(i=0;sfBandIndex->l[i]<=k;i++); + } + + { + int sfb; + + sfb=i; + i=sfBandIndex->l[i]; + for(;sfb<21;sfb++) + { + int k,t; + + k=sfBandIndex->l[sfb+1]-sfBandIndex->l[sfb]; + t=scalefactors[1].l[sfb]; + if(t!=7) + { + RATIOS r=ratios[t]; + + for(;k>0;k--,i++){ + is_pos[i]=t;is_ratio[i]=r;} + } + else + for(;k>0;k--,i++)is_pos[i]=t; + } + } + + { + int k,t,tt; + + tt=sfBandIndex->l[20]; + k=576-sfBandIndex->l[21]; + t=is_pos[tt]; + if(t!=7) + { + RATIOS r=is_ratio[tt]; + + for(;k>0;k--,i++){ + is_pos[i]=t;is_ratio[i]=r;} + } + else + for(;k>0;k--,i++)is_pos[i]=t; + } + } + + if(ms_stereo) + { + i=ARRAYSIZE-1; + do{ + if(is_pos[i]==7) + { + register REAL t=in[LS][0][i]; + in[LS][0][i]=(t+in[RS][0][i])*0.7071068f; + in[RS][0][i]=(t-in[RS][0][i])*0.7071068f; + } + else + { + in[RS][0][i]=in[LS][0][i]*is_ratio[i].r; + in[LS][0][i]*=is_ratio[i].l; + } + }while(i--); + } + else + { + i=ARRAYSIZE-1; + do{ + if(is_pos[i]!=7) + { + in[RS][0][i]=in[LS][0][i]*is_ratio[i].r; + in[LS][0][i]*=is_ratio[i].l; + } + }while(i--); + } + } + else + { + + if(ms_stereo) + { + int i=maxArray-1; + do{ + register REAL t=in[LS][0][i]; + + in[LS][0][i]=(t+in[RS][0][i])*0.7071068f; + in[RS][0][i]=(t-in[RS][0][i])*0.7071068f; + }while(i--); + } + for(int i=maxArray;i<ARRAYSIZE;i++) { + in[LS][0][i]=in[RS][0][i]=(REAL) 0.0; + } + + } + + + // channels==2 +} + +inline void layer3reorder_1(int version,int frequency, + REAL in[SBLIMIT][SSLIMIT], + REAL out[SBLIMIT][SSLIMIT]) +{ + SFBANDINDEX *sfBandIndex=&(sfBandIndextable[version][frequency]); + int sfb,sfb_start,sfb_lines; + + /* NO REORDER FOR LOW 2 SUBBANDS */ + out[0][ 0]=in[0][ 0];out[0][ 1]=in[0][ 1];out[0][ 2]=in[0][ 2]; + out[0][ 3]=in[0][ 3];out[0][ 4]=in[0][ 4];out[0][ 5]=in[0][ 5]; + out[0][ 6]=in[0][ 6];out[0][ 7]=in[0][ 7];out[0][ 8]=in[0][ 8]; + out[0][ 9]=in[0][ 9];out[0][10]=in[0][10];out[0][11]=in[0][11]; + out[0][12]=in[0][12];out[0][13]=in[0][13];out[0][14]=in[0][14]; + out[0][15]=in[0][15];out[0][16]=in[0][16];out[0][17]=in[0][17]; + + out[1][ 0]=in[1][ 0];out[1][ 1]=in[1][ 1];out[1][ 2]=in[1][ 2]; + out[1][ 3]=in[1][ 3];out[1][ 4]=in[1][ 4];out[1][ 5]=in[1][ 5]; + out[1][ 6]=in[1][ 6];out[1][ 7]=in[1][ 7];out[1][ 8]=in[1][ 8]; + out[1][ 9]=in[1][ 9];out[1][10]=in[1][10];out[1][11]=in[1][11]; + out[1][12]=in[1][12];out[1][13]=in[1][13];out[1][14]=in[1][14]; + out[1][15]=in[1][15];out[1][16]=in[1][16];out[1][17]=in[1][17]; + + + /* REORDERING FOR REST SWITCHED SHORT */ + for(sfb=3,sfb_start=sfBandIndex->s[3], + sfb_lines=sfBandIndex->s[4]-sfb_start; + sfb<13; + sfb++,sfb_start=sfBandIndex->s[sfb], + (sfb_lines=sfBandIndex->s[sfb+1]-sfb_start)) + { + for(int freq=0;freq<sfb_lines;freq++) + { + int src_line=sfb_start+(sfb_start<<1)+freq; + int des_line=src_line+(freq<<1); + out[0][des_line ]=in[0][src_line ]; + out[0][des_line+1]=in[0][src_line+sfb_lines ]; + out[0][des_line+2]=in[0][src_line+(sfb_lines<<1)]; + } + } +} + +inline void layer3reorder_2(int version,int frequency,REAL in[SBLIMIT][SSLIMIT], + REAL out[SBLIMIT][SSLIMIT]) +{ + SFBANDINDEX *sfBandIndex=&(sfBandIndextable[version][frequency]); + int sfb,sfb_start,sfb_lines; + + for(sfb=0,sfb_start=0,sfb_lines=sfBandIndex->s[1]; + sfb<13; + sfb++,sfb_start=sfBandIndex->s[sfb], + (sfb_lines=sfBandIndex->s[sfb+1]-sfb_start)) + { + for(int freq=0;freq<sfb_lines;freq++) + { + int src_line=sfb_start+(sfb_start<<1)+freq; + int des_line=src_line+(freq<<1); + + out[0][des_line ]=in[0][src_line ]; + out[0][des_line+1]=in[0][src_line+sfb_lines ]; + out[0][des_line+2]=in[0][src_line+(sfb_lines<<1)]; + } + } +} + + +inline void layer3antialias_1(REAL in[SBLIMIT][SSLIMIT]) +{ + for(int ss=0;ss<8;ss++) + { + REAL bu,bd; /* upper and lower butterfly inputs */ + + bu=in[0][17-ss];bd=in[1][ss]; + in[0][17-ss]=(bu*cs[ss])-(bd*ca[ss]); + in[1][ss] =(bd*cs[ss])+(bu*ca[ss]); + } +} + +inline +void layer3antialias_2(REAL in[SBLIMIT][SSLIMIT], + REAL out[SBLIMIT][SSLIMIT]) +{ + out[0][0]=in[0][0];out[0][1]=in[0][1]; + out[0][2]=in[0][2];out[0][3]=in[0][3]; + out[0][4]=in[0][4];out[0][5]=in[0][5]; + out[0][6]=in[0][6];out[0][7]=in[0][7]; + + for(int index=SSLIMIT;index<=(SBLIMIT-1)*SSLIMIT;index+=SSLIMIT) + { + for(int n=0;n<8;n++) + { + REAL bu,bd; + + bu=in[0][index-n-1];bd=in[0][index+n]; + out[0][index-n-1]=(bu*cs[n])-(bd*ca[n]); + out[0][index+n ]=(bd*cs[n])+(bu*ca[n]); + } + out[0][index-SSLIMIT+8]=in[0][index-SSLIMIT+8]; + out[0][index-SSLIMIT+9]=in[0][index-SSLIMIT+9]; + } + + out[31][ 8]=in[31][ 8];out[31][ 9]=in[31][ 9]; + out[31][10]=in[31][10];out[31][11]=in[31][11]; + out[31][12]=in[31][12];out[31][13]=in[31][13]; + out[31][14]=in[31][14];out[31][15]=in[31][15]; + out[31][16]=in[31][16];out[31][17]=in[31][17]; +} + +void Mpegtoraw::layer3reorderandantialias(int ch,int gr, + REAL in[SBLIMIT][SSLIMIT], + REAL out[SBLIMIT][SSLIMIT]) +{ + int version=mpegAudioHeader->getVersion(); + int frequency=mpegAudioHeader->getFrequency(); + int mpeg25=mpegAudioHeader->getLayer25(); + register layer3grinfo *gi=&(sideinfo.ch[ch].gr[gr]); + + if(gi->generalflag) { + if(gi->mixed_block_flag) { + layer3reorder_1 (mpeg25?2:version,frequency,in,out); // Not checked... + layer3antialias_1(out); + } + else { + layer3reorder_2(mpeg25?2:version,frequency,in,out); + } + } + else { + + layer3antialias_2(in,out); + + } +} + + +#include "dct36_12.cpp" +#include "window.cpp" + +void Mpegtoraw::layer3hybrid(int ch,int gr,REAL in[SBLIMIT][SSLIMIT], + REAL out[SSLIMIT][SBLIMIT]) +{ + layer3grinfo *gi=&(sideinfo.ch[ch].gr[gr]); + int bt1,bt2; + REAL *prev1,*prev2; + + prev1=prevblck[ch][currentprevblock][0]; + prev2=prevblck[ch][currentprevblock^1][0]; + + bt1 = gi->mixed_block_flag ? 0 : gi->block_type; + bt2 = gi->block_type; + + { + REAL *ci=(REAL *)in, + *co=(REAL *)out; + int i; + + if(lDownSample)i=(SBLIMIT/2)-2; + else i=SBLIMIT-2; + + + if(bt2==2) + { + if(!bt1) + { + dct36(ci,prev1,prev2,getSplayWindow(0),co); + ci+=SSLIMIT;prev1+=SSLIMIT;prev2+=SSLIMIT;co++; + dct36(ci,prev1,prev2,getSplayWindowINV(0),co); + } + else + { + dct12(ci,prev1,prev2,getSplayWindow(2),co); + ci+=SSLIMIT;prev1+=SSLIMIT;prev2+=SSLIMIT;co++; + dct12(ci,prev1,prev2,getSplayWindowINV(2),co); + } + + do{ + ci+=SSLIMIT;prev1+=SSLIMIT;prev2+=SSLIMIT;co++; + dct12(ci,prev1,prev2,getSplayWindow(2),co); + i--; + ci+=SSLIMIT;prev1+=SSLIMIT;prev2+=SSLIMIT;co++; + dct12(ci,prev1,prev2,getSplayWindowINV(2),co); + }while(--i); + } + else + { + dct36(ci,prev1,prev2,getSplayWindow(bt1),co); + ci+=SSLIMIT;prev1+=SSLIMIT;prev2+=SSLIMIT;co++; + dct36(ci,prev1,prev2,getSplayWindowINV(bt1),co); + + do + { + ci+=SSLIMIT;prev1+=SSLIMIT;prev2+=SSLIMIT;co++; + dct36(ci,prev1,prev2,getSplayWindow(bt2),co); + i--; + ci+=SSLIMIT;prev1+=SSLIMIT;prev2+=SSLIMIT;co++; + dct36(ci,prev1,prev2,getSplayWindowINV(bt2),co); + }while(--i); + } + } +} + +void Mpegtoraw::extractlayer3(void) { + int version=mpegAudioHeader->getVersion(); + int inputstereo=mpegAudioHeader->getInputstereo(); + int layer3slots=mpegAudioHeader->getLayer3slots(); + + if(version) { + extractlayer3_2(); + return; + } + + { + int main_data_end,flush_main; + int bytes_to_discard; + if (layer3getsideinfo() == false) { + return; + } + // read main data. + if(issync()) { + for(register int i=layer3slots;i>0;i--) { + bitwindow.putbyte(getbyte()); + } + } else { + // read main data. + for(register int i=layer3slots;i>0;i--) { + bitwindow.putbyte(getbits8()); + } + } + + main_data_end=bitwindow.gettotalbit()>>3;// of previous frame + if (main_data_end < 0) { + DEBUG_LAYER(printf("main_data_end < 0\n");) + return; + } + + if((flush_main=(bitwindow.gettotalbit() & 0x7))) { + bitwindow.forward(8-flush_main); + main_data_end++; + } + + bytes_to_discard=layer3framestart-(main_data_end+sideinfo.main_data_begin); + if(main_data_end>WINDOWSIZE) { + layer3framestart-=WINDOWSIZE; + bitwindow.rewind(WINDOWSIZE*8); + } + layer3framestart+=layer3slots; + bitwindow.wrap(); + if(bytes_to_discard<0) return; + bitwindow.forward(bytes_to_discard<<3); + } + for(int gr=0;gr<2;gr++) { + ATTR_ALIGN(64) union + { + int is [SBLIMIT][SSLIMIT]; + REAL hin [2][SBLIMIT][SSLIMIT]; + }b1; + ATTR_ALIGN(64) union + { + REAL ro [2][SBLIMIT][SSLIMIT]; + REAL lr [2][SBLIMIT][SSLIMIT]; + REAL hout [2][SSLIMIT][SBLIMIT]; + }b2; + + layer3part2start=bitwindow.gettotalbit(); + layer3getscalefactors (LS,gr); + + layer3huffmandecode (LS,gr ,b1.is); + layer3dequantizesample(LS,gr,b1.is,b2.ro[LS]); + //dump->dump(b2.ro[LS]); + + if(inputstereo) { + layer3part2start=bitwindow.gettotalbit(); + layer3getscalefactors (RS,gr); + layer3huffmandecode (RS,gr ,b1.is); + layer3dequantizesample(RS,gr,b1.is,b2.ro[RS]); + } + layer3fixtostereo(gr,b2.ro); // b2.ro -> b2.lr + currentprevblock^=1; + + + layer3reorderandantialias(LS,gr,b2.lr[LS],b1.hin[LS]); + //dump->dump(b1.hin[LS]); + layer3hybrid (LS,gr,b1.hin[LS],b2.hout[LS]); + //dump->dump(b2.hout[LS]); + + + + + if(lOutputStereo) { + layer3reorderandantialias(RS,gr,b2.lr[RS],b1.hin[RS]); + layer3hybrid (RS,gr,b1.hin[RS],b2.hout[RS]); + + } + synthesis->doMP3Synth(lDownSample,lOutputStereo,b2.hout); + } +} + +void Mpegtoraw::extractlayer3_2(void) { + int inputstereo=mpegAudioHeader->getInputstereo(); + int layer3slots=mpegAudioHeader->getLayer3slots(); + + { + int main_data_end,flush_main; + int bytes_to_discard; + if (layer3getsideinfo_2() == false) { + return; + } + // read main data. + if(issync()) { + for(register int i=layer3slots;i>0;i--) { + bitwindow.putbyte(getbyte()); + } + } + else { + // read main data. + for(register int i=layer3slots;i>0;i--) { + bitwindow.putbyte(getbits8()); + } + } + + //bitwindow.wrap(); + + main_data_end=bitwindow.gettotalbit()>>3;// of previous frame + if (main_data_end < 0) { + DEBUG_LAYER(printf("main_data_end < 0\n");) + return; + } + + if((flush_main=(bitwindow.gettotalbit() & 0x7))) { + bitwindow.forward(8-flush_main); + main_data_end++; + } + + bytes_to_discard=layer3framestart-(main_data_end+sideinfo.main_data_begin); + if(main_data_end>WINDOWSIZE) { + layer3framestart-=WINDOWSIZE; + bitwindow.rewind(WINDOWSIZE*8); + } + layer3framestart+=layer3slots; + + bitwindow.wrap(); + if(bytes_to_discard<0)return; + bitwindow.forward(bytes_to_discard<<3); + } + + //for(int gr=0;gr<2;gr++) { + ATTR_ALIGN(64) union + { + int is [SBLIMIT][SSLIMIT]; + REAL hin [2][SBLIMIT][SSLIMIT]; + }b1; + ATTR_ALIGN(64) union + { + REAL ro [2][SBLIMIT][SSLIMIT]; + REAL lr [2][SBLIMIT][SSLIMIT]; + REAL hout [2][SSLIMIT][SBLIMIT]; + }b2; + + + layer3part2start=bitwindow.gettotalbit(); + layer3getscalefactors_2(LS); + //dump->dump(&scalefactors[LS]); + + layer3huffmandecode (LS,0 ,b1.is); + //dump->dump(b1.is); + layer3dequantizesample (LS,0,b1.is,b2.ro[LS]); + + if(inputstereo) { + layer3part2start=bitwindow.gettotalbit(); + layer3getscalefactors_2(RS); + layer3huffmandecode (RS,0 ,b1.is); + layer3dequantizesample (RS,0,b1.is,b2.ro[RS]); + } + + layer3fixtostereo(0,b2.ro); // b2.ro -> b2.lr + currentprevblock^=1; + + layer3reorderandantialias(LS,0,b2.lr[LS],b1.hin[LS]); + layer3hybrid (LS,0,b1.hin[LS],b2.hout[LS]); + if(lOutputStereo) { + layer3reorderandantialias(RS,0,b2.lr[RS],b1.hin[RS]); + layer3hybrid (RS,0,b1.hin[RS],b2.hout[RS]); + } + synthesis->doMP3Synth(lDownSample,lOutputStereo,b2.hout); + + +} diff --git a/mpeglib/lib/splay/mpegsound.h b/mpeglib/lib/splay/mpegsound.h new file mode 100644 index 00000000..cd0c3571 --- /dev/null +++ b/mpeglib/lib/splay/mpegsound.h @@ -0,0 +1,248 @@ +// MPEG/WAVE Sound library + +// (C) 1997 by Woo-jae Jung + +// Mpegsound.h +// This is typeset for functions in MPEG/WAVE Sound library. +// Now, it's for only linux-pc-?86 + +/************************************/ +/* Include default library packages */ +/************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + + +#include "mpegAudioStream.h" +#include "common.h" + +class Synthesis; +class AudioFrame; + + +#ifndef _L__SOUND__ +#define _L__SOUND__ + +#include "mpegAudioHeader.h" +#include "mpegAudioBitWindow.h" + + +//#define DEBUG_LAYER(x) x +#define DEBUG_LAYER(x) + + +/**************************/ +/* Define values for MPEG */ +/**************************/ +#define SCALEBLOCK 12 +#define MAXSUBBAND 32 +#define MAXCHANNEL 2 +#define RAWDATASIZE (2*2*2*32*SSLIMIT) + + + +// Huffmancode +#define HTN 34 + + + +#define MODE_MONO 0 +#define MODE_STEREO 1 + +/********************/ +/* Type definitions */ +/********************/ + +typedef struct { + bool generalflag; + unsigned int part2_3_length; + unsigned int big_values; + unsigned int global_gain; + unsigned int scalefac_compress; + unsigned int window_switching_flag; + unsigned int block_type; + unsigned int mixed_block_flag; + unsigned int table_select[3]; + unsigned int subblock_gain[3]; + unsigned int region0_count; + unsigned int region1_count; + unsigned int preflag; + unsigned int scalefac_scale; + unsigned int count1table_select; +}layer3grinfo; + +typedef struct { + unsigned main_data_begin; + unsigned private_bits; + struct { + unsigned scfsi[4]; + layer3grinfo gr[2]; + }ch[2]; +}layer3sideinfo; + +typedef struct { + int l[23]; /* [cb] */ + int s[3][13]; /* [window][cb] */ +}layer3scalefactor; /* [ch] */ + +typedef struct { + int tablename; + unsigned int xlen,ylen; + unsigned int linbits; + unsigned int treelen; + const unsigned int (*val)[2]; +}HUFFMANCODETABLE; + + + + + + + +class DCT; +class Dump; + +// Class for converting mpeg format to raw format +class Mpegtoraw { + /*****************************/ + /* Constant tables for layer */ + /*****************************/ +private: + static const int bitrate[2][3][15]; + static const int frequencies[2][3]; + static const REAL scalefactorstable[64]; + static const ATTR_ALIGN(64) HUFFMANCODETABLE ht[HTN]; + + + friend class HuffmanLookup; + + /*************************/ + /* MPEG header variables */ + /*************************/ + + // comes from constructor, decoder works on them + MpegAudioStream* mpegAudioStream; + MpegAudioHeader* mpegAudioHeader; + AudioFrame* audioFrame; + Dump* dump; + Synthesis* synthesis; + + /***************************************/ + /* Interface for setting music quality */ + /***************************************/ + + int lWantStereo; + int lOutputStereo; + int lDownSample; + +public: + Mpegtoraw(MpegAudioStream* mpegAudioStream, + MpegAudioHeader* mpegAudioHeader); + + + ~Mpegtoraw(); + int decode(AudioFrame* audioFrame); + + + void setStereo(int lStereo); + int getStereo(); + + void setDownSample(int lDownSample); + int getDownSample(); + + + +private: + void initialize(); + + + + /*****************************/ + /* Loading MPEG-Audio stream */ + /*****************************/ + + union + { + unsigned char store[4]; + unsigned int current; + }u; + + + int getbyte() { return mpegAudioStream->getbyte(); } + int getbits(int bits) { return mpegAudioStream->getbits(bits); } + int getbits9(int bits) { return mpegAudioStream->getbits9(bits); } + int getbits8() { return mpegAudioStream->getbits8(); } + int getbit() { return mpegAudioStream->getbit(); } + + + void sync() { mpegAudioStream->sync(); } + bool issync() { return mpegAudioStream->issync(); } + + + /********************/ + /* Global variables */ + /********************/ + + // optimisation from maplay12+ + // 0/1: nonzero for channel 0/1 2: max position for both + int nonzero[3]; + + // for Layer3 + + int layer3framestart; + int layer3part2start; + + ATTR_ALIGN(64) REAL prevblck[2][2][SBLIMIT][SSLIMIT]; + int currentprevblock; + ATTR_ALIGN(64) layer3sideinfo sideinfo; + ATTR_ALIGN(64) layer3scalefactor scalefactors[2]; + + ATTR_ALIGN(64) MpegAudioBitWindow bitwindow; + MpegAudioBitWindow lastValidBitwindow; + + int wgetbit(void); + int wgetbits9(int bits); + int wgetbits(int bits); + int wgetCanReadBits(); + + /*************************************/ + /* Decoding functions for each layer */ + /*************************************/ + + // Extractor + void extractlayer1(void); // MPEG-1 + void extractlayer2(void); + void extractlayer3(void); + void extractlayer3_2(void); // MPEG-2 + + + // Functions for layer 3 + void layer3initialize(void); + bool layer3getsideinfo(void); + bool layer3getsideinfo_2(void); + void layer3getscalefactors(int ch,int gr); + void layer3getscalefactors_2(int ch); + void layer3huffmandecode(int ch,int gr,int out[SBLIMIT][SSLIMIT]); + REAL layer3twopow2(int scale,int preflag,int pretab_offset,int l); + REAL layer3twopow2_1(int a,int b,int c); + void layer3dequantizesample(int ch,int gr,int in[SBLIMIT][SSLIMIT], + REAL out[SBLIMIT][SSLIMIT]); + void adjustNonZero(REAL in[2][SBLIMIT][SSLIMIT]); + void layer3fixtostereo(int gr,REAL in[2][SBLIMIT][SSLIMIT]); + void layer3reorderandantialias(int ch,int gr,REAL in[SBLIMIT][SSLIMIT], + REAL out[SBLIMIT][SSLIMIT]); + + void layer3hybrid(int ch,int gr,REAL in[SBLIMIT][SSLIMIT], + REAL out[SSLIMIT][SBLIMIT]); + + void huffmandecoder_1(const HUFFMANCODETABLE *h,int *x,int *y); + void huffmandecoder_2(const HUFFMANCODETABLE *h,int *x,int *y,int *v,int *w); + +}; + + + +#endif diff --git a/mpeglib/lib/splay/mpegtable.cpp b/mpeglib/lib/splay/mpegtable.cpp new file mode 100644 index 00000000..be539ddd --- /dev/null +++ b/mpeglib/lib/splay/mpegtable.cpp @@ -0,0 +1,35 @@ +/* MPEG/WAVE Sound library + + (C) 1997 by Jung woo-jae */ + +// Mpegtable.cc +// It has tables for MPEG layer 1, 2 and a part of layer 3 + + +#include "mpegsound.h" + + + +// Mpeg general table +const REAL Mpegtoraw::scalefactorstable[64] = +{ + 2.00000000000000, 1.58740105196820, 1.25992104989487, 1.00000000000000, + 0.79370052598410, 0.62996052494744, 0.50000000000000, 0.39685026299205, + 0.31498026247372, 0.25000000000000, 0.19842513149602, 0.15749013123686, + 0.12500000000000, 0.09921256574801, 0.07874506561843, 0.06250000000000, + 0.04960628287401, 0.03937253280921, 0.03125000000000, 0.02480314143700, + 0.01968626640461, 0.01562500000000, 0.01240157071850, 0.00984313320230, + 0.00781250000000, 0.00620078535925, 0.00492156660115, 0.00390625000000, + 0.00310039267963, 0.00246078330058, 0.00195312500000, 0.00155019633981, + 0.00123039165029, 0.00097656250000, 0.00077509816991, 0.00061519582514, + 0.00048828125000, 0.00038754908495, 0.00030759791257, 0.00024414062500, + 0.00019377454248, 0.00015379895629, 0.00012207031250, 0.00009688727124, + 0.00007689947814, 0.00006103515625, 0.00004844363562, 0.00003844973907, + 0.00003051757813, 0.00002422181781, 0.00001922486954, 0.00001525878906, + 0.00001211090890, 0.00000961243477, 0.00000762939453, 0.00000605545445, + 0.00000480621738, 0.00000381469727, 0.00000302772723, 0.00000240310869, + 0.00000190734863, 0.00000151386361, 0.00000120155435, 0.00000000000000 +}; + + + diff --git a/mpeglib/lib/splay/mpegtoraw.cpp b/mpeglib/lib/splay/mpegtoraw.cpp new file mode 100644 index 00000000..93143bbe --- /dev/null +++ b/mpeglib/lib/splay/mpegtoraw.cpp @@ -0,0 +1,127 @@ +/* MPEG/WAVE Sound library + + (C) 1997 by Jung woo-jae */ + +// Mpegtoraw.cc +// Server which get mpeg format and put raw format. + + +#include "mpegsound.h" +#include "synthesis.h" +#include "dump.h" +#include "../frame/audioFrame.h" + +#include <iostream> + +using namespace std; + +Mpegtoraw::Mpegtoraw(MpegAudioStream* mpegAudioStream, + MpegAudioHeader* mpegAudioHeader) { + + this->mpegAudioStream=mpegAudioStream; + this->mpegAudioHeader=mpegAudioHeader; + + this->lOutputStereo=true; + setStereo(true); + setDownSample(false); + + dump=new Dump(); + synthesis=new Synthesis(); + initialize(); + +} + +Mpegtoraw::~Mpegtoraw() { + + delete synthesis; + delete dump; +} + + + + + + + +void Mpegtoraw::setStereo(int flag) { + lWantStereo=flag; +} + +void Mpegtoraw::setDownSample(int flag) { + lDownSample=flag; +} + +int Mpegtoraw::getStereo() { + return lWantStereo; +} + +int Mpegtoraw::getDownSample() { + return lDownSample; +} + + + + + + + +// Convert mpeg to raw +// Mpeg headder class +void Mpegtoraw::initialize() { + + + + layer3initialize(); + + +} + + + + + +// Convert mpeg to raw +int Mpegtoraw::decode(AudioFrame* audioFrame) { + int back=true; + + this->audioFrame=audioFrame; + if (audioFrame->getSize() < RAWDATASIZE) { + cout << "audioFrame needs at least:"<<RAWDATASIZE<<" size"<<endl; + exit(0); + } + + audioFrame->clearrawdata(); + synthesis->clearrawdata(); + + int layer=mpegAudioHeader->getLayer(); + this->lOutputStereo=lWantStereo & mpegAudioHeader->getInputstereo(); + + if (mpegAudioHeader->getProtection()==false) { + mpegAudioStream->getbyte(); + mpegAudioStream->getbyte(); + } + switch(layer) { + case 3: + extractlayer3(); + break; + case 2: + extractlayer2(); + break; + case 1: + extractlayer1(); + break; + default: + cout << "unknown layer:"<<layer<<endl; + back=false; + } + + // + // Now put the frequencies/output etc.. in the frame + // + audioFrame->setFrameFormat(lOutputStereo, + mpegAudioHeader->getFrequencyHz()>>lDownSample); + + audioFrame->putFloatData(synthesis->getOutputData(),synthesis->getLen()); + return back; + +} diff --git a/mpeglib/lib/splay/op.h b/mpeglib/lib/splay/op.h new file mode 100644 index 00000000..a741e97b --- /dev/null +++ b/mpeglib/lib/splay/op.h @@ -0,0 +1,96 @@ +/* + unrolled operations, for better Pentium FPU scheduling + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef __OP_H +#define __OP_H + +/** + The Pentium has two pipelined FPUs which makes it possible + to do two operations in one cycle. + (If you are lucky) + +*/ + +#define PTR_DIST (1024) + +#define OS r1=vp1[0] * dp[0]; \ + r2=vp1[PTR_DIST-0] * dp[0]; \ + dp++; + +#define XX1 vp1+=15;dp++; + +#define XX2 r1+=vp1[0] * dp[-1]; \ + r2+=vp1[PTR_DIST-0] * dp[-1]; + +#define OP_END(val) vp1-=val;dp+=val; + +#define OP_END_1(vVal,dVal) vp1+=(vVal-dVal),dp+=dVal + + +// this is OP_END(x);XX1; together: +#define OP_END_2(vVal) vp1+=(15-vVal),dp+=vVal+1 + + +// check this to test pipelining + +#define SCHEDULE1(op,r1,r2) r1;op;r2; +#define SCHEDULE2(op,r1,r2) op;r1;r2; + +#define SCHEDULE(a,b,c) SCHEDULE2(a,b,c); + + +#define OP r1+=vp1[-1] * dp[0]; \ + r2+=vp1[PTR_DIST-1] * dp[0]; + + + +#define OP2 SCHEDULE(OP ,r1+=vp1[-2] * dp[1] ,r2+=vp1[PTR_DIST-2] *dp[1]); +#define OP3 SCHEDULE(OP2 ,r1+=vp1[-3] * dp[2] ,r2+=vp1[PTR_DIST-3] *dp[2]); +#define OP4 SCHEDULE(OP3 ,r1+=vp1[-4] * dp[3] ,r2+=vp1[PTR_DIST-4] *dp[3]); +#define OP5 SCHEDULE(OP4 ,r1+=vp1[-5] * dp[4] ,r2+=vp1[PTR_DIST-5] *dp[4]); +#define OP6 SCHEDULE(OP5 ,r1+=vp1[-6] * dp[5] ,r2+=vp1[PTR_DIST-6] *dp[5]); +#define OP7 SCHEDULE(OP6 ,r1+=vp1[-7] * dp[6] ,r2+=vp1[PTR_DIST-7] *dp[6]); +#define OP8 SCHEDULE(OP7 ,r1+=vp1[-8] * dp[7] ,r2+=vp1[PTR_DIST-8] *dp[7]); +#define OP9 SCHEDULE(OP8 ,r1+=vp1[-9] * dp[8] ,r2+=vp1[PTR_DIST-9] *dp[8]); +#define OP10 SCHEDULE(OP9 ,r1+=vp1[-10] * dp[9] ,r2+=vp1[PTR_DIST-10] *dp[9]); +#define OP11 SCHEDULE(OP10,r1+=vp1[-11] * dp[10],r2+=vp1[PTR_DIST-11] *dp[10]); +#define OP12 SCHEDULE(OP11,r1+=vp1[-12] * dp[11],r2+=vp1[PTR_DIST-12] *dp[11]); +#define OP13 SCHEDULE(OP12,r1+=vp1[-13] * dp[12],r2+=vp1[PTR_DIST-13] *dp[12]); +#define OP14 SCHEDULE(OP13,r1+=vp1[-14] * dp[13],r2+=vp1[PTR_DIST-14] *dp[13]); +#define OP15 SCHEDULE(OP14,r1+=vp1[-15] * dp[14],r2+=vp1[PTR_DIST-15] *dp[14]); + + +/* +#define OP r1+=vp1[-1] * dp[0]; \ + r2+=vp2[-1] * dp[0]; + + + +#define OP2 SCHEDULE(OP ,r1+=vp1[-2] * dp[1] ,r2+=vp2[-2] * dp[1]); +#define OP3 SCHEDULE(OP2 ,r1+=vp1[-3] * dp[2] ,r2+=vp2[-3] * dp[2]); +#define OP4 SCHEDULE(OP3 ,r1+=vp1[-4] * dp[3] ,r2+=vp2[-4] * dp[3]); +#define OP5 SCHEDULE(OP4 ,r1+=vp1[-5] * dp[4] ,r2+=vp2[-5] * dp[4]); +#define OP6 SCHEDULE(OP5 ,r1+=vp1[-6] * dp[5] ,r2+=vp2[-6] * dp[5]); +#define OP7 SCHEDULE(OP6 ,r1+=vp1[-7] * dp[6] ,r2+=vp2[-7] * dp[6]); +#define OP8 SCHEDULE(OP7 ,r1+=vp1[-8] * dp[7] ,r2+=vp2[-8] * dp[7]); +#define OP9 SCHEDULE(OP8 ,r1+=vp1[-9] * dp[8] ,r2+=vp2[-9] * dp[8]); +#define OP10 SCHEDULE(OP9 ,r1+=vp1[-10] * dp[9] ,r2+=vp2[-10] * dp[9]); +#define OP11 SCHEDULE(OP10,r1+=vp1[-11] * dp[10],r2+=vp2[-11] * dp[10]); +#define OP12 SCHEDULE(OP11,r1+=vp1[-12] * dp[11],r2+=vp2[-12] * dp[11]); +#define OP13 SCHEDULE(OP12,r1+=vp1[-13] * dp[12],r2+=vp2[-13] * dp[12]); +#define OP14 SCHEDULE(OP13,r1+=vp1[-14] * dp[13],r2+=vp2[-14] * dp[13]); +#define OP15 SCHEDULE(OP14,r1+=vp1[-15] * dp[14],r2+=vp2[-15] * dp[14]); +*/ + +#endif diff --git a/mpeglib/lib/splay/sigsev.c b/mpeglib/lib/splay/sigsev.c new file mode 100644 index 00000000..906d8cb9 --- /dev/null +++ b/mpeglib/lib/splay/sigsev.c @@ -0,0 +1,29 @@ +/* + No SegFault: + + g++ -o sigsev.exe sigsevTest.cpp + + SegFault: + + g++ -o sigsev.exe -O6 sigsevTest.cpp + */ + +#include <stdio.h> +#undef __NO_MATH_INLINES // <<<< Add this line +#define __NO_MATH_INLINES 1 // <<<< and this. +#include <math.h> + + +int main() { + printf("hello Martin test->main\n"); + + //pow(6.0,3.0); + float value; + value=cos(double(0)); + printf("Wert: %f\n",value); + pow(6.0,3.0); + + printf("hi:\n"); + exit(0); +} + diff --git a/mpeglib/lib/splay/splayDecoder.cpp b/mpeglib/lib/splay/splayDecoder.cpp new file mode 100644 index 00000000..13d6de1b --- /dev/null +++ b/mpeglib/lib/splay/splayDecoder.cpp @@ -0,0 +1,73 @@ +/* + decoder interface for the splay mp3 decoder. + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + +#define _FROM_SOURCE +#include "dxHead.h" +#include "splayDecoder.h" +#include "mpegsound.h" + + + +SplayDecoder::SplayDecoder() { + header = new MpegAudioHeader(); + stream = new MpegAudioStream(); + server = new Mpegtoraw(stream,header); + + xHeadData=new XHEADDATA(); + xHeadData->toc=new unsigned char[101]; + dump=new Dump(); +} + + +SplayDecoder::~SplayDecoder() { + delete [] xHeadData->toc; + delete xHeadData; + + delete server; + delete header; + delete stream; + delete dump; +} + + + +int SplayDecoder::decode(unsigned char* ptr, int len,AudioFrame* dest) { + int back; + // fist setup the stream and the 4 bytes header info; + //dump->dump((char*)ptr,len); + if (header->parseHeader(ptr) == false) { + return false; + } + // maybe a Xing Header? + if (len >= 152+4) { + int lXing=GetXingHeader(xHeadData,(unsigned char*)ptr); + if (lXing) { + return false; + } + } + stream->setFrame(ptr+4,len-4); + back=server->decode(dest); + + return back; + +} + + +void SplayDecoder::config(const char* key,const char* val,void* ) { + if (strcmp(key,"2")==0) { + server->setDownSample(atoi(val)); + } + if (strcmp(key,"m")==0) { + server->setStereo(atoi(val)); + } +} + diff --git a/mpeglib/lib/splay/splayDecoder.h b/mpeglib/lib/splay/splayDecoder.h new file mode 100644 index 00000000..acbfdbfc --- /dev/null +++ b/mpeglib/lib/splay/splayDecoder.h @@ -0,0 +1,70 @@ +/* + decoder interface for the splay mp3 decoder. + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + + +#ifndef __SPLAYDECODER_H +#define __SPLAYDECODER_H + +// state definitions for splay decoder + +#define _SPLAY_RESET 0 +#define _SPLAY_EOF 1 +#define _SPLAY_FIRSTINIT 2 +#define _SPLAY_REINIT 3 +#define _SPLAY_DECODE 4 +#define _SPLAY_FRAME 5 + + +#include "../frame/audioFrame.h" +#include "dump.h" +#include <string.h> +#include <kdemacros.h> + +class Mpegtoraw; +class MpegAudioStream; +class MpegAudioHeader; + + +/** + The decoder interface. + The decoder expects an mpeg audio frame. + The call to decode is "atomic", after that you have + a PCMFrame to play. + +*/ + + + +class KDE_EXPORT SplayDecoder { + + MpegAudioStream* stream; + MpegAudioHeader* header; + Mpegtoraw* server; + Dump* dump; +#ifdef _FROM_SOURCE + XHEADDATA* xHeadData; +#else + void* xHeadData; +#endif + + + public: + SplayDecoder(); + ~SplayDecoder(); + + int decode(unsigned char* ptr, int len,AudioFrame* dest); + void config(const char* key,const char* val,void* ret); + +}; +#endif diff --git a/mpeglib/lib/splay/synth_Down.cpp b/mpeglib/lib/splay/synth_Down.cpp new file mode 100644 index 00000000..fbe3887b --- /dev/null +++ b/mpeglib/lib/splay/synth_Down.cpp @@ -0,0 +1,231 @@ +/* + downsample implementation + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "synthesis.h" +#include "dct64_down.cpp" + +#include <iostream> + +using namespace std; + + +void Synthesis::computebuffer_Down(REAL *fraction, + REAL buffer[2][CALCBUFFERSIZE]){ + REAL *out1,*out2; + + out1=buffer[currentcalcbuffer]+calcbufferoffset; + out2=buffer[currentcalcbuffer^1]+calcbufferoffset; + dct64_downsample(out1,out2,fraction); +} + + + +#define SAVE putraw(r); \ + dp+=16;vp+=15+(15-14) +#define OS r=*vp * *dp++ +#define XX vp+=15;r+=*vp * *dp++ +#define OP r+=*--vp * *dp++ + +inline void Synthesis::generatesingle_Down(void) +{ + int i; + register REAL r, *vp; + register const REAL *dp; + + i=32/2; + dp=filter; + vp=calcbuffer[LS][currentcalcbuffer]+calcbufferoffset; +// actual_v+actual_write_pos; + + switch (calcbufferoffset) + { + case 0:for(;i;i--,vp+=15){ + OS;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 1:for(;i;i--,vp+=15){ + OS;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 2:for(;i;i--,vp+=15){ + OS;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 3:for(;i;i--,vp+=15){ + OS;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 4:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 5:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 6:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 7:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 8:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 9:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP; + SAVE;}break; + case 10:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP; + SAVE;}break; + case 11:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP; + SAVE;}break; + case 12:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP; + SAVE;}break; + case 13:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP; + SAVE;}break; + case 14:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX; + SAVE;}break; + case 15:for(;i;i--,vp+=31){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + } +} + +#undef OS +#undef XX +#undef OP +#undef SAVE + +#define SAVE \ + putraw(r1); \ + putraw(r2); \ + dp+=16;vp1+=15+(15-14);vp2+=15+(15-14) +#define OS r1=*vp1 * *dp; \ + r2=*vp2 * *dp++ +#define XX vp1+=15;r1+=*vp1 * *dp; \ + vp2+=15;r2+=*vp2 * *dp++ +#define OP r1+=*--vp1 * *dp; \ + r2+=*--vp2 * *dp++ + + +inline void Synthesis::generate_Down(void) +{ + int i; + REAL r1,r2; + register REAL *vp1,*vp2; + register const REAL *dp; + + dp=filter; + vp1=calcbuffer[LS][currentcalcbuffer]+calcbufferoffset; + vp2=calcbuffer[RS][currentcalcbuffer]+calcbufferoffset; +// actual_v+actual_write_pos; + + i=32/2; + switch (calcbufferoffset) + { + case 0:for(;i;i--,vp1+=15,vp2+=15){ + OS;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 1:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 2:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 3:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 4:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 5:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 6:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 7:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 8:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 9:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP; + SAVE;}break; + case 10:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP; + SAVE;}break; + case 11:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP; + SAVE;}break; + case 12:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP; + SAVE;}break; + case 13:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP; + SAVE;}break; + case 14:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX; + SAVE;}break; + case 15:for(;i;i--,vp1+=31,vp2+=31){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + } +} + + + +void Synthesis::synth_Down(int lOutputStereo,REAL *fractionL,REAL *fractionR) { + switch(lOutputStereo) { + case true: + computebuffer_Down(fractionL,calcbuffer[LS]); + computebuffer_Down(fractionR,calcbuffer[RS]); + generate_Down(); + nextOffset(); + break; + case false: + computebuffer_Down(fractionL,calcbuffer[LS]); + generatesingle_Down(); + nextOffset(); + break; + default: + cout << "unknown lOutputStereo in Synthesis::synth_Std"<<endl; + exit(0); + } +} + + +void Synthesis::synthMP3_Down(int lOutputStereo, + REAL hout [2][SSLIMIT][SBLIMIT]) { + int ss; + switch(lOutputStereo) { + case true: + for(ss=0;ss<SSLIMIT;ss++) { + computebuffer_Down(hout[LS][ss],calcbuffer[LS]); + computebuffer_Down(hout[RS][ss],calcbuffer[RS]); + generate_Down(); + nextOffset(); + } + break; + case false: + for(ss=0;ss<SSLIMIT;ss++) { + computebuffer_Down(hout[LS][ss],calcbuffer[LS]); + generatesingle_Down(); + nextOffset(); + } + break; + default: + cout << "unknown lOutputStereo in Synthesis::synth_Std"<<endl; + exit(0); + } +} diff --git a/mpeglib/lib/splay/synth_Std.cpp b/mpeglib/lib/splay/synth_Std.cpp new file mode 100644 index 00000000..6ea1d027 --- /dev/null +++ b/mpeglib/lib/splay/synth_Std.cpp @@ -0,0 +1,330 @@ +/* + std synth implementation + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#include "synthesis.h" + + + +#include "dct64.cpp" + +#include <iostream> + +using namespace std; + +inline void Synthesis::computebuffer_Std(REAL *fraction, + REAL buffer[2][CALCBUFFERSIZE]) { + REAL *out1,*out2; + out1=buffer[currentcalcbuffer]+calcbufferoffset; + out2=buffer[currentcalcbuffer^1]+calcbufferoffset; + dct64(out1,out2,fraction); +} + + +#define SAVE putraw(r); +#define OS r=*vp * *dp++ +#define XX vp+=15;r+=*vp * *dp++ +#define OP r+=*--vp * *dp++ + + +inline void Synthesis::generatesingle_Std(void) { + int i; + register REAL r, *vp; + register const REAL *dp; + + i=32; + dp=filter; + vp=calcbuffer[LS][currentcalcbuffer]+calcbufferoffset; +// actual_v+actual_write_pos; + + switch (calcbufferoffset) + { + case 0:for(;i;i--,vp+=15){ + OS;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 1:for(;i;i--,vp+=15){ + OS;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 2:for(;i;i--,vp+=15){ + OS;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 3:for(;i;i--,vp+=15){ + OS;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 4:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 5:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 6:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 7:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 8:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 9:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP; + SAVE;}break; + case 10:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP; + SAVE;}break; + case 11:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP; + SAVE;}break; + case 12:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP; + SAVE;}break; + case 13:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP; + SAVE;}break; + case 14:for(;i;i--,vp+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX; + SAVE;}break; + case 15:for(;i;i--,vp+=31){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + } +} + +#undef OS +#undef XX +#undef OP +#undef SAVE + + +#define SAVE putraw(r1); putraw(r2); + +#define OS r1=*vp1 * *dp; \ + r2=*vp2 * *dp++ +#define XX vp1+=15;r1+=*vp1 * *dp; \ + vp2+=15;r2+=*vp2 * *dp++ +#define OP r1+=*--vp1 * *dp; \ + r2+=*--vp2 * *dp++ + +/* +inline void Synthesis::generate_old(void) +{ + int i; + REAL r1,r2; + register REAL *vp1,*vp2; + register const REAL *dp; + + dp=filter; + vp1=calcbuffer[LS][currentcalcbuffer]+calcbufferoffset; + vp2=calcbuffer[RS][currentcalcbuffer]+calcbufferoffset; +// actual_v+actual_write_pos; + + i=32; + switch (calcbufferoffset) + { + case 0:for(;i;i--,vp1+=15,vp2+=15){ + OS;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 1:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 2:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 3:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 4:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 5:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 6:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 7:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 8:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP;OP; + SAVE;}break; + case 9:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP;OP; + SAVE;}break; + case 10:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP;OP; + SAVE;}break; + case 11:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP;OP; + SAVE;}break; + case 12:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP;OP; + SAVE;}break; + case 13:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX;OP; + SAVE;}break; + case 14:for(;i;i--,vp1+=15,vp2+=15){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;XX; + SAVE;}break; + case 15:for(;i;i--,vp1+=31,vp2+=31){ + OS;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP;OP; + SAVE;}break; + } +} +*/ +#undef OS +#undef XX +#undef OP +#undef SAVE + +#include "op.h" +#define SAVE putraw(r1); putraw(r2); + +inline void Synthesis::generate_Std(void) +{ + int i; + REAL r1,r2; + + register REAL *vp1; + register const REAL *dp; + + dp=filter; + vp1=calcbuffer[LS][currentcalcbuffer]+calcbufferoffset; + // we calculate cp2 from vp1 because they are both + // in the same array. code was: + // register REAL* vp2 + //vp2=calcbuffer[RS][currentcalcbuffer]+calcbufferoffset; + + i=32; + switch (calcbufferoffset) + { + case 0:for(;i;i--,OP_END_1(15,14)){ + OS;XX1;XX2;OP14; + SAVE;}break; + case 1:for(;i;i--,OP_END_1(15,13)){ + OS;OP;OP_END_2(1);XX2;OP13; + SAVE;}break; + case 2:for(;i;i--,OP_END_1(15,12)){ + OS;OP2;OP_END_2(2);XX2;OP12; + SAVE;}break; + case 3:for(;i;i--,OP_END_1(15,11)){ + OS;OP3;OP_END_2(3);XX2;OP11; + SAVE;}break; + case 4:for(;i;i--,OP_END_1(15,10)){ + OS;OP4;OP_END_2(4);XX2;OP10; + SAVE;}break; + case 5:for(;i;i--,OP_END_1(15,9)){ + OS;OP5;OP_END_2(5);XX2;OP9; + SAVE;}break; + case 6:for(;i;i--,OP_END_1(15,8)){ + OS;OP6;OP_END_2(6);XX2;OP8; + SAVE;}break; + case 7:for(;i;i--,OP_END_1(15,7)){ + OS;OP7;OP_END_2(7);XX2;OP7; + SAVE;}break; + case 8:for(;i;i--,OP_END_1(15,6)){ + OS;OP8;OP_END_2(8);XX2;OP6; + SAVE;}break; + case 9:for(;i;i--,OP_END_1(15,5)){ + OS;OP9;OP_END_2(9);XX2;OP5; + SAVE;}break; + case 10:for(;i;i--,OP_END_1(15,4)){ + OS;OP10;OP_END_2(10);XX2;OP4; + SAVE;}break; + case 11:for(;i;i--,OP_END_1(15,3)){ + OS;OP11;OP_END_2(11);XX2;OP3; + SAVE;}break; + case 12:for(;i;i--,OP_END_1(15,2)){ + OS;OP12;OP_END_2(12);XX2;OP2; + SAVE;}break; + case 13:for(;i;i--,OP_END_1(15,1)){ + OS;OP13;OP_END_2(13);XX2;OP; + SAVE;}break; + case 14:for(;i;i--,vp1+=15){ + OS;OP14;OP_END_2(14);XX2; + SAVE;}break; + case 15:for(;i;i--,OP_END_1(31,15)){ + OS;OP15; + SAVE;}break; + } +} +#undef OP_END_1 +#undef OP_END_2 +#undef OP +#undef OP1 +#undef OP2 +#undef OP3 +#undef OP4 +#undef OP5 +#undef OP6 +#undef OP7 +#undef OP8 +#undef OP9 +#undef OP10 +#undef OP11 +#undef OP12 +#undef OP13 +#undef OP14 +#undef OP15 +#undef OS +#undef XX1 +#undef XX2 +#undef SCHEDULE +#undef SCHEDULE1 +#undef SCHEDULE2 +#undef SAVE + +void Synthesis::synth_Std(int lOutputStereo,REAL *fractionL,REAL *fractionR) { + switch(lOutputStereo) { + case true: + computebuffer_Std(fractionL,calcbuffer[LS]); + computebuffer_Std(fractionR,calcbuffer[RS]); + generate_Std(); + nextOffset(); + break; + case false: + computebuffer_Std(fractionL,calcbuffer[LS]); + generatesingle_Std(); + nextOffset(); + break; + default: + cout << "unknown lOutputStereo in Synthesis::synth_Std"<<endl; + exit(0); + } +} + + +void Synthesis::synthMP3_Std(int lOutputStereo, + REAL hout [2][SSLIMIT][SBLIMIT]) { + int ss; + switch(lOutputStereo) { + case true: + for(ss=0;ss<SSLIMIT;ss++) { + computebuffer_Std(hout[LS][ss],calcbuffer[LS]); + computebuffer_Std(hout[RS][ss],calcbuffer[RS]); + generate_Std(); + nextOffset(); + } + break; + case false: + for(ss=0;ss<SSLIMIT;ss++) { + computebuffer_Std(hout[LS][ss],calcbuffer[LS]); + generatesingle_Std(); + nextOffset(); + } + break; + default: + cout << "unknown lOutputStereo in Synthesis::synth_Std"<<endl; + exit(0); + } +} diff --git a/mpeglib/lib/splay/synth_filter.cpp b/mpeglib/lib/splay/synth_filter.cpp new file mode 100644 index 00000000..47455288 --- /dev/null +++ b/mpeglib/lib/splay/synth_filter.cpp @@ -0,0 +1,147 @@ +/* + filer definition + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "synthesis.h" + + +ATTR_ALIGN(64) const REAL Synthesis::filter[512]= +{ + 0.000000000, -0.000442505, 0.003250122, -0.007003784, + 0.031082153, -0.078628540, 0.100311279, -0.572036743, + 1.144989014, 0.572036743, 0.100311279, 0.078628540, + 0.031082153, 0.007003784, 0.003250122, 0.000442505, + -0.000015259, -0.000473022, 0.003326416, -0.007919312, + 0.030517578, -0.084182739, 0.090927124, -0.600219727, + 1.144287109, 0.543823242, 0.108856201, 0.073059082, + 0.031478882, 0.006118774, 0.003173828, 0.000396729, + -0.000015259, -0.000534058, 0.003387451, -0.008865356, + 0.029785156, -0.089706421, 0.080688477, -0.628295898, + 1.142211914, 0.515609741, 0.116577148, 0.067520142, + 0.031738281, 0.005294800, 0.003082275, 0.000366211, + -0.000015259, -0.000579834, 0.003433228, -0.009841919, + 0.028884888, -0.095169067, 0.069595337, -0.656219482, + 1.138763428, 0.487472534, 0.123474121, 0.061996460, + 0.031845093, 0.004486084, 0.002990723, 0.000320435, + -0.000015259, -0.000625610, 0.003463745, -0.010848999, + 0.027801514, -0.100540161, 0.057617188, -0.683914185, + 1.133926392, 0.459472656, 0.129577637, 0.056533813, + 0.031814575, 0.003723145, 0.002899170, 0.000289917, + -0.000015259, -0.000686646, 0.003479004, -0.011886597, + 0.026535034, -0.105819702, 0.044784546, -0.711318970, + 1.127746582, 0.431655884, 0.134887695, 0.051132202, + 0.031661987, 0.003005981, 0.002792358, 0.000259399, + -0.000015259, -0.000747681, 0.003479004, -0.012939453, + 0.025085449, -0.110946655, 0.031082153, -0.738372803, + 1.120223999, 0.404083252, 0.139450073, 0.045837402, + 0.031387329, 0.002334595, 0.002685547, 0.000244141, + -0.000030518, -0.000808716, 0.003463745, -0.014022827, + 0.023422241, -0.115921021, 0.016510010, -0.765029907, + 1.111373901, 0.376800537, 0.143264771, 0.040634155, + 0.031005859, 0.001693726, 0.002578735, 0.000213623, + -0.000030518, -0.000885010, 0.003417969, -0.015121460, + 0.021575928, -0.120697021, 0.001068115, -0.791213989, + 1.101211548, 0.349868774, 0.146362305, 0.035552979, + 0.030532837, 0.001098633, 0.002456665, 0.000198364, + -0.000030518, -0.000961304, 0.003372192, -0.016235352, + 0.019531250, -0.125259399, -0.015228271, -0.816864014, + 1.089782715, 0.323318481, 0.148773193, 0.030609131, + 0.029937744, 0.000549316, 0.002349854, 0.000167847, + -0.000030518, -0.001037598, 0.003280640, -0.017349243, + 0.017257690, -0.129562378, -0.032379150, -0.841949463, + 1.077117920, 0.297210693, 0.150497437, 0.025817871, + 0.029281616, 0.000030518, 0.002243042, 0.000152588, + -0.000045776, -0.001113892, 0.003173828, -0.018463135, + 0.014801025, -0.133590698, -0.050354004, -0.866363525, + 1.063217163, 0.271591187, 0.151596069, 0.021179199, + 0.028533936, -0.000442505, 0.002120972, 0.000137329, + -0.000045776, -0.001205444, 0.003051758, -0.019577026, + 0.012115479, -0.137298584, -0.069168091, -0.890090942, + 1.048156738, 0.246505737, 0.152069092, 0.016708374, + 0.027725220, -0.000869751, 0.002014160, 0.000122070, + -0.000061035, -0.001296997, 0.002883911, -0.020690918, + 0.009231567, -0.140670776, -0.088775635, -0.913055420, + 1.031936646, 0.221984863, 0.151962280, 0.012420654, + 0.026840210, -0.001266479, 0.001907349, 0.000106812, + -0.000061035, -0.001388550, 0.002700806, -0.021789551, + 0.006134033, -0.143676758, -0.109161377, -0.935195923, + 1.014617920, 0.198059082, 0.151306152, 0.008316040, + 0.025909424, -0.001617432, 0.001785278, 0.000106812, + -0.000076294, -0.001480103, 0.002487183, -0.022857666, + 0.002822876, -0.146255493, -0.130310059, -0.956481934, + 0.996246338, 0.174789429, 0.150115967, 0.004394531, + 0.024932861, -0.001937866, 0.001693726, 0.000091553, + -0.000076294, -0.001586914, 0.002227783, -0.023910522, + -0.000686646, -0.148422241, -0.152206421, -0.976852417, + 0.976852417, 0.152206421, 0.148422241, 0.000686646, + 0.023910522, -0.002227783, 0.001586914, 0.000076294, + -0.000091553, -0.001693726, 0.001937866, -0.024932861, + -0.004394531, -0.150115967, -0.174789429, -0.996246338, + 0.956481934, 0.130310059, 0.146255493, -0.002822876, + 0.022857666, -0.002487183, 0.001480103, 0.000076294, + -0.000106812, -0.001785278, 0.001617432, -0.025909424, + -0.008316040, -0.151306152, -0.198059082, -1.014617920, + 0.935195923, 0.109161377, 0.143676758, -0.006134033, + 0.021789551, -0.002700806, 0.001388550, 0.000061035, + -0.000106812, -0.001907349, 0.001266479, -0.026840210, + -0.012420654, -0.151962280, -0.221984863, -1.031936646, + 0.913055420, 0.088775635, 0.140670776, -0.009231567, + 0.020690918, -0.002883911, 0.001296997, 0.000061035, + -0.000122070, -0.002014160, 0.000869751, -0.027725220, + -0.016708374, -0.152069092, -0.246505737, -1.048156738, + 0.890090942, 0.069168091, 0.137298584, -0.012115479, + 0.019577026, -0.003051758, 0.001205444, 0.000045776, + -0.000137329, -0.002120972, 0.000442505, -0.028533936, + -0.021179199, -0.151596069, -0.271591187, -1.063217163, + 0.866363525, 0.050354004, 0.133590698, -0.014801025, + 0.018463135, -0.003173828, 0.001113892, 0.000045776, + -0.000152588, -0.002243042, -0.000030518, -0.029281616, + -0.025817871, -0.150497437, -0.297210693, -1.077117920, + 0.841949463, 0.032379150, 0.129562378, -0.017257690, + 0.017349243, -0.003280640, 0.001037598, 0.000030518, + -0.000167847, -0.002349854, -0.000549316, -0.029937744, + -0.030609131, -0.148773193, -0.323318481, -1.089782715, + 0.816864014, 0.015228271, 0.125259399, -0.019531250, + 0.016235352, -0.003372192, 0.000961304, 0.000030518, + -0.000198364, -0.002456665, -0.001098633, -0.030532837, + -0.035552979, -0.146362305, -0.349868774, -1.101211548, + 0.791213989, -0.001068115, 0.120697021, -0.021575928, + 0.015121460, -0.003417969, 0.000885010, 0.000030518, + -0.000213623, -0.002578735, -0.001693726, -0.031005859, + -0.040634155, -0.143264771, -0.376800537, -1.111373901, + 0.765029907, -0.016510010, 0.115921021, -0.023422241, + 0.014022827, -0.003463745, 0.000808716, 0.000030518, + -0.000244141, -0.002685547, -0.002334595, -0.031387329, + -0.045837402, -0.139450073, -0.404083252, -1.120223999, + 0.738372803, -0.031082153, 0.110946655, -0.025085449, + 0.012939453, -0.003479004, 0.000747681, 0.000015259, + -0.000259399, -0.002792358, -0.003005981, -0.031661987, + -0.051132202, -0.134887695, -0.431655884, -1.127746582, + 0.711318970, -0.044784546, 0.105819702, -0.026535034, + 0.011886597, -0.003479004, 0.000686646, 0.000015259, + -0.000289917, -0.002899170, -0.003723145, -0.031814575, + -0.056533813, -0.129577637, -0.459472656, -1.133926392, + 0.683914185, -0.057617188, 0.100540161, -0.027801514, + 0.010848999, -0.003463745, 0.000625610, 0.000015259, + -0.000320435, -0.002990723, -0.004486084, -0.031845093, + -0.061996460, -0.123474121, -0.487472534, -1.138763428, + 0.656219482, -0.069595337, 0.095169067, -0.028884888, + 0.009841919, -0.003433228, 0.000579834, 0.000015259, + -0.000366211, -0.003082275, -0.005294800, -0.031738281, + -0.067520142, -0.116577148, -0.515609741, -1.142211914, + 0.628295898, -0.080688477, 0.089706421, -0.029785156, + 0.008865356, -0.003387451, 0.000534058, 0.000015259, + -0.000396729, -0.003173828, -0.006118774, -0.031478882, + -0.073059082, -0.108856201, -0.543823242, -1.144287109, + 0.600219727, -0.090927124, 0.084182739, -0.030517578, + 0.007919312, -0.003326416, 0.000473022, 0.000015259 +}; diff --git a/mpeglib/lib/splay/synthesis.cpp b/mpeglib/lib/splay/synthesis.cpp new file mode 100644 index 00000000..699037c9 --- /dev/null +++ b/mpeglib/lib/splay/synthesis.cpp @@ -0,0 +1,73 @@ +/* + header for synthesis + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "synthesis.h" + + +#include <iostream> + +using namespace std; + +Synthesis::Synthesis() { + + int i; + outpos=0; + calcbufferoffset=15; + currentcalcbuffer=0; + + for(i=CALCBUFFERSIZE-1;i>=0;i--) + calcbuffer[LS][0][i]=calcbuffer[LS][1][i]= + calcbuffer[RS][0][i]=calcbuffer[RS][1][i]=0.0; + + initialize_dct64(); + initialize_dct64_downsample(); +} + + +Synthesis::~Synthesis() { +} + + +void Synthesis::doSynth(int lDownSample,int lOutputStereo, + REAL *fractionL,REAL *fractionR) { + switch(lDownSample) { + case false: + synth_Std(lOutputStereo,fractionL,fractionR); + break; + case true: + synth_Down(lOutputStereo,fractionL,fractionR); + break; + default: + cout << "unknown downsample parameter"<<lDownSample<<endl; + exit(0); + } +} + + +void Synthesis::doMP3Synth(int lDownSample,int lOutputStereo, + REAL in[2][SSLIMIT][SBLIMIT]) { + + switch(lDownSample) { + case false: + synthMP3_Std(lOutputStereo,in); + break; + case true: + synthMP3_Down(lOutputStereo,in); + break; + default: + cout << "unknown downsample parameter:"<<lDownSample<<endl; + exit(0); + } +} + + diff --git a/mpeglib/lib/splay/synthesis.h b/mpeglib/lib/splay/synthesis.h new file mode 100644 index 00000000..801d658e --- /dev/null +++ b/mpeglib/lib/splay/synthesis.h @@ -0,0 +1,95 @@ +/* + header for synthesis + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#ifndef __SYNTHESIS_H +#define __SYNTHESIS_H + +#include "common.h" +#include "dct.h" + +#define CALCBUFFERSIZE 512 +// AIX seems to have FRAMESIZE defined +#undef FRAMESIZE + +#define FRAMESIZE (2*2*2*32*18) + + +class Synthesis { + + // + // Subbandsynthesis two calcbuffers for every channel, and two channels. + // calcbufferL[0]=calcbuffer[0] + // calcbufferL[1]=calcbuffer[1] + // calcbufferR[0]=calcbuffer[2] + // calcbufferR[1]=calcbuffer[3] + ATTR_ALIGN(64) REAL calcbuffer[2][2][CALCBUFFERSIZE]; + ATTR_ALIGN(64) int currentcalcbuffer,calcbufferoffset; + static ATTR_ALIGN(64) const REAL filter[512]; + ATTR_ALIGN(64) REAL out[FRAMESIZE]; + int outpos; + + public: + Synthesis(); + ~Synthesis(); + + // mpeg1,2 + void doSynth(int lDownSample,int lOutputStereo, + REAL *fractionL,REAL *fractionR); + + void doMP3Synth(int lDownSample,int lOutputStereo, + REAL in[2][SSLIMIT][SBLIMIT]); + + // put mpeg to raw + inline void putraw(REAL val) { + out[outpos++]=val; + } + + inline REAL* getOutputData() { return out; } + inline void clearrawdata() { outpos=0; } + inline int getLen() { return outpos; } + + + private: + void synth_Down(int lOutputStereo,REAL *fractionL,REAL *fractionR); + void synth_Std(int lOutputStereo,REAL *fractionL,REAL *fractionR); + + void synthMP3_Down(int lOutputStereo,REAL hout [2][SSLIMIT][SBLIMIT]); + void synthMP3_Std(int lOutputStereo,REAL hout [2][SSLIMIT][SBLIMIT]); + + inline void nextOffset() { + calcbufferoffset++; + calcbufferoffset&=0xf; + /* + if (calcbufferoffset<15) { + calcbufferoffset++; + } else { + calcbufferoffset=0; + } + */ + currentcalcbuffer^=1; + } + + + void computebuffer_Std(REAL *fraction,REAL buffer[2][CALCBUFFERSIZE]); + void generate_Std(void); + void generatesingle_Std(void); + + void computebuffer_Down(REAL *fraction,REAL buffer[2][CALCBUFFERSIZE]); + void generate_Down(void); + void generatesingle_Down(void); + + +}; + +#endif diff --git a/mpeglib/lib/splay/window.cpp b/mpeglib/lib/splay/window.cpp new file mode 100644 index 00000000..b95dbdcf --- /dev/null +++ b/mpeglib/lib/splay/window.cpp @@ -0,0 +1,70 @@ +/* + wrapper for window functions + Copyright (C) 2001 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + +#include "mpegsound.h" + + +static int windowInit=0; + +ATTR_ALIGN(64) REAL win[4][36]; +ATTR_ALIGN(64) REAL winINV[4][36]; + + +void initialize_win() { + if (windowInit==true) { + return; + } + windowInit=true; + + int i; + + for(i=0;i<18;i++) { + /* + win[0][i]=win[1][i]=0.5*sin(PI_72*(double)(2*i+1))/ + cos(PI_72*(double)(2*i+19)); + */ + win[0][i]=win[1][i]=0.5*sin(PI_72*(double)(2*(i+0)+1))/cos(MY_PI * (double) (2*(i+0) +19) / 72.0 ); + win[0][i+18] = win[3][i+18] = 0.5 * sin( MY_PI / 72.0 * (double) (2*(i+18)+1) ) / cos ( MY_PI * (double) (2*(i+18)+19) / 72.0 ); + } + /* + for(;i<36;i++) { + win[0][i]=win[3][i]=0.5*sin(PI_72*(double)(2*i+1))/cos(PI_72*(double)(2*i+19)); + + } + */ + for(i=0;i<6;i++) { + win[1][i+18]=0.5/cos(MY_PI*(double)(2*(i+18)+19)/72.0); + win[3][i+12]=0.5/cos(MY_PI*(double)(2*(i+12)+19)/72.0); + win[1][i+24]=0.5*sin(PI_24*(double)(2*i+13))/cos(MY_PI*(double)(2*(i+24)+19)/72.0); + win[1][i+30]=win[3][i]=0.0; + win[3][i+6 ]=0.5*sin(PI_24*(double)(2*i+1))/cos(MY_PI*(double)(2*(i+6)+19)/72.0); + } + for(i=0;i<12;i++) + win[2][i]=0.5*sin(PI_24*(double)(2*i+1))/cos(MY_PI*(double)(2*i+7)/24.0); + + int j; + + for(j=0;j<4;j++) { + int len[4] = { 36,36,12,36 }; + for(i=0;i<len[j];i+=2) + winINV[j][i] = + win[j][i]; + for(i=1;i<len[j];i+=2) + winINV[j][i] = - win[j][i]; + } + + +} + + +inline REAL* getSplayWindow(int nr) { return win[nr]; } +inline REAL* getSplayWindowINV(int nr) { return winINV[nr]; } |