📄 mpeglayer3.cpp
字号:
/* 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) #ifdef HAVE_CONFIG_H#include "config.h"#endif#include <math.h>#include <stdlib.h>#include "MPEGaudio.h"#if defined(_WIN32) && defined(_MSC_VER)// disable warnings about double to float conversions#pragma warning(disable: 4244 4305)#endifinline void Mpegbitwindow::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);}#define MUL3(a) (((a)<<1)+(a))#define REAL0 0#define ARRAYSIZE (SBLIMIT*SSLIMIT)#define REALSIZE (sizeof(REAL))#ifdef PI#undef PI#endif#define PI 3.141593#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)#ifdef NATIVE_ASSEMBLYinline 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 (1<<13)static REAL two_to_negative_half_pow[40];static REAL TO_FOUR_THIRDSTABLE[FOURTHIRDSTABLENUMBER*2];static REAL POW2[256];static REAL POW2_1[8][2][16];static REAL ca[8],cs[8];static REAL cos1_6=cos(PI/6.0*1.0);static REAL cos2_6=cos(PI/6.0*2.0);static REAL win[4][36];static REAL cos_18[9];static REAL hsec_36[9],hsec_12[3];typedef struct{ REAL l,r;}RATIOS;static RATIOS rat_1[16],rat_2[2][64];void MPEGaudio::layer3initialize(void){ static bool initializedlayer3=false; register int i; int j,k,l;#if 0 double td = 0.0;printf( "%f\n", td ); //pow( 0.0, 1.333333 );printf( "A\n" ); pow( td, 1.333333 );printf( "B\n" );#endif 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; // Calculate win { 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)); 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(PI_72*(double)(2*(i+18)+19)); win[3][i+12]=0.5/cos(PI_72*(double)(2*(i+12)+19)); win[1][i+24]=0.5*sin(PI_24*(double)(2*i+13))/cos(PI_72*(double)(2*(i+24)+19)); win[1][i+30]=win[3][i]=0.0; win[3][i+6 ]=0.5*sin(PI_24*(double)(2*i+1))/cos(PI_72*(double)(2*(i+6)+19)); } for(i=0;i<12;i++) win[2][i]=0.5*sin(PI_24*(double)(2*i+1))/cos(PI_24*(double)(2*i+7)); } for(i=0;i<9;i++) cos_18[i]=cos(PI_18*double(i)); for(i=0;i<9;i++) hsec_36[i]=0.5/cos(PI_36*double(i*2+1)); for(i=0;i<3;i++) hsec_12[i]=0.5/cos(PI_12*double(i*2+1)); for(i=0;i<40;i++) two_to_negative_half_pow[i]=(REAL)pow(2.0,-0.5*(double)i); { REAL *TO_FOUR_THIRDS=TO_FOUR_THIRDSTABLE+FOURTHIRDSTABLENUMBER;//KR for( i = 0; i < FOURTHIRDSTABLENUMBER; i++ ) { TO_FOUR_THIRDS[-i]= -(TO_FOUR_THIRDS[i] = (REAL)pow((double)i,4.0/3.0)); } } for(i=0;i<256;i++)POW2[i]=(REAL)pow(2.0,(0.25*(i-210.0))); 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)); { static REAL TAN12[16]= { 0.0, 0.26794919, 0.57735027 , 1.0, 1.73205081, 3.73205081, 9.9999999e10,-3.73205081, -1.73205081,-1.01, -0.57735027, -0.26794919, 0.0, 0.26794919, 0.57735027, 1.0}; for(i=0;i<16;i++) { rat_1[i].l=TAN12[i]/(1.0+TAN12[i]); rat_1[i].r=1.0/(1.0+TAN12[i]); } }#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); } { static REAL Ci[8]= {-0.6f,-0.535f,-0.33f,-0.185f,-0.095f,-0.041f,-0.0142f,-0.0037f}; REAL sq; for(int i=0;i<8;i++) { sq=sqrt(1.0f+Ci[i]*Ci[i]); cs[i]=1.0f/sq; ca[i]=Ci[i]*cs[i]; } } initializedlayer3=true;}bool MPEGaudio::layer3getsideinfo(void){ 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); 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) { /* printf("Side info bad: block_type == 0 in split block.\n"); exit(0); */ 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 MPEGaudio::layer3getsideinfo_2(void){ 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); 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) { /* printf("Side info bad: block_type == 0 in split block.\n"); exit(0); */ 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 MPEGaudio::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]; } 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; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -