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; chscfsi[ch][i] = getbit(1); 
 
	for (gr=0; gr<2; gr++) { 
		for (ch=0; chwindow_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;freqsampling_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;sbwindow_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;sbbitrate_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); 
}