www.pudn.com > AVS_M_ver10.rar > avq_dec.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 "../include/amr_plus.h" 
 
#ifdef NEW_TVC 
#define HD_MAX     12 
#define NQ_MAX	36 
#define FAC_LOG2   3.321928095 
#define NSV_MAX    256     /* number of sub-vector max in QVAE, 256*8=2048 */ 
/* local functions */ 
static int read_nq(int *nq, int* flag, int *n_bits, int *parm, int *pos, int *cache_use); 
static void read_all_nq(int n_pack, int NB_BITS, int Nsv, int *pos_n, int *nq, int *last, int **parm_ptr, int* flag, int *cache_use); 
static void write_bits(int *n_bits, int last_bits); 
static void chk_ovf(int n_bits, int n, int *n1, int *n2); 
static void read_I(int n, int *pos_i, long *I, int *parm); 
static void read_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_use); 
void read_ovf(int n_pack, int *parm_ovf, int n, int *pos_i_ovf, int *pos_n, int **parm_ptr); 
static void read_all_i(int n_pack, int *nq, int *pos_n, int last, long *I, int *kv, int **parm_ptr, int* flag, int *cache_use); 
static void read_track(int *pos_n, int *pos_i, int *nq, long *I, int *kv, int *parm, int* flag, int *cache_use); 
static void hit_cache(long index, int *cache_p, int y[]); 
static void update_cache(int *cache_p, int y[]); 
 
int cache[16*9]={0}; /* LVQ cache when RE8 lattice locate in Q2 */ 
 
/* 
  AVQ_demuxdec_multi(parm, xriq, parm, NB_BITS, Nsv, n_pack, bfi) 
  DEMULTIPLEX AND DECODE SUBVECTORS FROM SEVERAL PACKETS 
  -> n_pack  : number of packets 
  -> parm    : bitstream = table of 4-bit words [0..(NB_BITS-1)/4] 
               the bitstream is divided into n_pack blocks 
             parm[0]..parm[NB_BITS-1] 
  <- 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 
  -> bfi     : bad frame indicator for each packet 
  notes (see AVQ_encmux_multi) 
*/ 
void AVQ_demuxdec(int n_pack, int *param, int *n_bits, float *xriq, int Nsv, int *bfi) 
{ 
  int p, pos_i[N_PACK_MAX], pos_n[N_PACK_MAX], l, i; 
  int any_loss; 
  int nq[NSV_MAX], *kv, last, c[8], flag[NSV_MAX]; 
  long I[NSV_MAX]; 
  int *parm_ptr[4]; 
  int NB_BITS; 
 
 
  //new 
  int cache_use[NSV_MAX]; 
  int a[8]; 
 
  memset(cache_use, 0, NSV_MAX*sizeof(int)); 
  memset(a, 0, 8*sizeof(int)); 
  //end 
   
  kv = (int *)xriq;        /* reuse vector to save memory */ 
  NB_BITS=0; 
  for (i=0; ip[0])  
				{ 
				if (tmp1&&j[0]<5) j[0]=j[0]-1; 
			else if (j[0]>4) ; 
			else {j[0]=4;p=j;} 
 
	} 
	for (i=0;i<8;i++) 
		p[i+1]=y[i]; 
 
	return; 
	 
} 
 
static int read_nq(int *nq, int *flag, int *n_bits, int *parm, int *pos, int *cache_use) 
{ 
  int hd = 0, hd_len = 0, even_flag = 0, spec_flag = 0, t, mode; 
   
  *nq = 0; 
   *flag = 0; 
  hd = 0; 
  if (*n_bits >= 10) { 
    if (((parm[*pos/4] >> (*pos%4)) & 0x01) == 1) { 
	hd_len++; 
	hd = 1; 
      *pos = *pos-1; 
      /* CHECK: add a test for nq == NQ_MAX */ 
      while ((((parm[*pos/4] >> (*pos%4)) & 0x01) == 1)  
	  	&& (hd_len<=HD_MAX)) { 
	  /* FIXME check available bits here */ 
	  hd_len++; 
	  hd = (hd << 1) + 1; 
        *pos = *pos-1; 
      } 
	if (hd_len == HD_MAX + 1 || hd_len == HD_MAX){ 
	  /* scalar quantizer: 111111 11 11 11*/ 
	  /* read 1 more bit for even_flag */ 
	  *flag = RE8_MODE_SCALAR; 
 
	  if (hd_len == HD_MAX){ 
	  	even_flag = 0; 
	  	hd = (hd << 1); 
	  	*pos = *pos -1; 
	  }else{ 
	  	even_flag = 1; 
	  } 
	  /* read 2 more bit for bits/digital */ 
	  mode = (parm[*pos/4] >> (*pos%4)) & 0x01; 
	  *pos = *pos -1; 
	  mode = (mode << 1) +( (parm[*pos/4] >> (*pos%4)) & 0x01); 
	  *pos = *pos -1; 
	  *nq = mode + 6; 
	  hd = (hd << 2) + mode; 
	  }else{ 
		switch (hd_len){ 
			case 1:				/* in Q2: 10*/ 
				*flag = RE8_MODE_BASE; 
				*nq = 2; 
				/* read 1 more stop bit */ 
				hd = hd << 1; 
				*pos = *pos -1; 
				break; 
 
			case 2:				/* in Q3: 110 */ 
				*flag = RE8_MODE_BASE; 
				*nq = 3; 
				/* read 1 more stop bit */ 
				hd = hd << 1; 
				*pos = *pos -1; 
				*cache_use = (parm[*pos/4] >> (*pos%4)) & 0x01; 
				if (*cache_use) 
					*nq = 2; 
				hd = (hd << 1) + *cache_use; 
				*pos = *pos - 1; 
				break; 
			case 3:				/* in Q4: 1110x */ 
				*flag = RE8_MODE_BASE; 
				*nq = 4; 
				/* read 1 more stop bit */ 
				hd = hd << 1; 
				*pos = *pos -1; 
				/* read 1 more even_flag bit */ 
				even_flag = (parm[*pos/4] >> (*pos%4)) & 0x01; 
				hd = (hd << 1) + even_flag; 
				*pos = *pos - 1; 
				break;				 
			case 4:				/* r=1 in Q4: 11110 */ 
				*flag = RE8_MODE_EXT1; 
				*nq = 6; 
				/* read 1 more stop bit */ 
				hd = hd << 1; 
				*pos = *pos -1; 
				/* read 1 more even_flag bit */ 
				even_flag = (parm[*pos/4] >> (*pos%4)) & 0x01; 
				hd = (hd << 1) + even_flag; 
				*pos = *pos -1; 
				break;						 
			case 5:				/* r=2, in Q4: 111110 */ 
				*flag = RE8_MODE_EXT2; 
				*nq = 8; 
				/* read 1 more stop bit */ 
				hd = hd << 1; 
				*pos = *pos -1; 
				/* read 1 more even_flag bit */ 
				even_flag = (parm[*pos/4] >> (*pos%4)) & 0x01; 
				hd = (hd << 1) + even_flag; 
				*pos = *pos -1; 
				break;						 
			case 7:				/* r=0(base), in inv_Q4 */ 
				*flag = RE8_MODE_BASE; 
				*nq = 4; 
				spec_flag = 1; 
				/* read 1 more stop bit */ 
				hd = hd << 1; 
				*pos = *pos -1; 
				/* read 1 more even_flag bit */ 
				even_flag = (parm[*pos/4] >> (*pos%4)) & 0x01; 
				hd = (hd << 1) + even_flag; 
				*pos = *pos -1; 
				break;						 
			case 9:				/* r=3, in Q4: 111111 11 10 */ 
				*flag = RE8_MODE_EXT3; 
				*nq = 10; 
				/* read 1 more stop bit */ 
				hd = hd << 1; 
				*pos = *pos -1; 
				/* read 1 more even_flag bit */ 
				even_flag = (parm[*pos/4] >> (*pos%4)) & 0x01; 
				hd = (hd << 1) + even_flag; 
				*pos = *pos -1; 
				break;						 
			case 10:				/* r=2 in inv_Q4 111111 11 11 0 */ 
				*flag = RE8_MODE_EXT2; 
				*nq = 8; 
				spec_flag = 1; 
				/* read 1 more stop bit */ 
				hd = hd << 1; 
				*pos = *pos -1; 
				/* read 1 more even_flag bit */ 
				even_flag = (parm[*pos/4] >> (*pos%4)) & 0x01; 
				hd = (hd << 1) + even_flag; 
				*pos = *pos -1; 
				break;	 
			case 11:				/* r=3 in inv_q4 111111 11 11 10 */ 
				*flag = RE8_MODE_EXT3; 
				*nq = 10; 
				spec_flag = 1; 
				/* read 1 more stop bit */ 
				hd = hd << 1; 
				*pos = *pos -1; 
				/* read 1 more even_flag bit */ 
				even_flag = (parm[*pos/4] >> (*pos%4)) & 0x01; 
				hd = (hd << 1) + even_flag; 
				*pos = *pos-1; 
				break; 
			case 6:				/* r=1 or 2 in Q3: 111111 00 or 111111 01 */ 
				/* read 0 bit */ 
				hd = hd << 1; 
				*pos = *pos -1; 
				/* read 1 bit from parm */ 
				t = (parm[*pos/4] >> (*pos%4)) & 0x01; 
				if (t == 0){ 
					*flag = RE8_MODE_EXT1; 
					*nq = 5; 
				}else{ 
					*flag = RE8_MODE_EXT2; 
					*nq = 7; 
				} 
				hd = (hd << 1) + t; 
				*pos = *pos -1; 
				/* read 1 more even_flag bit */ 
				even_flag = (parm[*pos/4] >> (*pos%4)) & 0x01; 
				hd = (hd << 1) + even_flag; 
				*pos = *pos -1;	 
				break; 
			case 8:				/* r=1 in inv_Q4: 111111 11 00 or r=3 in Q3:       111111 11 01 */ 
				/* read 0 bit */ 
				hd = hd << 1; 
				*pos = *pos -1; 
				/* read 1 bit from parm */ 
				t = (parm[*pos/4] >> (*pos%4)) & 0x01; 
				if (t == 0){ 
					*flag = RE8_MODE_EXT1; 
					*nq = 6; 
					spec_flag = 1; 
				}else{ 
					*flag = RE8_MODE_EXT3; 
					*nq = 9; 
				} 
				hd = (hd << 1) + t; 
				*pos = *pos -1; 
				/* read 1 more even_flag bit */ 
				even_flag = (parm[*pos/4] >> (*pos%4)) & 0x01; 
				hd = (hd << 1) + even_flag; 
				*pos = *pos -1;				 
				break; 
			default: 
				printf("unkown length of header: %d \r\n", hd_len); 
		} 
	} 
	if (spec_flag) *flag |= RE8_SPEC_FLAG; 
	if (even_flag) *flag |= RE8_EVEN_FLAG; 
		 
    }else{ 
    	*pos = *pos - 1; 
    } 
  } 
//  printf("header = %x\r\n", hd); 
  return hd; 
/*  if (*n_bits > 0) { 
    *n_bits = *n_bits-1; 
    *pos = *pos-1; 
  }*/ 
} 
/* 
  read_all_nq(pos_n, n_pack, nq, pos_ovf, n_bits_left, last, parm) 
  DE-MULTIPLEX AND DECODE AND ALL CODEBOOKS NUMBERS IN nq[] TRACK-BY-TRACK 
   ->  nq         : table of codebook numbers [0..Nsv-1] 
   ->  pos_n      : table of pointers to write nq in packets [0..n_pack-1] 
   ->  NB_BITS    : number of bits allocated for split multi-rate RE8 VQ 
   ->  n_pack     : number of packets 
   ->  last       : index of last described subvector 
  <-  pos_ovf     : pointers for overflow [0..n_pack-1] 
  <-  n_bits_left : number of unused bits in packets [0..n_pack-1] 
  <-> parm        : bistream 
*/ 
static void read_all_nq(int n_pack, int NB_BITS, int Nsv, int *pos_n, int *nq, int *last, int **parm_ptr, int* flag, int *cache_use) 
{ 
  int n_bits, p, l; 
  n_bits = NB_BITS; 
  *last = -1; 
  for (l=0; l 0) { 
	*last = l; 
      } 
  } 
  return; 
} 
/* check if n groups of 4 bits (i.e. 4n 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; 
  } 
} 
/* read 4n bits for base codebook index (I) */ 
static void read_I(int n, int *pos_i, long *I, int *parm) 
{ 
  int pos; 
  /* base codebook index */ 
  *pos_i = *pos_i + 4*n; 
  pos = *pos_i/4 - 1; 
  while (n-- > 0) { 
    *I = *I << 4; 
    *I = *I+(parm[pos--] & 0x0F); 
  } 
} 
/* read 4n bits for Voronoi index (k[]) */ 
static void read_k(int n, int *pos_i, int *k, int *parm, int flag) 
{ 
  int pos, i, ival, delta, *kv; 
  *pos_i = *pos_i + 4*n; 
  pos = *pos_i/4 -1; 
  delta = 4*flag; 
  while (n-- > 0) { 
    kv=k+delta; 
    ival = (parm[pos--] & 0x0F); /* optional mask */ 
    for (i=3; i>=0; i--) { 
      kv[i] <<= 1; 
      kv[i] += (ival & 0x01); 
      ival >>= 1; 
    } 
    delta = (delta+4)%8; /* circular shift */ 
  } 
} 
/* split a codebook number (nq) into a number of bits for the base 
   codebook index (4 x ni) and  the Voronoi index (4 x nk) */ 
static void split_n(int nq, int *ni, int *nk) 
{ 
  int tmp; 
  *ni = nq; 
  *nk=0; 
  if (*ni > 4) { 
    tmp = (*ni-4+1)/2; 
    *nk = tmp*2; 
    *ni -= *nk; 
  } 
} 
/* 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_use) 
{ 
  int p, pos, n_bits, l, n1, n2,ni; 
  /* find in each packet the positions where overflow occurs & count the number 
     of bits to put in the extra packet */ 
  for (p=0; p 0) {    
	  	ni=nq[l]; 
	  if (cache_use[l]==1) 
	  	ni=ni-1; 
 
        chk_ovf(n_bits, ni, &n1, &n2); 
        n_bits -= 4*n1; 
        pos += n1; 
      } 
    } 
    pos_i_ovf[p] = pos*4; 
  } 
} 
/* read bits in overflow */ 
void read_ovf(int n_pack, int *parm_ovf, int n, int *pos_i_ovf, int *pos_n, int **parm_ptr) 
{ 
  int p, n_bits, pos, *parm, pos_ovf, moved_bit; 
  /* initialize position in overflow packet (parm_ovf[]) */ 
  pos_ovf = 0; 
  /* read 4-bit chunks */ 
  for (p=0; p= 4) && (n>0)) { 
      pos = pos_i_ovf[p]/4; 
      parm = parm_ptr[p]; 
      do { 
        parm_ovf[pos_ovf++] = parm[pos++]; 
        n_bits -= 4; 
        n-=4; 
      } while ((n_bits >= 4) && (n>0)); 
    pos_i_ovf[p] = pos*4; 
    } 
  } 
  pos_ovf *= 4; 
  /* read bit-by-bit */ 
  for (p=0; p 0) && (n>0)) { 
      pos = pos_i_ovf[p]; 
      parm = parm_ptr[p]; 
      do { 
        moved_bit = (parm[pos/4] >> (pos%4)) & 0x01; 
        parm_ovf[pos_ovf/4] += moved_bit << (pos_ovf%4); 
        n_bits--; 
        n--; 
        pos++; 
        pos_ovf++; 
      } while ((n_bits > 0) && (n>0)); 
      pos_i_ovf[p] = pos; 
    } 
  } 
} 
/* 
  read_all_i(nq, p, pos_n, n_pack, last, pos_ovf, n_bits_left, I, kv, parm) 
  DEMULTIPLEX AN INDEX (I,kv) OF 4*nq BITS FROM BITSTREAM 
  (THE INDEX CORRESPONDS TO A SUBVECTOR IN TRACK #p) 
   -> n_pack      : number for packets 
   -> nq          : codebook numbers 
   -> pos_n       : position in bitstream after reading nq[] 
   -> last        : index of last described subvector 
  <-  I           : base codebook index 
  <-  kv          : Voronoi index 
   -> parm_ptr    : multiple bistreams 
*/ 
static void read_all_i(int n_pack, int *nq, int *pos_n, int last, long *I, int *kv, int **parm_ptr, int* flag, int *cache_use) 
{ 
  int pos_ovf, p, l, n_bits, ni, nk, n1, i, n2, pos, *parm, pos_i_ovf[N_PACK_MAX]; 
  long index; 
  //char str[35]; 
  int parm_ovf[NQ_MAX]; 
  /* initialize overflow packet */ 
  for (i=0; i 0) {       
        /* compute number of bits left for indices in packet #p */ 
        n_bits = pos_n[p]-pos+1; 
	if ((flag[l] & RE8_MODE_MASK) != RE8_MODE_SCALAR){ 
        split_n(nq[l], &ni, &nk); 
        /* read I in packet #p and in overflow */ 
	if (cache_use[l]==1) 
		ni=ni-1; 
 
        chk_ovf(n_bits, ni, &n1, &n2); 
        index = 0; 
        if (n2>0) { 
          pos_ovf = 0; 
          read_ovf(n_pack, parm_ovf, 4*n2, pos_i_ovf, pos_n, parm_ptr); 
          read_I(n2, &pos_ovf, &index, parm_ovf); 
          for (i=0; i0) { 
          for (i=0; i<8; i++) { 
            kv[8*l+i] = 0; 
          } 
          chk_ovf(n_bits, nk, &n1, &n2); 
          if (n2>0) { 
            pos_ovf = 0; 
            read_ovf(n_pack, parm_ovf, 4*n2, pos_i_ovf, pos_n, parm_ptr); 
            read_k(n2, &pos_ovf, &kv[8*l], parm_ovf,1); 
            for (i=0; i0) { 
            pos_ovf = 0; 
            read_ovf(n_pack, parm_ovf, 4*n2, pos_i_ovf, pos_n, parm_ptr); 
            read_k(n2, &pos_ovf, &kv[8*l], parm_ovf,1); 
            for (i=0; i pos_n       : pointer to read nq 
  <-> pos_i       : pointer to read i 
  <-  nq          : codebook number (scalar) 
  <-  I           : base codebook index 
  <-  kv          : Voronoi index 
   -> parm        : bistream 
*/ 
static void read_track(int *pos_n, int *pos_i, int *nq, long *I, int *kv, int *parm, int* flag, int *cache_use) 
{ 
  int n_bits, i,ni,nk; 
  /* compute number of bits left for indices in packet #p */ 
  n_bits = *pos_n-*pos_i+1; 
  /* read nq */ 
  read_nq(nq, flag, &n_bits, parm, pos_n, cache_use); 
  /* read i and kv */ 
  if (*nq > 0) { 
    *I=0; 
    for (i=0; i<8; i++) { 
      kv[i] = 0; 
    } 
    split_n(*nq, &ni, &nk); 
    if (*nq==2&&*cache_use==1) 
		ni=ni-1; 
 
    read_I(ni, pos_i, I, parm); 
    read_k(nk, pos_i, kv, parm,1); 
  } 
} 
#if 0 
int read_n_test(int *nq, int *flag, int *n_bits, int *parm, int *pos, int *cache_use) 
{ 
	return read_nq(nq, flag, n_bits, parm, pos,cache_use); 
} 
 
void read_i_test(int nq, long* I,  int* kv, int* pos_i, int* pos_n, int* parm, int flag) 
{ 
	int n_bits, ni, nk, n1, n2, i; 
	long index; 
	 if (nq > 0) { 
        /* compute number of bits left for indices in packet #p */ 
        n_bits = *pos_n-*pos_i+1; 
	if ((flag & RE8_MODE_MASK) != RE8_MODE_SCALAR){ 
        split_n(nq, &ni, &nk); 
        /* read I in packet #p and in overflow */ 
        chk_ovf(n_bits, ni, &n1, &n2); 
        index = 0; 
        read_I(n1, pos_i, &index, parm); 
        n_bits -= 4*n1; 
        *I = index; 
        /* read table index  */ 
        if (nk >0) { 
          for (i=0; i<8; i++) { 
            kv[i] = 0; 
          } 
          chk_ovf(n_bits, nk, &n1, &n2); 
          read_k(n1, pos_i, kv, parm,(n2+1)%2); 
        } 
	}else{ 
          /* scalar quantizer, bits/digital in n */ 
          for (i=0; i<8; i++) { 
            kv[i] = 0; 
          } 
          chk_ovf(n_bits, nq*2, &n1, &n2); 
          read_k(n1, pos_i, kv, parm,(n2+1)%2);		 
	} 
      } 
} 
#endif 
#else 
#define NQ_MAX     36 
#define FAC_LOG2   3.321928095 
#define NSV_MAX    256     /* number of sub-vector max in QVAE, 256*8=2048 */ 
/* local functions */ 
static void read_nq(int *nq, int *n_bits, int *parm, int *pos); 
static void read_all_nq(int n_pack, int NB_BITS, int Nsv, int *pos_n, int *nq, int *last, int **parm_ptr); 
static void chk_ovf(int n_bits, int n, int *n1, int *n2); 
static void read_I(int n, int *pos_i, long *I, int *parm); 
static void read_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); 
void read_ovf(int n_pack, int *parm_ovf, int n, int *pos_i_ovf, int *pos_n, int **parm_ptr); 
static void read_all_i(int n_pack, int *nq, int *pos_n, int last, long *I, int *kv, int **parm_ptr); 
static void read_track(int *pos_n, int *pos_i, int *nq, long *I, int *kv, int *parm); 
/* 
  AVQ_demuxdec_multi(parm, xriq, parm, NB_BITS, Nsv, n_pack, bfi) 
  DEMULTIPLEX AND DECODE SUBVECTORS FROM SEVERAL PACKETS 
  -> n_pack  : number of packets 
  -> parm    : bitstream = table of 4-bit words [0..(NB_BITS-1)/4] 
               the bitstream is divided into n_pack blocks 
             parm[0]..parm[NB_BITS-1] 
  <- 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 
  -> bfi     : bad frame indicator for each packet 
  notes (see AVQ_encmux_multi) 
*/ 
void AVQ_demuxdec(int n_pack, int *param, int *n_bits, float *xriq, int Nsv, int *bfi) 
{ 
  int p, pos_i[N_PACK_MAX], pos_n[N_PACK_MAX], l, i; 
  int any_loss; 
  int nq[NSV_MAX], *kv, last, c[8]; 
  long I[NSV_MAX]; 
  int *parm_ptr[4]; 
  int NB_BITS; 
  kv = (int *)xriq;        /* reuse vector to save memory */ 
  NB_BITS=0; 
  for (i=0; i= 9) { 
    if (((parm[*pos/4] >> (*pos%4)) & 0x01) == 1) { 
      *nq = 2; 
      *n_bits -= 9; 
      *pos = *pos-1; 
      /* CHECK: add a test for nq == NQ_MAX */ 
      while ((((parm[*pos/4] >> (*pos%4)) & 0x01) == 1) && 
             (*n_bits >= 5) && (*nq 0) { 
    *n_bits = *n_bits-1; 
    *pos = *pos-1; 
  } 
} 
/* 
  read_all_nq(pos_n, n_pack, nq, pos_ovf, n_bits_left, last, parm) 
  DE-MULTIPLEX AND DECODE AND ALL CODEBOOKS NUMBERS IN nq[] TRACK-BY-TRACK 
   ->  nq         : table of codebook numbers [0..Nsv-1] 
   ->  pos_n      : table of pointers to write nq in packets [0..n_pack-1] 
   ->  NB_BITS    : number of bits allocated for split multi-rate RE8 VQ 
   ->  n_pack     : number of packets 
   ->  last       : index of last described subvector 
  <-  pos_ovf     : pointers for overflow [0..n_pack-1] 
  <-  n_bits_left : number of unused bits in packets [0..n_pack-1] 
  <-> parm        : bistream 
*/ 
static void read_all_nq(int n_pack, int NB_BITS, int Nsv, int *pos_n, int *nq, int *last, int **parm_ptr) 
{ 
  int n_bits, p, l; 
  n_bits = NB_BITS; 
  *last = -1; 
  for (l=0; l 0) { 
	*last = l; 
      } 
  } 
  return; 
} 
/* check if n groups of 4 bits (i.e. 4n 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; 
  } 
} 
/* read 4n bits for base codebook index (I) */ 
static void read_I(int n, int *pos_i, long *I, int *parm) 
{ 
  int pos; 
  /* base codebook index */ 
  *pos_i = *pos_i + 4*n; 
  pos = *pos_i/4 - 1; 
  while (n-- > 0) { 
    *I = *I << 4; 
    *I = *I+(parm[pos--] & 0x0F); 
  } 
} 
/* read 4n bits for Voronoi index (k[]) */ 
static void read_k(int n, int *pos_i, int *k, int *parm, int flag) 
{ 
  int pos, i, ival, delta, *kv; 
  *pos_i = *pos_i + 4*n; 
  pos = *pos_i/4 -1; 
  delta = 4*flag; 
  while (n-- > 0) { 
    kv=k+delta; 
    ival = (parm[pos--] & 0x0F); /* optional mask */ 
    for (i=3; i>=0; i--) { 
      kv[i] <<= 1; 
      kv[i] += (ival & 0x01); 
      ival >>= 1; 
    } 
    delta = (delta+4)%8; /* circular shift */ 
  } 
} 
/* split a codebook number (nq) into a number of bits for the base 
   codebook index (4 x ni) and  the Voronoi index (4 x nk) */ 
static void split_n(int nq, int *ni, int *nk) 
{ 
  int tmp; 
  *ni = nq; 
  *nk=0; 
  if (*ni > 4) { 
    tmp = (*ni-4+1)/2; 
    *nk = tmp*2; 
    *ni -= *nk; 
  } 
} 
/* 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; 
  /* find in each packet the positions where overflow occurs & count the number 
     of bits to put in the extra packet */ 
  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; 
  } 
} 
/* read bits in overflow */ 
void read_ovf(int n_pack, int *parm_ovf, int n, int *pos_i_ovf, int *pos_n, int **parm_ptr) 
{ 
  int p, n_bits, pos, *parm, pos_ovf, moved_bit; 
  /* initialize position in overflow packet (parm_ovf[]) */ 
  pos_ovf = 0; 
  /* read 4-bit chunks */ 
  for (p=0; p= 4) && (n>0)) { 
      pos = pos_i_ovf[p]/4; 
      parm = parm_ptr[p]; 
      do { 
        parm_ovf[pos_ovf++] = parm[pos++]; 
        n_bits -= 4; 
        n-=4; 
      } while ((n_bits >= 4) && (n>0)); 
    pos_i_ovf[p] = pos*4; 
    } 
  } 
  pos_ovf *= 4; 
  /* read bit-by-bit */ 
  for (p=0; p 0) && (n>0)) { 
      pos = pos_i_ovf[p]; 
      parm = parm_ptr[p]; 
      do { 
        moved_bit = (parm[pos/4] >> (pos%4)) & 0x01; 
        parm_ovf[pos_ovf/4] += moved_bit << (pos_ovf%4); 
        n_bits--; 
        n--; 
        pos++; 
        pos_ovf++; 
      } while ((n_bits > 0) && (n>0)); 
      pos_i_ovf[p] = pos; 
    } 
  } 
} 
/* 
  read_all_i(nq, p, pos_n, n_pack, last, pos_ovf, n_bits_left, I, kv, parm) 
  DEMULTIPLEX AN INDEX (I,kv) OF 4*nq BITS FROM BITSTREAM 
  (THE INDEX CORRESPONDS TO A SUBVECTOR IN TRACK #p) 
   -> n_pack      : number for packets 
   -> nq          : codebook numbers 
   -> pos_n       : position in bitstream after reading nq[] 
   -> last        : index of last described subvector 
  <-  I           : base codebook index 
  <-  kv          : Voronoi index 
   -> parm_ptr    : multiple bistreams 
*/ 
static void read_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, *parm, pos_i_ovf[N_PACK_MAX]; 
  long index; 
  int parm_ovf[NQ_MAX]; 
  /* initialize overflow packet */ 
  for (i=0; i 0) {       
        /* compute number of bits left for indices in packet #p */ 
        n_bits = pos_n[p]-pos+1; 
        split_n(nq[l], &ni, &nk); 
        /* read I in packet #p and in overflow */ 
        chk_ovf(n_bits, ni, &n1, &n2); 
        index = 0; 
        if (n2>0) { 
          pos_ovf = 0; 
          read_ovf(n_pack, parm_ovf, 4*n2, pos_i_ovf, pos_n, parm_ptr); 
          read_I(n2, &pos_ovf, &index, parm_ovf); 
          for (i=0; i0) { 
          for (i=0; i<8; i++) { 
            kv[8*l+i] = 0; 
          } 
          chk_ovf(n_bits, nk, &n1, &n2); 
          if (n2>0) { 
            pos_ovf = 0; 
            read_ovf(n_pack, parm_ovf, 4*n2, pos_i_ovf, pos_n, parm_ptr); 
            read_k(n2, &pos_ovf, &kv[8*l], parm_ovf,1); 
            for (i=0; i pos_n       : pointer to read nq 
  <-> pos_i       : pointer to read i 
  <-  nq          : codebook number (scalar) 
  <-  I           : base codebook index 
  <-  kv          : Voronoi index 
   -> parm        : bistream 
*/ 
static void read_track(int *pos_n, int *pos_i, int *nq, long *I, int *kv, int *parm) 
{ 
  int n_bits, i,ni,nk; 
  /* compute number of bits left for indices in packet #p */ 
  n_bits = *pos_n-*pos_i+1; 
  /* read nq */ 
  read_nq(nq, &n_bits, parm, pos_n); 
  /* read i and kv */ 
  if (*nq > 0) { 
    *I=0; 
    for (i=0; i<8; i++) { 
      kv[i] = 0; 
    } 
    split_n(*nq, &ni, &nk); 
    read_I(ni, pos_i, I, parm); 
    read_k(nk, pos_i, kv, parm,1); 
  } 
} 
#endif