/* MPEG/WAVE Sound library (C) 1997 by Jung woo-jae */ // Mpeglayer3.cpp // 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;j0) { 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:"<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]); 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:"<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:"<getExtendedmode(); layer3grinfo *gi=&(sideinfo.ch[ch].gr[0]); 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;jwindow_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)pointtreelen))) { 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*/ 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)pointtreelen))) { *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;itable_select[0]]; if(region1Start>e)end=e; else end=region1Start; } else if(itable_select[1]]; if(region2Start>e)end=e; else end=region2Start; } else { h=&ht[gi->table_select[2]]; end=e; } if(h->treelen) { while(itablename, 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(;icount1table_select+32]; while(bitwindow.gettotalbit()=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(;igetVersion(); 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(;indexmixed_block_flag) { int cb=0,index=0; int cb_width; do { cb_width=(sfBandIndex->s[cb+1]-sfBandIndex->s[cb])>>1; for(int k=0;k<3;k++) { REAL factor; 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(indexl[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;il[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(indexl[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(;indexl[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(indexl[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 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];iscalefac_compress%2]; else ratios=rat_1; /* initialization */ for(i=0;igeneralflag) { 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) { 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{ 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;is[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;freqs[1]; sfb<13; sfb++,sfb_start=sfBandIndex->s[sfb], (sfb_lines=sfBandIndex->s[sfb+1]-sfb_start)) { for(int freq=0;freqgetVersion(); int frequency=mpegAudioHeader->getFrequency(); int mpeg25=mpegAudioHeader->getLayer25(); 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(int i=layer3slots;i>0;i--) { bitwindow.putbyte(getbyte()); } } else { // read main data. for(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(int i=layer3slots;i>0;i--) { bitwindow.putbyte(getbyte()); } } else { // read main data. for(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); }