📄 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 <stdio.h>
#include "MPEGaudio.h"
#if defined(_WIN32) && defined(_MSC_VER)
// disable warnings about double to float conversions
#pragma warning(disable: 4244 4305)
#endif
inline 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_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 (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->mixed_block_flag = 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->mixed_block_flag = 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 + -