www.pudn.com > av3dec_20050318.zip > sam_decoder.c


                                      /* 
*********************************************************************** 
* COPYRIGHT AND WARRANTY INFORMATION 
* 
* Copyright 2004,  Audio Video Coding Standard, Part III 
* 
* This software module was originally developed by 
* 
* JungHoe Kim (kjh94@samsung.com), Samsung AIT 
* 
* edited by 
* 
* Lei Miao (win.miaolei@samsung.com), Samsung AIT 
* 
* DISCLAIMER OF WARRANTY 
* 
* These software programs are available to the users without any 
* license fee or royalty on an "as is" basis. The AVS disclaims 
* any and all warranties, whether express, implied, or statutory, 
* including any implied warranties of merchantability or of fitness 
* for a particular purpose. In no event shall the contributors or  
* the AVS be liable for any incidental, punitive, or consequential 
* damages of any kind whatsoever arising from the use of this program. 
* 
* This disclaimer of warranty extends to the user of this program 
* and user's customers, employees, agents, transferees, successors, 
* and assigns. 
* 
* The AVS does not represent or warrant that the program furnished 
* hereunder are free of infringement of any third-party patents. 
* Commercial implementations of AVS, including shareware, may be 
* subject to royalty fees to patent holders. Information regarding 
* the AVS patent policy is available from the AVS Web site at 
* http://www.avs.org.cn 
* 
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. 
************************************************************************ 
*/ 
 
#include  
#include "sam_cbc_dec.h" 
#include "sam_scf_band.h" 
 
#define SF_OFFSET		100 
#define TEXP			128 
#define MAX_IQ_TBL		128 
 
static int  av3BandL[60];		/*max : 51*/ 
static int  av3BandS[20];		/*max : 15*/ 
static int  nsfb1024; 
static int  nsfb128; 
 
Float calc_scale(int fac); 
Float iquant_exp(int q); 
 
static Float  exptable[TEXP]; 
static Float  iq_exp_tbl[MAX_IQ_TBL]; 
 
int init_cbc(int fsidx) 
{ 
	int		i; 
 
	for (i = 0; i < TEXP; i++) 
		exptable[i] = pow(2.0, 1./4.*i); 
 
	for (i = 0; i < MAX_IQ_TBL; i++) 
		iq_exp_tbl[i] = pow(i, 4./3.); 
   
	/* for long */ 
	nsfb1024 = samp_rate_info[fsidx].nsfb1024; 
	av3BandL[0] = 0; 
	for (i = 0; i < nsfb1024; i++) 
		av3BandL[i+1] = samp_rate_info[fsidx].SFbands1024[i]; 
 
	/* for short */ 
	nsfb128 = samp_rate_info[fsidx].nsfb128; 
	av3BandS[0] = 0; 
	for (i = 0; i < nsfb128; i++) 
		av3BandS[i+1] = samp_rate_info[fsidx].SFbands128[i]; 
 
	cbc_decode_init(fsidx); 
 
	BSHCDecInit(); 
 
	return samp_rate_info[fsidx].samp_rate; 
} 
 
void decodeCBC( 
  int  target, 
  int  stereo_mode, 
  int  windowSequence[], 
  int  num_window_groups, 
  int  window_group_length[], 
  int  scalefactors[][8][MAX_SCFAC_BANDS], 
  int  samples[][FRAMESIZE], 
  int  maxSfb[], 
 
  int  ps_mask[],  
 
  int  ubits, 
  int  frameSize, 
  int  enc_top_layer, 
  int  base_snf, 
  int  base_band, 
  int  nch, 
  int  fill_length) 
{ 
	int		i, w; 
	int		swb_offset[8][52]; 
	int		sppl[2][FRAMESIZE]; 
 
	target -= 16; 
 
	if (target > enc_top_layer) 
		target = enc_top_layer; 
 
	if (windowSequence[0] == SHORT_WINDOW) { 
		for (w = 0; w < num_window_groups; w++) { 
			swb_offset[w][0] = 0; 
			for (i = 0; i < nsfb128; i++) 
				swb_offset[w][i+1] = av3BandS[i+1] * window_group_length[w]; 
		} 
	}  
	else { 
		for (i = 0; i < nsfb1024+1; i++) 
			swb_offset[0][i] = av3BandL[i]; 
	} 
 
 
	cbc_decode(windowSequence[0], target, sppl, scalefactors, maxSfb[0], num_window_groups, 
		window_group_length, ps_mask, stereo_mode, swb_offset, ubits, frameSize, 
	    enc_top_layer, base_snf, base_band, nch, fill_length); 
 
	/* Deinterleaving quantized spectral data for short window*/ 
	if (windowSequence[0] == SHORT_WINDOW) { 
		int offset, b, s, k; 
		 
		s = 0; 
		for (w = 0; w < num_window_groups; w++) { 
			for (i = 0; i < 128; i += 4) { 
				offset = (128 * s) + (i * window_group_length[w]); 
				for (k = 0; k < 4; k++) 
					for (b = 0 ; b < window_group_length[w]; b++) { 
						samples[0][128*(b+s)+i+k] = sppl[0][offset+4*b+k]; 
						samples[1][128*(b+s)+i+k] = sppl[1][offset+4*b+k]; 
					} 
			} 
			s += window_group_length[w]; 
		} 
	} 
	else { 
		for (i = 0; i < FRAMESIZE; i++) { 
			samples[0][i] = sppl[0][i]; 
			samples[1][i] = sppl[1][i]; 
		} 
	} 
} 
 
void dequantization(int target, 
  int  windowSequence, 
  int  scalefactors[][MAX_SCFAC_BANDS], 
  int  num_window_groups, 
  int  window_group_length[], 
  int  samples[], 
  int  maxSfb, 
  Float spectrums[], 
  int ch) 
{ 
  int  sfb, i; 
  Float   scale; 
 
  target = (target - 16); 
 
  for(i = 0; i < FRAMESIZE; i++) 
    spectrums[i] = -0.0; 
 
  if(windowSequence != SHORT_WINDOW) { 
 
    for(sfb = 0; sfb < maxSfb; sfb++) { 
 
      scale = calc_scale(scalefactors[0][sfb]-SF_OFFSET); 
 
      for(i = av3BandL[sfb]; i < av3BandL[sfb+1]; i++) { 
        spectrums[i] = iquant_exp(samples[i]) * scale; 
	  } 
    } 
 
  }  
  else  
  { 
    int w, b, s, k; 
	int spl; 
 
	s = 0; 
    for(w = 0; w < num_window_groups; w++) { 
      for(sfb = 0; sfb < maxSfb; sfb++) { 
 
        scale = calc_scale(scalefactors[w][sfb]-SF_OFFSET); 
 
        for(b = 0 ; b < window_group_length[w]; b++) { 
          k = (s + b) * 128; 
          for(i = av3BandS[sfb]; i < av3BandS[sfb+1]; i++) { 
			  spl = samples[k+i]; 
              spectrums[k+i] = iquant_exp(spl) * scale; 
          } 
        } 
      } 
	  s += window_group_length[w]; 
    } 
  } 
} 
 
 
 
/* bypass stereo decoding, just get swb_offset info 
   from its 'samp_rate_info' in "sam_cbc_band.h" */ 
void cbc_swboffset_for_polarstereo(int*	swb_offset_long,  
								   int* swb_offset_short,    
								   int	fsidx) 
{ 
	int i; 
	/* for long */ 
	swb_offset_long[0] = 0; 
	for (i = 0; i < samp_rate_info[fsidx].nsfb1024; i++) 
		swb_offset_long[i+1] = samp_rate_info[fsidx].SFbands1024[i]; 
 
	/* for short */ 
	swb_offset_short[0] = 0; 
	for (i = 0; i < samp_rate_info[fsidx].nsfb128; i++) 
		swb_offset_short[i+1] = samp_rate_info[fsidx].SFbands128[i]; 
} 
 
Float calc_scale(int fac) 
{ 
  Float  scale; 
 
  if(fac >= 0 && fac < TEXP) { 
    scale = exptable[fac]; 
  } else { 
    if(fac == -SF_OFFSET) 
      scale = 0.; 
    else 
      scale = pow((double)2.0, (double)(0.25*fac)); 
  } 
 
  return scale; 
} 
 
Float iquant_exp(int q) 
{ 
  Float return_value; 
 
  if (q > 0) { 
    if (q < MAX_IQ_TBL) { 
        return((Float)iq_exp_tbl[q]); 
    } 
    else { 
        return_value = (Float)(pow((double)q, (double)(4./3.))); 
    } 
  } 
  else { 
    q = -q; 
    if (q < MAX_IQ_TBL) { 
        return((Float)(-iq_exp_tbl[q])); 
    } 
    else { 
        return_value = (Float)(-pow((double)q, (double)(4./3.))); 
    } 
  } 
 
  return return_value; 
}