www.pudn.com > AVS_M_ver10.rar > avq_cod.c


/* 
*********************************************************************** 
* COPYRIGHT AND WARRANTY INFORMATION 
* 
* Copyright 2007  Audio Video Coding Standard, Part Ⅹ 
* 
* This software module was developed by AVS Audio sub-group 
* 
* 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. 
************************************************************************ 
*/ 
 
/*---------------------------------------------------------------------------* 
 *         SPLIT ALGEBRAIC VECTOR QUANTIZER BASED ON RE8 LATTICE             * 
 *---------------------------------------------------------------------------* 
 * NOTE: a mitsmatch can occurs in some subvectors between the encoder       * 
 *       and decoder, because the encoder use a bit-rate estimator to set    * 
 *       the TCX global gain - this estimator is many times faster than the  * 
 *       call of RE8_idx() for bits calculation.                             *  
 *---------------------------------------------------------------------------*/ 
#include  
#include  
#include  
#include "../include/amr_plus.h" 
#define NQ_MAX     36 
#define FAC_LOG2   3.321928095f 
#define NSV_MAX    256     /* number of sub-vector max in QVAE, 256*8=2048 */ 
 
#ifdef NEW_TVC 
#define VQ_FACTOR 5.285f 
#define VQ_FACTOR2 1.1f 
/* local function */ 
static int calc_bits(int nq, int flag, int* nq_change, int cache_hit); 
static void sort(int *ebits, int n, int *idx); 
static void split_idx_noovf(int *xriq, int NB_BITS, int Nsv, int *nq, long *I, int *kv, int* flag, int *ka); 
static void writ_all_nq(int n_pack, int *nq, int *pos_n, int NB_BITS, int Nsv, int *last, int **parm_ptr, int* flag, int *cache_hit); 
static void chk_ovf(int n_bits, int n, int *n1, int *n2); 
static void writ_I(int n, int *pos_i, long *I, int *parm); 
static void writ_k(int n, int *pos_i, int *k, int *parm, int flag); 
static void init_pos_i_ovf(int n_pack, int *nq, int *pos_n, int last, int *pos_i_ovf, int *cache_hit); 
static void writ_ovf(int n_pack, int *parm_ovf, int n, int *pos_i_ovf, int *pos_n, int **parm_ptr); 
static void writ_all_i(int n_pack, int *nq, int *pos_n, int last, long *I, int *kv, int **parm_ptr, int* flag, int *cache_hit); 
static int calc_header(int n, int flag, int* header,int cache_hit); 
static int hit_table(int *p,long index,int base); 
 
long cache[16*2]={0}; 
 
int hit_table(int *p,long index,int base) 
{ 
  long *point,*j; 
  int flag=0,tmp=base,cache_num; 
  for (point=p;pointpoint[0])  
		  { 
			if (tmp1&&j[0]<5) j[0]=j[0]-1; 
	  else if (j[0]>4) ; 
	  else {j[0]=4;point=j;} 
 
  } 
  point[1]=index; 
 
  return 0; 
} 
 
int calc_header(int n, int flag, int* header, int cache_hit) 
{ 
  int hd_len = 0; 
  if (flag > 0xfff || flag < 0) 
	flag = 0;	 
  switch (flag & RE8_MODE_MASK){ 
	case RE8_MODE_SCALAR: 
	  /* bits/digital in n, header = 111111 11 11 11 x mm 
		 x = EVEN_FLAG 
		 n = 6, 7, 8, 9 ==>  mm = 00, 01, 10, 11       */ 
	  *header = 0xFFF << 3; 
	  hd_len = 15; 
	  if (flag & RE8_EVEN_FLAG) 
		*header |= (1<<2); 
	  *header |= (n-6); 
	  break; 
	case RE8_MODE_BASE: 
	  if (flag & RE8_SPEC_FLAG && n == 4){ 
		/* special leader in base codebook: n = 111111 10*/ 
		*header = 0xFE<<1; 
		hd_len = 9; 
		if (flag & RE8_EVEN_FLAG) 
		  *header = *header + 1; 
	  }else{ 
		/* in Q0: n = 0, in Q2: n = 10, in Q3: n = 110, in Q4: n = 1110 */ 
		if (n == 0){ 
		  *header = 0; 
		  hd_len = 1; 
		}else if ( n== 2){ 
		  if (cache_hit){ 
			*header = 0xD; 
			hd_len = 4; 
		  } 
		  else{ 
			*header = 2; 
			hd_len = 2; 
		  } 
		}else if (n == 3){ 
		  *header = 0xC; 
		  hd_len = 4; 
		}else if (n == 4){ 
		  *header = 0xE<<1; 
		  hd_len = 5; 
		  if (flag & RE8_EVEN_FLAG) 
			*header = *header + 1; 
		} 
	  } 
	  break; 
	case RE8_MODE_EXT1: 
	  if (flag & RE8_SPEC_FLAG && n == 4){ 
		/* special leader with r=1 in Q4 n = 111111 11 00*/ 
		*header = 0x3FC; 
		hd_len = 11; 
	  }else{ 
		/* in Q3: n = 111111 00, in Q4: n = 11110 */ 
		if (n == 3 || n == 2){ 
		  *header = 0xFC; 
		  hd_len = 9; 
		}else{ 
		  *header = 0x1E; 
		  hd_len = 6; 
		} 
	  } 
	  *header = *header << 1; 
	  if (flag & RE8_EVEN_FLAG) 
		*header = *header + 1; 
	  break; 
	case RE8_MODE_EXT2: 
	  if (flag & RE8_SPEC_FLAG && n == 4){ 
		/* special leader with r=2 in Q4 n = 111111 11 11 0*/ 
		*header = 0x7FE; 
		hd_len = 12; 
	  }else{ 
		/* in Q3: n = 111111 01, in Q4: n = 111110 */ 
		if (n == 3 || n == 2){ 
		  *header = 0xFD; 
		  hd_len = 9; 
		}else{ 
		  *header = 0x3E; 
		  hd_len = 7; 
		} 
	  } 
	  *header = *header << 1; 
	  if (flag & RE8_EVEN_FLAG) 
		*header = *header + 1; 
	  break; 
	case RE8_MODE_EXT3: 
	  if (flag & RE8_SPEC_FLAG && n == 4){ 
		/* special leader with r=3 in Q4 n = 111111 11 11 10*/ 
		*header = 0xFFE; 
		hd_len = 13; 
	  }else{ 
		/* in Q3: n = 111111 11 01, in Q4: n = 111111 11 10 */ 
		if (n == 3 || n == 2){ 
		  *header = 0x3FD; 
		  hd_len = 11; 
		}else{ 
		  *header = 0x3FE; 
		  hd_len = 11; 
		} 
	  } 
	  *header = *header << 1; 
	  if (flag & RE8_EVEN_FLAG) 
		*header = *header + 1; 
	  break; 
	default: 
	  printf("%s Internal error: unkown flag %d in RE8_cod()\r\n", "calc_header", flag); 
  } 
  return hd_len; 
} 
 
/* …… 预整形 模块 (开始) ……*/ 
/*-----------------------------------------------------------------* 
 *   Funtion  AVQ_gain_allocator    * 
 *   ->routine to compute two gains allocated to high band and low band 
 *-----------------------------------------------------------------*/ 
void AVQ_gain_allocator( 
	float *xri, 		/* (i) input samples in frequency band */ 
	int len, 		/* (i) length of the sample array in whole band */ 
	int bits_max, 	/* (i) available bits number */ 
	float *gh, 		/* (o) gain for high band */ 
	float* gg)		/* (o) gain for low band */ 
{ 
  float ebits[NSV_MAX]; 
  float offset, offset1, offset2, tmp, nbits; 
  int Nsv = len / 8; 
  int rb,i; 
  offset = AVQ_gain_comput(xri, len, bits_max, ebits); 
  /* computing actual bits consumed by low band */ 
  nbits = 0; 
  for (i = 0; i < Nsv/2; i++){ 
	tmp = ebits[i] - offset; 
	if (tmp < 0.0){ 
	  tmp = 1.0; 
	} 
	nbits += tmp; 
  } 
  rb = bits_max - (int)ceil(VQ_FACTOR2*nbits); 
  /* high band gain estimation */ 
  offset2 = AVQ_gain_comput(xri+len/2, len/2, rb, ebits); 
  /* computing actual bits consumed by high band */ 
  nbits = 0; 
  for (i = 0; i < Nsv/2; i++){ 
	tmp = ebits[i] - offset2; 
	if (tmp < 0.0){ 
	  tmp = 1.0; 
	} 
	nbits += tmp; 
  } 
  rb = bits_max - (int)ceil(VQ_FACTOR2*nbits); 
  /* further low band gain estimation */ 
  offset1 = AVQ_gain_comput(xri, len/2, rb, ebits); 
  offset1 = (offset1 < offset)?offset:offset1; 
  offset2 = (offset2 > offset)?offset:offset2; 
  /* estimated gain (when offset=0, estimated gain=1) */ 
  *gg = (float)pow(10.0, offset1 / (2.0*VQ_FACTOR*FAC_LOG2)); 
  *gh = (float)pow(10.0, (offset1-offset2)/(2.0*VQ_FACTOR*FAC_LOG2)); 
  //printf("gg = %f; gh = %f\r\n", *gg, *gh); 
  return; 
} 
 
/*-----------------------------------------------------------------* 
 *   Funtion  AVQ_get_nf    * 
 *   ->routine to get noise factor of a frame 
 *   	   Return:  noise factor 
 *-----------------------------------------------------------------*/ 
float AVQ_get_nf( /* output noise factor */ 
	float *xri, 	/* (i) input samples in freqency band */ 
	int NB_BITS, 	/* (i) available bits number */ 
	int Nsv)		/* (i) number of 8-bits subvectors */ 
{ 
  int    i, l, n, iter; 
  float  x1[8], ener, tmp, nbits, nbits_max, fac, offset; 
  float  ebits[NSV_MAX]; 
  /* find energy of each subvector in log domain (scaled for bits estimation) */ 
  for (l=0; l= 0 */ 
	for (i=0;i<8;i++) { 
	  ener += x1[i]*x1[i]; 
	} 
	/* estimated bit consumption when gain=1 */  
	ebits[l] = VQ_FACTOR*FAC_LOG2*(float)log10(ener*0.5); 
  } 
  /*---------------------------------------------------------------------* 
   * subvector energy worst case:                                        * 
   * - typically, it's a tone with maximum of amplitude (RMS=23170).     * 
   * - fft length max = 1024 (N/2 is 512)                                * 
   * log10(energy) = log10(23710*23710*1024*(N/2)) = 14.45               * 
   * ebits --> 5.0*FAC_LOG2*14.45 = 240 bits                             * 
   *---------------------------------------------------------------------*/ 
  /* estimate gain according to number of bits allowed */ 
  fac = 128.0;      /* start at the middle (offset range = 0 to 255.75) */ 
  offset = 0.0; 
  nbits_max = 0.95f * ((float)(NB_BITS - Nsv)); 
  /* tree search with 10 iterations : offset with step of 0.25 bits (0.3 dB) */ 
  for (iter=0; iter<10; iter++){ 
	offset += fac; 
	/* calculate the required number of bits */ 
	nbits = 0.0; 
	for (l=0; l tmp) tmp = ebits[l]; 
  tmp = tmp - 10.0f; 
  if (offset < tmp) offset = tmp; 
#endif 
  for (l=Nsv/2; lroutine to quantize the gain 
 * 	Return: quantized index of the gain 
 *-----------------------------------------------------------------*/ 
int AVQ_gband( /* output quantized index of the gain */ 
	float gain, 	/* (i) gain to be quantized */ 
	float *qgain)	/* (o) gain after quantize/dequantize */ 
{ 
  int tmp; 
 
  tmp = (int)floor(64 * gain + 0.5); 
  if (tmp > 127) 
	tmp = 127; 
  else if (tmp < 3) 
	tmp = 2; 
  *qgain = (float)tmp/(float)64.0; 
  return(tmp); 
}     
 
/*-----------------------------------------------------------------* 
 *   Funtion  AVQ_gain_comput    * 
 *   ->routine to estimate proper gain when bits_max bits are available 
 * 	Return: estimated gain 
 *-----------------------------------------------------------------*/ 
float AVQ_gain_comput( /* output estimated gain */ 
	float *xri,		/* (i) input samples in freqency band */ 
	int len, 			/* (i) length of input samples */ 
	int bits_max, 	/* (i) available bits number */ 
	float *ebits)		/* (o) estimated consumed bits for every 8-bit subvector */ 
{ 
  int    i, l,  iter; 
  float  x1[8], ener, tmp, nbits, nbits_max, fac, offset; 
  int Nsv = len / 8; 
 
  /* find energy of each subvector in log domain (scaled for bits estimation) */ 
  for (l=0; l= 0 */ 
	for (i=0;i<8;i++) { 
	  ener += x1[i]*x1[i]; 
	} 
	/* estimated bit consumption when gain=1 */  
	ebits[l] = VQ_FACTOR*FAC_LOG2*(float)log10(ener*0.5); 
  } 
 
  fac = 128.0;      /* start at the middle (offset range = 0 to 255.75) */ 
  offset = 0.0; 
  nbits_max = 0.95f * ((float)(bits_max-Nsv)); 
  /* tree search with 10 iterations : offset with step of 0.25 bits (0.3 dB) */ 
  for (iter=0; iter<10; iter++){ 
	offset += fac; 
	/* calculate the required number of bits */ 
	nbits = 0.0; 
	for (l=0; lroutine to quantize input samples in a frame in freqency band 
 *-----------------------------------------------------------------*/ 
float AVQ_cod(   /* output: comfort noise gain factor      */  
	float *xri,    /* input:  vector to quantize             */ 
	int *xriq,     /* output: quantized normalized vector (assuming the bit budget is enough) */  
	int NB_BITS,   /* input:  number of allocated bits          */  
	int Nsv,       /* input:  number of subvectors 
					* (lg=Nsv*8) */ 
	float *gh,  /* input: ratio between high band and low band scale factor */ 
	float *gg) /* input: whole band scale factor */ 
{ 
  int    i, l, c[8]; 
  float  gain_inv, x1[8], ener; 
  float  ebits[NSV_MAX]; 
 
  /* amplify high band  */ 
  for (l = 0; l < Nsv*8/2; l++){ 
	xri[l+Nsv*8/2] *= (*gh); 
  } 
  /* find energy of each subvector in log domain (scaled for bits estimation) */ 
  for (l=0; l= 0 */ 
	for (i=0;i<8;i++) { 
	  ener += x1[i]*x1[i]; 
	} 
	/* estimated bit consumption when gain=1 */  
	ebits[l] = VQ_FACTOR*FAC_LOG2*(float)log10(ener*0.5); 
  } 
  /* quantize all subvector using estimated gain */ 
  gain_inv = 1.0f / (*gg); 
  for (l=0; l n_pack  : number of packets 
   -> xriq    : rounded subvectors [0..8*Nsv-1] 
   followed by rounded bit allocations [8*Nsv..8*Nsv+Nsv-1] 
   <-> param   : multiplexed parameters 
   -> n_bits  : size of each packet  
   -> Nsv     : number of subvectors 
note: 
Nsv MUST be multiple of n_pack 
IMPORTANT: 
it is assumed that codebook numbers in track #p do not cause bit 
budget overflow in packet #p 
in practice this is ok if p<5 because the quantizer #n takes 5n bits 
and putting all bits in subvectors of track #p results in NB_BITS/5 bits 
for codebook numbers 
 */ 
void AVQ_encmux(int n_pack, int *xriq, int *param, int *n_bits, int Nsv) 
{ 
  int   last,i,p,flag[NSV_MAX]; 
  int   kv[NSV_MAX*8], nq[NSV_MAX]; 
  long  I[NSV_MAX]; 
  int pos_n[N_PACK_MAX]; 
  /* int pos_i[N_PACK_MAX]; */ 
  int *parm; 
  int *parm_ptr[4]; 
  int NB_BITS; 
  //new 
  int ka[NSV_MAX],l,hit_num=0,cache_hit[NSV_MAX]={0}; 
 
 
  NB_BITS=0; 
  for (i=0; i0){ 
	  switch(ka[l]){ 
		case 0: 
		case 1:  
		case 2:  
		  hit_num=hit_table(cache,I[l],0); 
		  break; 
		default: {hit_num=0;break;} 
 
	  } 
	  if(hit_num){ 
		cache_hit[l]=1; 
		I[l]=hit_num; 
	  } 
	} 
  } 
 
  //end 
 
 
  /* split multiplexing of codebook numbers (by interleaved tracks) */ 
  writ_all_nq(n_pack, nq, pos_n, NB_BITS, Nsv, &last, parm_ptr, flag, cache_hit); 
  /* write indices 
	 multiplexing is done track-by-track (from track #0 to track #n_pack-1) */ 
  writ_all_i(n_pack, nq, pos_n, last, I, kv, parm_ptr, flag, cache_hit); 
 
} 
/* 
   calc_bits(nq) 
   COMPUTE (NUMBER OF BITS -1) TO DESCRIBE Q #nq 
   -> nq: quantizer id (0,2,3,4...) 
   <-   : bit allocation 
 */ 
static int calc_bits(int n, int flag, int* nq_change, int cache_hit) 
{ 
  int len = 0; 
  if (flag > 0xfff || flag < 0) 
	flag = 0; 
  switch (flag & RE8_MODE_MASK){ 
	case RE8_MODE_SCALAR: 
	  /* bits/digital in n, header =  111111 11 11 11 x mm */ 
	  len = 15 + n * 8; 
	  *nq_change = n; 
	  break; 
	case RE8_MODE_BASE: 
	  if (flag & RE8_SPEC_FLAG && n == 4){ 
		/* special leader in base codebook: n = 111111 10*/ 
		len = 9+4*4; 
	  }else{ 
		/* in Q0: n = 0, in Q2: n = 10, in Q3: n = 110, in Q4: n = 1110 */ 
		if (n == 0){ 
		  len = 1; 
		}else if ( n== 2){ 
		  //		len = 2+2*4; 
		  if (cache_hit) 
			len= 8; 
		  else  
			len = 2+2*4; 
		}else if (n == 3){ 
		  len = 3+3*4+1; 
		}else if (n == 4){ 
		  len = 5+4*4; 
		} 
	  } 
	  *nq_change = n; 
	  break; 
	case RE8_MODE_EXT1: 
	  if (flag & RE8_SPEC_FLAG && n == 4){ 
		/* special leader with r=1 in Q4 n = 111111 11 00*/ 
		len = 11+4*4+8; 
	  }else{ 
		/* in Q3: n = 111111 00, in Q4: n = 11110 */ 
		if (n == 3 || n == 2){ 
		  len = 9+3*4+8; 
		}else{ 
		  len = 6+4*4+8; 
		} 
	  } 
	  if (n == 2)n = 3;  		/* consider Q2 as Q3 when using division table */ 
	  *nq_change = n+2; 
	  break; 
	case RE8_MODE_EXT2: 
	  if (flag & RE8_SPEC_FLAG && n == 4){ 
		/* special leader with r=2 in Q4 n = 111111 11 11 0*/ 
		len = 12+4*4+8*2; 
	  }else{ 
		/* in Q3: n = 111111 01, in Q4: n = 111110 */ 
		if (n == 3 || n == 2){ 
		  len = 9+3*4+2*8; 
		}else{ 
		  len = 7+4*4+2*8; 
		} 
	  } 
	  if (n == 2)n = 3;		/* consider Q2 as Q3 when using division table */ 
	  *nq_change = n+4; 
	  break; 
	case RE8_MODE_EXT3: 
	  if (flag & RE8_SPEC_FLAG && n == 4){ 
		/* special leader with r=3 in Q4 n = 111111 11 11 10*/ 
		len = 13+4*4+8*3; 
	  }else{ 
		/* in Q3: n = 111111 11 01, in Q4: n = 111111 11 10 */ 
		if (n == 3 || n == 2){ 
		  len = 11+3*4+3*8; 
		}else{ 
		  len = 11+4*4+3*8; 
		} 
	  } 
	  if (n == 2)n = 3;		/* consider Q2 as Q3 when using division table */ 
	  *nq_change = n + 6; 
	  break; 
	default: 
	  printf("%s Internal error: unkown flag %d in RE8_cod()\r\n", "calc_bits", flag); 
  } 
  return len; 
} 
/* 
   sort(ebits, n, idx) 
   SORT SUBVECTORS BY DECREASING BIT ALLOCATIONS 
   -> ebits : estimated bit allocations (table of n *positive* integers) 
   -> n     : number of subvectors 
   <- idx   : indices 
 */ 
static void sort(int *ebits, int n, int *idx) 
{ 
  int t[NSV_MAX],i,j,ebits_max,pos; 
  for (i=0; iebits_max) { 
		ebits_max = t[j]; 
		pos = j; 
	  } 
	} 
	idx[i]=pos; 
	t[pos]=-1; 
  } 
  return; 
} 
/* 
   split_idx_noovf(xriq,NB_BITS, Nsv, nq, I, kv, last) 
   COMPUTE MULTI-RATE INDICES FOR ALL SUBVECTORS AND FORCE NO BIT BUDGET OVERFLOW 
   PRIOR TO MULTIPLEXING 
   -> xriq    : rounded subvectors [0..8*Nsv-1] 
   followed by rounded bit allocations [8*Nsv..8*Nsv+Nsv-1] 
   -> NB_BITS : number of bits allocated for split multi-rate RE8 VQ 
   -> Nsv     : number of subvectors 
   <- nq      : codebook numbers 
   <- I       : indices for base quantizers (Q2,Q3,Q4) 
   <- kv      : Voronoi indices 
 */ 
static void split_idx_noovf(int *xriq, int NB_BITS, int Nsv, int *nq, long *I, int *kv, int* flag, int *ka) 
{ 
  int k,l,n,n_bits,pos, pos_max, n_ch; 
  int sort_idx[NSV_MAX]; 
 
  /* sort subvectors by estimated bit allocations in decreasing order 
	 (l=idx[0] is such that (rounded) ebits[l] is maximum) */ 
  sort(&xriq[8*Nsv],Nsv,sort_idx); 
  /* compute multi-rate indices and avoid bit budget overflow  */ 
  pos_max = 0; 
  n_bits = 0; 
  for (l=0; l0) { 
	  k = pos_max; 
	  if (pos > k) { 
		k = pos; 
	  } 
	  /* check for overflow and compute number of bits-1 (n) */ 
	  n = calc_bits(nq[pos], flag[pos], &n_ch,0); 
	  if ((n_bits+n+k) > NB_BITS) { /* if budget overflow */ 
		//		char str[35]; 
		//printf("Truancate [%s] to Q0\r\n", re8_sprint(&xriq[pos*8], str)); 
		nq[pos] = 0; /* force Q0 */ 
	  } else { 
		n_bits += n; 
		pos_max = k; /* update index of last described subvector (last) */ 
	  } 
	} 
  } 
  //	printf("here\r\n"); 
} 
/* 
   writ_all_nq(n_pack, nq, pos_n, NB_BITS, last, parm_ptr) 
   ENCODE AND MULTIPLEX ALL CODEBOOKS NUMBERS IN nq[] TRACK-BY-TRACK 
   ->  n_pack      : number of packets 
   ->  nq          : table of codebook numbers [0..Nsv-1] 
   ->  pos_n       : table of pointers to write nq in packets [0..n_pack-1] 
   ->  NB_BITS     : total bit allocation 
   <-  last        : index of last subvector for which an index is written 
   <-> parm        : bistream 
 */ 
static void writ_all_nq(int n_pack, int *nq, int *pos_n, int NB_BITS, int Nsv, int *last, int **parm_ptr, int* flag, int *cache_hit) 
{ 
  int p, pos, l, i, n_bits, *parm, hd, hd_len,room,nq_change; 
  n_bits = NB_BITS; 
  *last = -1; 
  /* write nq[l] for l=0...Nsv-1 in packet #p= mod(l,number_of_packets)*/ 
  for (l=0;l n_bits) { 
	  nq[l] = 0; 
	} else { 
	  n_bits -= i; 
	} 
	/* update "last" */ 
	if (nq[l] >= 2) { 
	  *last=l; 
	} 
	/* write the header for nq[l] in packet #p */ 
	hd_len = calc_header(nq[l], flag[l], &hd, cache_hit[l]); 
	//	printf("header = %x\r\n", hd);	 
	/* fill the first 4 bits room and then fill remains*/ 
	room = (pos%4)+1; 
	while (hd_len > room){ 
	  hd_len -= room; 
	  parm[pos/4] += hd >> hd_len; 
	  hd -= (hd >> hd_len) << hd_len; 
	  pos -= room; 
	  room = 4; 
	} 
	parm[pos/4] += hd << (room - hd_len); 
	pos -= hd_len; 
 
	pos_n[p] = pos; 
	if (nq_change > 4) 
	  nq[l] = nq_change; 
  } 
  return; 
} 
/* check if n groups of 4 bits fit in n_bits bits */ 
static void chk_ovf(int n_bits, int n, int *n1, int *n2) 
{ 
  if (4*n<=n_bits) { 
	*n1=n; 
	*n2=0; 
  } else { 
	*n1=n_bits/4; /* >> 2*/ 
	*n2=n-*n1; 
  } 
} 
/* write n groups of 4-bit for base codebook index (I) */ 
static void writ_I(int n, int *pos_i, long *I, int *parm) 
{ 
  int pos; 
  /* base codebook index */ 
  pos = *pos_i/4; 
  while (n-- > 0) { 
	parm[pos++] = (*I & 0x0F); 
	*I = *I>>4; 
  } 
  *pos_i=pos*4; 
} 
/* write n groups of 4-bit for Voronoi index (k[]) */ 
static void writ_k(int n, int *pos_i, int *k, int *parm, int flag) 
{ 
  int i, ival, delta, *kv, pos; 
  delta = 4*flag; 
  pos = *pos_i/4; 
  while (n-- > 0) { 
	kv=k+delta; 
	ival = 0; 
	for (i=0; i<4; i++) { 
	  ival <<= 1; 
	  ival += (kv[i] & 0x01); 
	  kv[i] >>= 1; 
	} 
	parm[pos++] = ival; 
	delta = (delta+4)%8; /* circular shift */ 
  } 
  *pos_i=pos*4; 
} 
 
/* find in each packet the positions where overflow occurs */ 
static void init_pos_i_ovf(int n_pack, int *nq, int *pos_n, int last, int *pos_i_ovf, int *cache_hit) 
{ 
  int p, pos, n_bits, l, n1, n2, ni=0; 
  for (p=0; p 0) { 
		ni=nq[l]; 
		if(ni==2&&cache_hit[l]) 
		  ni=ni-1; 
		chk_ovf(n_bits, ni, &n1, &n2); 
		n_bits -= 4*n1; 
		pos += n1; 
	  } 
	} 
	pos_i_ovf[p] = pos*4; 
  } 
} 
/* write bits in overflow */ 
static void writ_ovf(int n_pack, int *parm_ovf, int n, int *pos_i_ovf, int *pos_n, int **parm_ptr) 
{ 
  int pos_ovf, p, n_bits, pos, *parm, moved_bit; 
  /* initialize position in overflow packet (parm_ovf[]) */ 
  pos_ovf=0; 
  /* move bits from overflow packet (parm_ovf[]) to packets (parm_ptr[][]) 
	 [write 4-bit by 4-bit] */ 
  for (p=0; p= 4) && (n>0)) { 
	  pos=pos_i_ovf[p]/4; 
	  parm = parm_ptr[p]; 
	  do { 
		parm[pos++]=parm_ovf[pos_ovf++]; /* move 4 bits */ 
		n_bits -= 4; 
		n -= 4; 
	  } while ((n_bits>=4) && (n>0)); 
	  pos_i_ovf[p]=pos*4; 
	} 
  } 
  pos_ovf *=4; 
  /* move bits remaining in overflow packet 
	 [write bit-by-bit (3 bits at maximum per packet)] */ 
  for (p=0; p 0) && (n>0)) { 
	  pos = pos_i_ovf[p]; 
	  parm = parm_ptr[p]; 
	  do { 
		/* write a single bit */ 
		moved_bit = (parm_ovf[pos_ovf/4] >> (pos_ovf%4)) & 0x01; 
		parm[pos/4] +=  moved_bit<<(pos%4); 
		pos++; 
		pos_ovf++; 
		n_bits--; 
		n--; 
	  } while ((n_bits > 0) && (n > 0)); 
	  pos_i_ovf[p] = pos; 
	} 
  } 
} 
/* 
   writ_all_i(nq, p, pos_n, n_pack, last, pos_ovf, n_bits_left, parm_ptr) 
   MULTIPLEX AN INDEX (I,kv) OF 4*nq BITS INTO BITSTREAM 
   (THE INDEX CORRESPONDS TO A SUBVECTOR IN TRACK #p) 
   ->  nq          : codebook number (scalar) 
   ->  p           : index of track 
   ->  pos_i       : pointer to write i in packet [0..n_pack-1] 
   ->  n_pack      : number of packets 
   <-> pos_ovf     : pointers for overflow [0..n_pack-1] 
   <-> n_bits_left : number of unused bits in packets [0..n_pack-1] 
   ->  I           : base codebook index 
   ->  kv          : Voronoi index 
   <-> parm        : bistream [initialized to zero when writ_all_i is called] 
   ->flag   	: mode flag to decide encoding mode. 
   ->cache_hit :  whether Q2 index is cache index or basebook index 
   important note: 
   - if the index fits completely in packet #p, multiplexing is done as 
   in writ_parm from top to bottom: 
   the 1st bit of I is written at the top 
   the last bit of kv at the bottom 
 */ 
static void writ_all_i(int n_pack, int *nq, int *pos_n, int last, long *I, int *kv, int **parm_ptr, int* flag, int *cache_hit) 
{ 
  int pos_ovf, p, l, n_bits, ni, nk, n1, i, n2, pos, k[8], *parm; 
  long index; 
  //  char str[35]; 
  int parm_ovf[NQ_MAX]; 
  int pos_i_ovf[N_PACK_MAX]; 
  /* initialize overflow packet */ 
  for (i=0; i 0) { 
		/* compute number of bits left in packet #p */ 
		n_bits = pos_n[p]-pos+1; 
		/* compute number of 4-bit groups for base codebook index (ni) 
		   and Voronoi index (nk) */ 
		ni=nq[l]; 
		nk = 0; 
		if(ni==2&&cache_hit[l]==1) 
		  ni=ni-1; 
 
		if (ni <= 4){ 
		  for (i = 0; i < 8; i++) 
			kv[8*l+i] = 0; 
		} 
		//	printf("I = %d k = [%s]\r\n", I[l], re8_sprint(&kv[8*l], str)); 
		if ((flag[l] & RE8_MODE_MASK) != RE8_MODE_SCALAR){ 
		  /* LVQ mode */ 
		  if (ni > 4) { 
			nk = (ni-4+1)/2; /* nkv*2 = number of 4-bit groups */ 
			nk *= 2; 
			ni -= nk; 
		  } 
		  /* write base codebook index (in packet #p / overflow packet) */ 
		  index = I[l]; 
		  chk_ovf(n_bits, ni, &n1, &n2); 
		  writ_I(n1, &pos, &index, parm); 
		  n_bits -= 4*n1; 
		  if (n2>0) { 
			/* write 4-bit groups in overflow packet */ 
			pos_ovf = 0; 
			writ_I(n2, &pos_ovf, &index, parm_ovf); 
			/* distribute bits from overflow packet to packets 
#0 to n_pack-1 */ 
			writ_ovf(n_pack, parm_ovf, 4*n2, pos_i_ovf, pos_n, parm_ptr); 
			for (i=0; i0) { 
			/* write table index (in packet #p / overflow packet) */ 
			for (i=0; i<8; i++) { 
			  k[i] = kv[8*l+i]; 
			} 
			chk_ovf(n_bits, nk, &n1, &n2); 
			writ_k(n1, &pos, k, parm, 0); 
			if (n2>0) { 
			  pos_ovf = 0; 
			  writ_k(n2, &pos_ovf, k, parm_ovf,n1%2); 
			  writ_ovf(n_pack, parm_ovf, 4*n2, pos_i_ovf, pos_n, parm_ptr); 
			  for (i=0; i0) { 
			pos_ovf = 0; 
			writ_k(n2, &pos_ovf, k, parm_ovf,n1%2); 
			writ_ovf(n_pack, parm_ovf, 4*n2, pos_i_ovf, pos_n, parm_ptr); 
			for (i=0; i= 0 */ 
	for (i=0;i<8;i++) { 
	  ener += x1[i]*x1[i]; 
	} 
	/* estimated bit consumption when gain=1 */  
	ebits[l] = 5.0f*FAC_LOG2*(float)log10(ener*0.5); 
  } 
  /*---------------------------------------------------------------------* 
   * subvector energy worst case:                                        * 
   * - typically, it's a tone with maximum of amplitude (RMS=23170).     * 
   * - fft length max = 1024 (N/2 is 512)                                * 
   * log10(energy) = log10(23710*23710*1024*(N/2)) = 14.45               * 
   * ebits --> 5.0*FAC_LOG2*14.45 = 240 bits                             * 
   *---------------------------------------------------------------------*/ 
  /* estimate gain according to number of bits allowed */ 
  fac = 128.0;      /* start at the middle (offset range = 0 to 255.75) */ 
  offset = 0.0; 
  nbits_max = 0.95f * ((float)(NB_BITS - Nsv)); 
  /* tree search with 10 iterations : offset with step of 0.25 bits (0.3 dB) */ 
  for (iter=0; iter<10; iter++) 
  { 
	offset += fac; 
	/* calculate the required number of bits */ 
	nbits = 0.0; 
	for (l=0; l tmp) tmp = ebits[l]; 
  tmp = tmp - 10.0f; 
  if (offset < tmp) offset = tmp; 
#endif 
  for (l=Nsv/2; l n_pack  : number of packets 
   -> xriq    : rounded subvectors [0..8*Nsv-1] 
   followed by rounded bit allocations [8*Nsv..8*Nsv+Nsv-1] 
   <-> param   : multiplexed parameters 
   -> n_bits  : size of each packet  
   -> Nsv     : number of subvectors 
note: 
Nsv MUST be multiple of n_pack 
IMPORTANT: 
it is assumed that codebook numbers in track #p do not cause bit 
budget overflow in packet #p 
in practice this is ok if p<5 because the quantizer #n takes 5n bits 
and putting all bits in subvectors of track #p results in NB_BITS/5 bits 
for codebook numbers 
 */ 
void AVQ_encmux(int n_pack, int *xriq, int *param, int *n_bits, int Nsv) 
{ 
  int   last,i,p; 
  int   kv[NSV_MAX*8], nq[NSV_MAX]; 
  long  I[NSV_MAX]; 
  int pos_n[N_PACK_MAX]; 
  /* int pos_i[N_PACK_MAX]; */ 
  int *parm; 
  int *parm_ptr[4]; 
  int NB_BITS; 
  NB_BITS=0; 
  for (i=0; i nq: quantizer id (0,2,3,4...) 
   <-   : bit allocation 
 */ 
static int calc_bits(int nq) 
{ 
  if (nq >= 2) { 
	/* 4n bits + variable-length descriptor for allocation: 
	   descriptor -> nq 
	   0          -> 0 
	   10         -> 2 
	   110        -> 3 
	   => size of descriptor = 5n bits */ 
	return((nq*5)-1); /* [5n-1] */ 
  } 
  else { 
	return 0; /* 1-1 [1 bit to describe the allocation] */ 
  } 
} 
/* 
   sort(ebits, n, idx) 
   SORT SUBVECTORS BY DECREASING BIT ALLOCATIONS 
   -> ebits : estimated bit allocations (table of n *positive* integers) 
   -> n     : number of subvectors 
   <- idx   : indices 
 */ 
static void sort(int *ebits, int n, int *idx) 
{ 
  int t[NSV_MAX],i,j,ebits_max,pos; 
  for (i=0; iebits_max) { 
		ebits_max = t[j]; 
		pos = j; 
	  } 
	} 
	idx[i]=pos; 
	t[pos]=-1; 
  } 
  return; 
} 
/* 
   split_idx_noovf(xriq,NB_BITS, Nsv, nq, I, kv, last) 
   COMPUTE MULTI-RATE INDICES FOR ALL SUBVECTORS AND FORCE NO BIT BUDGET OVERFLOW 
   PRIOR TO MULTIPLEXING 
   -> xriq    : rounded subvectors [0..8*Nsv-1] 
   followed by rounded bit allocations [8*Nsv..8*Nsv+Nsv-1] 
   -> NB_BITS : number of bits allocated for split multi-rate RE8 VQ 
   -> Nsv     : number of subvectors 
   <- nq      : codebook numbers 
   <- I       : indices for base quantizers (Q2,Q3,Q4) 
   <- kv      : Voronoi indices 
 */ 
static void split_idx_noovf(int *xriq, int NB_BITS, int Nsv, int *nq, long *I, int *kv) 
{ 
  int k,l,n,n_bits,pos, pos_max; 
  int sort_idx[NSV_MAX]; 
  /* sort subvectors by estimated bit allocations in decreasing order 
	 (l=idx[0] is such that (rounded) ebits[l] is maximum) */ 
  sort(&xriq[8*Nsv],Nsv,sort_idx); 
  /* compute multi-rate indices and avoid bit budget overflow  */ 
  pos_max = 0; 
  n_bits = 0; 
  for (l=0; l0) { 
	  k = pos_max; 
	  if (pos > k) { 
		k = pos; 
	  } 
	  /* check for overflow and compute number of bits-1 (n) */ 
	  n = calc_bits(nq[pos]); 
	  if ((n_bits+n+k) > NB_BITS) { /* if budget overflow */ 
		nq[pos] = 0; /* force Q0 */ 
	  } else { 
		n_bits += n; 
		pos_max = k; /* update index of last described subvector (last) */ 
	  } 
	} 
  } 
} 
/* 
   writ_all_nq(n_pack, nq, pos_n, NB_BITS, last, parm_ptr) 
   ENCODE AND MULTIPLEX ALL CODEBOOKS NUMBERS IN nq[] TRACK-BY-TRACK 
   ->  n_pack      : number of packets 
   ->  nq          : table of codebook numbers [0..Nsv-1] 
   ->  pos_n       : table of pointers to write nq in packets [0..n_pack-1] 
   ->  NB_BITS     : total bit allocation 
   <-  last        : index of last subvector for which an index is written 
   <-> parm        : bistream 
 */ 
static void writ_all_nq(int n_pack, int *nq, int *pos_n, int NB_BITS, int Nsv, int *last, int **parm_ptr) 
{ 
  int p, pos, l, i, n_bits, *parm; 
  n_bits = NB_BITS; 
  *last = -1; 
  /* write nq[l] for l=0...Nsv-1 in packet #p= mod(l,number_of_packets)*/ 
  for (l=0;l n_bits) { 
	  nq[l] = 0; 
	} else { 
	  n_bits -= i; 
	} 
	/* update "last" */ 
	if (nq[l] >= 2) { 
	  *last=l; 
	} 
	/* write the unary code (except stop bit) for nq[l] in packet #p */ 
	i = nq[l] - 1; 
	while (i-- > 0) { 
	  parm[pos/4] += 1<<(pos%4); 
	  pos--; 
	} 
	/* if bit budget is not empty, write stop bit of unary code */ 
	if (n_bits > 0) { 
	  pos--; 
	  n_bits--; 
	} 
	pos_n[p] = pos; 
  } 
  return; 
} 
/* check if n groups of 4 bits fit in n_bits bits */ 
static void chk_ovf(int n_bits, int n, int *n1, int *n2) 
{ 
  if (4*n<=n_bits) { 
	*n1=n; 
	*n2=0; 
  } else { 
	*n1=n_bits/4; /* >> 2*/ 
	*n2=n-*n1; 
  } 
} 
/* write n groups of 4-bit for base codebook index (I) */ 
static void writ_I(int n, int *pos_i, long *I, int *parm) 
{ 
  int pos; 
  /* base codebook index */ 
  pos = *pos_i/4; 
  while (n-- > 0) { 
	parm[pos++] = (*I & 0x0F); 
	*I = *I>>4; 
  } 
  *pos_i=pos*4; 
} 
/* write n groups of 4-bit for Voronoi index (k[]) */ 
static void writ_k(int n, int *pos_i, int *k, int *parm, int flag) 
{ 
  int i, ival, delta, *kv, pos; 
  delta = 4*flag; 
  pos = *pos_i/4; 
  while (n-- > 0) { 
	kv=k+delta; 
	ival = 0; 
	for (i=0; i<4; i++) { 
	  ival <<= 1; 
	  ival += (kv[i] & 0x01); 
	  kv[i] >>= 1; 
	} 
	parm[pos++] = ival; 
	delta = (delta+4)%8; /* circular shift */ 
  } 
  *pos_i=pos*4; 
} 
/* find in each packet the positions where overflow occurs */ 
static void init_pos_i_ovf(int n_pack, int *nq, int *pos_n, int last, int *pos_i_ovf) 
{ 
  int p, pos, n_bits, l, n1, n2; 
  for (p=0; p 0) { 
		chk_ovf(n_bits, nq[l], &n1, &n2); 
		n_bits -= 4*n1; 
		pos += n1; 
	  } 
	} 
	pos_i_ovf[p] = pos*4; 
  } 
} 
/* write bits in overflow */ 
static void writ_ovf(int n_pack, int *parm_ovf, int n, int *pos_i_ovf, int *pos_n, int **parm_ptr) 
{ 
  int pos_ovf, p, n_bits, pos, *parm, moved_bit; 
  /* initialize position in overflow packet (parm_ovf[]) */ 
  pos_ovf=0; 
  /* move bits from overflow packet (parm_ovf[]) to packets (parm_ptr[][]) 
	 [write 4-bit by 4-bit] */ 
  for (p=0; p= 4) && (n>0)) { 
	  pos=pos_i_ovf[p]/4; 
	  parm = parm_ptr[p]; 
	  do { 
		parm[pos++]=parm_ovf[pos_ovf++]; /* move 4 bits */ 
		n_bits -= 4; 
		n -= 4; 
	  } while ((n_bits>=4) && (n>0)); 
	  pos_i_ovf[p]=pos*4; 
	} 
  } 
  pos_ovf *=4; 
  /* move bits remaining in overflow packet 
	 [write bit-by-bit (3 bits at maximum per packet)] */ 
  for (p=0; p 0) && (n>0)) { 
	  pos = pos_i_ovf[p]; 
	  parm = parm_ptr[p]; 
	  do { 
		/* write a single bit */ 
		moved_bit = (parm_ovf[pos_ovf/4] >> (pos_ovf%4)) & 0x01; 
		parm[pos/4] +=  moved_bit<<(pos%4); 
		pos++; 
		pos_ovf++; 
		n_bits--; 
		n--; 
	  } while ((n_bits > 0) && (n > 0)); 
	  pos_i_ovf[p] = pos; 
	} 
  } 
} 
/* 
   writ_all_i(nq, p, pos_n, n_pack, last, pos_ovf, n_bits_left, parm_ptr) 
   MULTIPLEX AN INDEX (I,kv) OF 4*nq BITS INTO BITSTREAM 
   (THE INDEX CORRESPONDS TO A SUBVECTOR IN TRACK #p) 
   ->  nq          : codebook number (scalar) 
   ->  p           : index of track 
   ->  pos_i       : pointer to write i in packet [0..n_pack-1] 
   ->  n_pack      : number of packets 
   <-> pos_ovf     : pointers for overflow [0..n_pack-1] 
   <-> n_bits_left : number of unused bits in packets [0..n_pack-1] 
   ->  I           : base codebook index 
   ->  kv          : Voronoi index 
   <-> parm        : bistream [initialized to zero when writ_all_i is called] 
   important note: 
   - if the index fits completely in packet #p, multiplexing is done as 
   in writ_parm from top to bottom: 
   the 1st bit of I is written at the top 
   the last bit of kv at the bottom 
 */ 
static void writ_all_i(int n_pack, int *nq, int *pos_n, int last, long *I, int *kv, int **parm_ptr) 
{ 
  int pos_ovf, p, l, n_bits, ni, nk, n1, i, n2, pos, k[8], *parm; 
  long index; 
  int parm_ovf[NQ_MAX]; 
  int pos_i_ovf[N_PACK_MAX]; 
  /* initialize overflow packet */ 
  for (i=0; i 0) { 
		/* compute number of bits left in packet #p */ 
		n_bits = pos_n[p]-pos+1; 
		/* compute number of 4-bit groups for base codebook index (ni) 
		   and Voronoi index (nk) */ 
		ni=nq[l]; 
		nk = 0; 
		if (ni > 4) { 
		  nk = (ni-4+1)/2; /* nkv*2 = number of 4-bit groups */ 
		  nk *= 2; 
		  ni -= nk; 
		} 
		/* write base codebook index (in packet #p / overflow packet) */ 
		index = I[l]; 
		chk_ovf(n_bits, ni, &n1, &n2); 
		writ_I(n1, &pos, &index, parm); 
		n_bits -= 4*n1; 
		if (n2>0) { 
		  /* write 4-bit groups in overflow packet */ 
		  pos_ovf = 0; 
		  writ_I(n2, &pos_ovf, &index, parm_ovf); 
		  /* distribute bits from overflow packet to packets 
#0 to n_pack-1 */ 
		  writ_ovf(n_pack, parm_ovf, 4*n2, pos_i_ovf, pos_n, parm_ptr); 
		  for (i=0; i0) { 
		  /* write Voronoi index (in packet #p / overflow packet) */ 
		  for (i=0; i<8; i++) { 
			k[i] = kv[8*l+i]; 
		  } 
		  chk_ovf(n_bits, nk, &n1, &n2); 
		  writ_k(n1, &pos, k, parm, 0); 
		  if (n2>0) { 
			pos_ovf = 0; 
			writ_k(n2, &pos_ovf, k, parm_ovf,n1%2); 
			writ_ovf(n_pack, parm_ovf, 4*n2, pos_i_ovf, pos_n, parm_ptr); 
			for (i=0; i