www.pudn.com > mp3decoder.rar > Decode.c
/*********************************************** copyright by Haia Tech www.haia2004.com ************************************************/ #include//#include #include "common.h" #include "decode.h" extern struct Granule grle[2][2]; extern Bit_stream_struc bs; extern frame_params fr_ps; struct BandIndex sfBandIndex[3]= { {{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}} }; void decode_info() { layer *hdr = fr_ps.header; int x; hdr->version = getbit(1); hdr->lay = 4-getbit(2); hdr->error_protection = !getbit(1); /* error protect. TRUE/FALSE */ hdr->bitrate_index = getbit(4); hdr->sampling_frequency = getbit(2); hdr->padding = getbit(1); hdr->extension = getbit(1); hdr->mode = getbit(2); hdr->mode_ext = getbit(2); hdr->copyright = getbit(1); hdr->original = getbit(1); hdr->emphasis = getbit(2); } void III_get_side_info(III_side_info_t *si) { int ch, gr, i; int stereo = fr_ps.stereo; si->main_data_begin = getbit(9); //SI 边信息结构 if (stereo == 1) si->private_bits = getbit(5); else si->private_bits = getbit(3); for (ch=0; ch scfsi[ch][i] = getbit(1); for (gr=0; gr<2; gr++) { for (ch=0; ch window_switching_flag && (gr_info->block_type == 2)) { if (gr_info->mixed_block_flag) { /* MIXED */ /* NEW - ag 11/25 */ for (sfb = 0; sfb < 8; sfb++) (*scalefac)[ch].l[sfb] = hgetbits( slen[0][gr_info->scalefac_compress]); //用 slen[0] for (sfb = 3; sfb < 6; sfb++) for (window=0; window<3; window++) (*scalefac)[ch].s[window][sfb] = hgetbits( slen[0][gr_info->scalefac_compress]); //用 slen[0] for (sfb = 6; sfb < 12; sfb++) for (window=0; window<3; window++) (*scalefac)[ch].s[window][sfb] = hgetbits( slen[1][gr_info->scalefac_compress]); //6-11用 slen[1] for (sfb=12,window=0; window<3; window++) (*scalefac)[ch].s[window][sfb] = 0; } else { /* SHORT*/ for (i=0; i<2; i++) for (sfb = sfbtable.s[i]; sfb < sfbtable.s[i+1]; sfb++) for (window=0; window<3; window++) (*scalefac)[ch].s[window][sfb] = hgetbits( slen[i][gr_info->scalefac_compress]); for (sfb=12,window=0; window<3; window++) (*scalefac)[ch].s[window][sfb] = 0; } } else { /* LONG types 0,1,3 */ for (i=0; i<4; i++) { if ((si->scfsi[ch][i] == 0) || (gr == 0)) for (sfb = sfbtable.l[i]; sfb < sfbtable.l[i+1]; sfb++) (*scalefac)[ch].l[sfb] = hgetbits( slen[(i<2)?0:1][gr_info->scalefac_compress]); } (*scalefac)[ch].l[22] = 0; } } 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}; void III_dequantize_sample(int is[SBLIMIT][SSLIMIT], double xr[SBLIMIT][SSLIMIT], III_scalefac_t *scalefac, struct Granule *gr_info, int ch) { int ss,sb,cb=0,sfreq=fr_ps.header->sampling_frequency; int next_cb_boundary, cb_begin, cb_width, sign; double is43_table[1024],temp; static int init=1; if(init) { for(init=0;init<1024;init++) is43_table[init]=1.33333333333*log(init); init=0; } /* choose correct scalefactor band per block type, initalize boundary */ if (gr_info->window_switching_flag && (gr_info->block_type == 2) ) if (gr_info->mixed_block_flag) next_cb_boundary=sfBandIndex[sfreq].l[1]; /* LONG blocks: 0,1,3 */ else { next_cb_boundary=sfBandIndex[sfreq].s[1]*3; /* pure SHORT block */ cb_width = sfBandIndex[sfreq].s[1]; cb_begin = 0; } else next_cb_boundary=sfBandIndex[sfreq].l[1]; /* LONG blocks: 0,1,3 */ /* apply formula per block type */ for (sb=0 ; sb < SBLIMIT ; sb++) { //0-31 for (ss=0 ; ss < SSLIMIT ; ss++) { //0-17 /********* 由sb和ss计算cb(比例因子带)和cb_width(比例因子带宽) **************/ if ( (sb*18)+ss == next_cb_boundary) { /* Adjust critical band boundary */ if (gr_info->window_switching_flag && (gr_info->block_type == 2)) { if (gr_info->mixed_block_flag) { if (((sb*18)+ss) == sfBandIndex[sfreq].l[8]) { next_cb_boundary=sfBandIndex[sfreq].s[4]*3; cb = 3; cb_width = sfBandIndex[sfreq].s[cb+1] - sfBandIndex[sfreq].s[cb]; cb_begin = sfBandIndex[sfreq].s[cb]*3; } else if (((sb*18)+ss) < sfBandIndex[sfreq].l[8]) next_cb_boundary = sfBandIndex[sfreq].l[(++cb)+1]; else { next_cb_boundary = sfBandIndex[sfreq].s[(++cb)+1]*3; cb_width = sfBandIndex[sfreq].s[cb+1] - sfBandIndex[sfreq].s[cb]; cb_begin = sfBandIndex[sfreq].s[cb]*3; } } else { next_cb_boundary = sfBandIndex[sfreq].s[(++cb)+1]*3; cb_width = sfBandIndex[sfreq].s[cb+1] - sfBandIndex[sfreq].s[cb]; cb_begin = sfBandIndex[sfreq].s[cb]*3; } } else /* long blocks */ next_cb_boundary = sfBandIndex[sfreq].l[(++cb)+1]; } /***************************************************************************************/ if(is[sb][ss]!=0) { /* Compute overall (global) scaling. */ xr[sb][ss] = (0.25 * (gr_info->global_gain - 210.0)); /* Do long/short dependent scaling operations. */ if (gr_info->window_switching_flag && ( ((gr_info->block_type == 2) && (gr_info->mixed_block_flag == 0)) || ((gr_info->block_type == 2) && gr_info->mixed_block_flag && (sb >= 2)) )) { xr[sb][ss] += (0.25 * -8.0 *gr_info->subblock_gain[(((sb*18)+ss) - cb_begin)/cb_width]); xr[sb][ss] += (0.25 * -2.0 * (1.0+gr_info->scalefac_scale) * (*scalefac)[ch].s[(((sb*18)+ss) - cb_begin)/cb_width][cb]); } else /* LONG block types 0,1,3 & 1st 2 subbands of switched blocks */ { xr[sb][ss] += (-0.5 * (1.0+gr_info->scalefac_scale) * ((*scalefac)[ch].l[cb] + gr_info->preflag * pretab[cb])); } /* Scale quantized value. */ //求出符号 sign=0; if(is[sb][ss]<0) { sign=1; is[sb][ss]=-is[sb][ss]; } if(is[sb][ss]>1023) temp=is43_table[(unsigned)is[sb][ss]>>3]+2.7725887;// 4/3*ln8 else temp=is43_table[is[sb][ss]]; xr[sb][ss] *=0.69314318; //log(2); xr[sb][ss] +=temp; xr[sb][ss] =exp(xr[sb][ss]); if (sign) xr[sb][ss] = -xr[sb][ss]; } else xr[sb][ss] =0; } } } void III_reorder(SS xr , struct Granule *gr_info) { int sfreq=fr_ps.header->sampling_frequency; int sfb, sfb_start, sfb_lines; int sb, ss, window, freq, src_line, des_line; SS ro ; if (gr_info->window_switching_flag && (gr_info->block_type == 2)) { if (gr_info->mixed_block_flag) { /* NO REORDER FOR LOW 2 SUBBANDS */ for (sb=0 ; sb < 2 ; sb++) for (ss=0 ; ss < SSLIMIT ; ss++) ro[sb][ss] = xr[sb][ss]; /* REORDERING FOR REST SWITCHED SHORT */ for(sfb=3,sfb_start=sfBandIndex[sfreq].s[3], sfb_lines=sfBandIndex[sfreq].s[4] - sfb_start; sfb < 13; sfb++,sfb_start=sfBandIndex[sfreq].s[sfb], (sfb_lines=sfBandIndex[sfreq].s[sfb+1] - sfb_start)) for(window=0; window<3; window++) for(freq=0;freq sampling_frequency; int stereo = fr_ps.stereo; int ms_stereo = (fr_ps.header->mode == MPG_MD_JOINT_STEREO) && (fr_ps.header->mode_ext & 0x2); int i_stereo = (fr_ps.header->mode == MPG_MD_JOINT_STEREO) && (fr_ps.header->mode_ext & 0x1); int sfb; int i,j,sb,ss,is_pos[576]; double is_ratio[576]; /* intialization */ for ( i=0; i<576; i++ ) is_pos[i] = 7; if ((stereo == 2) && i_stereo ) { if (gr_info->window_switching_flag && (gr_info->block_type == 2)) { if( gr_info->mixed_block_flag ) { int max_sfb = 0; for ( j=0; j<3; j++ ) { int sfbcnt; sfbcnt = 2; for( sfb=12; sfb >=3; sfb-- ) { int lines; lines = sfBandIndex[sfreq].s[sfb+1]-sfBandIndex[sfreq].s[sfb]; i = 3*sfBandIndex[sfreq].s[sfb] + (j+1) * lines - 1; while ( lines > 0 ) { if ( xr[1][i/SSLIMIT][i%SSLIMIT] != 0.0 ) { sfbcnt = sfb; sfb = -10; lines = -10; } lines--; i--; } } sfb = sfbcnt + 1; if ( sfb > max_sfb ) max_sfb = sfb; while( sfb<12 ) { sb = sfBandIndex[sfreq].s[sfb+1]-sfBandIndex[sfreq].s[sfb]; i = 3*sfBandIndex[sfreq].s[sfb] + j * sb; for ( ; sb > 0; sb--) { is_pos[i] = (*scalefac)[1].s[j][sfb]; if ( is_pos[i] != 7 ) is_ratio[i] = tan( is_pos[i] * (PI / 12)); i++; } sfb++; } sb = sfBandIndex[sfreq].s[11]-sfBandIndex[sfreq].s[10]; sfb = 3*sfBandIndex[sfreq].s[10] + j * sb; sb = sfBandIndex[sfreq].s[12]-sfBandIndex[sfreq].s[11]; i = 3*sfBandIndex[sfreq].s[11] + j * sb; for ( ; sb > 0; sb-- ) { is_pos[i] = is_pos[sfb]; is_ratio[i] = is_ratio[sfb]; i++; } } if ( max_sfb <= 3 ) { i = 2; ss = 17; sb = -1; while ( i >= 0 ) { if ( xr[1][i][ss] != 0.0 ) { sb = i*18+ss; i = -1; } else { ss--; if ( ss < 0 ) { i--; ss = 17; } } } i = 0; while ( sfBandIndex[sfreq].l[i] <= sb ) i++; sfb = i; i = sfBandIndex[sfreq].l[i]; for ( ; sfb<8; sfb++ ) { sb = sfBandIndex[sfreq].l[sfb+1]-sfBandIndex[sfreq].l[sfb]; for ( ; sb > 0; sb--) { is_pos[i] = (*scalefac)[1].l[sfb]; if ( is_pos[i] != 7 ) is_ratio[i] = tan( is_pos[i] * (PI / 12)); i++; } } } } else { for ( j=0; j<3; j++ ) { int sfbcnt; sfbcnt = -1; for( sfb=12; sfb >=0; sfb-- ) { int lines; lines = sfBandIndex[sfreq].s[sfb+1]-sfBandIndex[sfreq].s[sfb]; i = 3*sfBandIndex[sfreq].s[sfb] + (j+1) * lines - 1; while ( lines > 0 ) { if ( xr[1][i/SSLIMIT][i%SSLIMIT] != 0.0 ) { sfbcnt = sfb; sfb = -10; lines = -10; } lines--; i--; } } sfb = sfbcnt + 1; while( sfb<12 ) { sb = sfBandIndex[sfreq].s[sfb+1]-sfBandIndex[sfreq].s[sfb]; i = 3*sfBandIndex[sfreq].s[sfb] + j * sb; for ( ; sb > 0; sb--) { is_pos[i] = (*scalefac)[1].s[j][sfb]; if ( is_pos[i] != 7 ) is_ratio[i] = tan( is_pos[i] * (PI / 12)); i++; } sfb++; } sb = sfBandIndex[sfreq].s[11]-sfBandIndex[sfreq].s[10]; sfb = 3*sfBandIndex[sfreq].s[10] + j * sb; sb = sfBandIndex[sfreq].s[12]-sfBandIndex[sfreq].s[11]; i = 3*sfBandIndex[sfreq].s[11] + j * sb; for ( ; sb > 0; sb-- ) { is_pos[i] = is_pos[sfb]; is_ratio[i] = is_ratio[sfb]; i++; } } } } else { i = 31; ss = 17; sb = 0; while ( i >= 0 ) { if ( xr[1][i][ss] != 0.0 ) { sb = i*18+ss; i = -1; } else { ss--; if ( ss < 0 ) { i--; ss = 17; } } } i = 0; while ( sfBandIndex[sfreq].l[i] <= sb ) i++; sfb = i; i = sfBandIndex[sfreq].l[i]; for ( ; sfb<21; sfb++ ) { sb = sfBandIndex[sfreq].l[sfb+1] - sfBandIndex[sfreq].l[sfb]; for ( ; sb > 0; sb--) { is_pos[i] = (*scalefac)[1].l[sfb]; if ( is_pos[i] != 7 ) is_ratio[i] = tan( is_pos[i] * (PI / 12)); i++; } } sfb = sfBandIndex[sfreq].l[20]; for ( sb = 576 - sfBandIndex[sfreq].l[21]; sb > 0; sb-- ) { is_pos[i] = is_pos[sfb]; is_ratio[i] = is_ratio[sfb]; i++; } } } if (stereo==2) for(sb=0;sb window_switching_flag && (gr_info->block_type == 2) && !gr_info->mixed_block_flag ) return; if ( gr_info->window_switching_flag && gr_info->mixed_block_flag && (gr_info->block_type == 2)) sblim = 1; else sblim = SBLIMIT-1; /* 31 alias-reduction operations between each pair of sub-bands */ /* with 8 butterflies between each pair */ for(sb=0;sb bitrate_index]) / s_freq[fr_ps.header->sampling_frequency]); if (fr_ps.header->padding) nSlots++; nSlots -= 4; //减去4字节的头 if (fr_ps.header->error_protection) //如有CRC 则减2字节 nSlots -= 2; if (fr_ps.stereo == 1) //单声道-17字节的side 信息 nSlots -= 17; else nSlots -=32; //单声道-32字节的side 信息 return(nSlots); }