www.pudn.com > g729.rar > qua_gain.c


/* 
   ITU-T G.729A Speech Coder    ANSI-C Source Code 
   Version 1.1    Last modified: September 1996 
 
   Copyright (c) 1996, 
   AT&T, France Telecom, NTT, Universite de Sherbrooke 
   All rights reserved. 
*/ 
 
#include "typedef.h" 
#include "basic_op.h" 
#include "oper_32b.h" 
 
#include "ld8a.h" 
#include "tab_ld8a.h" 
 
static void Gbk_presel( 
   Word16 best_gain[],     /* (i) [0] Q9 : unquantized pitch gain     */ 
                           /* (i) [1] Q2 : unquantized code gain      */ 
   Word16 *cand1,          /* (o)    : index of best 1st stage vector */ 
   Word16 *cand2,          /* (o)    : index of best 2nd stage vector */ 
   Word16 gcode0           /* (i) Q4 : presearch for gain codebook    */ 
); 
 
 
/*---------------------------------------------------------------------------* 
 * Function  Qua_gain                                                        * 
 * ~~~~~~~~~~~~~~~~~~                                                        * 
 * Inputs:                                                                   * 
 *   code[]     :Innovative codebook.                                        * 
 *   g_coeff[]  :Correlations compute for pitch.                             * 
 *   L_subfr    :Subframe length.                                            * 
 *                                                                           * 
 * Outputs:                                                                  * 
 *   gain_pit   :Quantized pitch gain.                                       * 
 *   gain_cod   :Quantized code gain.                                        * 
 *                                                                           * 
 * Return:                                                                   * 
 *   Index of quantization.                                                  * 
 *                                                                           * 
 *--------------------------------------------------------------------------*/ 
Word16 Qua_gain( 
   Word16 code[],       /* (i) Q13 :Innovative vector.             */ 
   Word16 g_coeff[],    /* (i)     :Correlations  -2 */ 
                        /*            , -2, 2 */ 
   Word16 exp_coeff[],  /* (i)     :Q-Format g_coeff[]             */ 
   Word16 L_subfr,      /* (i)     :Subframe length.               */ 
   Word16 *gain_pit,    /* (o) Q14 :Pitch gain.                    */ 
   Word16 *gain_cod,    /* (o) Q1  :Code gain.                     */ 
   Word16 tameflag      /* (i)     : set to 1 if taming is needed  */ 
) 
{ 
   Word16  i, j, index1, index2; 
   Word16  cand1, cand2; 
   Word16  exp, gcode0, exp_gcode0, gcode0_org, e_min ; 
   Word16  nume, denom, inv_denom; 
   Word16  exp1,exp2,exp_nume,exp_denom,exp_inv_denom,sft,tmp; 
   Word16  g_pitch, g2_pitch, g_code, g2_code, g_pit_cod; 
   Word16  coeff[5], coeff_lsf[5]; 
   Word16  exp_min[5]; 
   Word32  L_gbk12; 
   Word32  L_tmp, L_dist_min, L_temp, L_tmp1, L_tmp2, L_acc, L_accb; 
   Word16  best_gain[2]; 
 
        /* Gain predictor, Past quantized energies = -14.0 in Q10 */ 
 
 static Word16 past_qua_en[4] = { -14336, -14336, -14336, -14336 }; 
 
  /*---------------------------------------------------* 
   *-  energy due to innovation                       -* 
   *-  predicted energy                               -* 
   *-  predicted codebook gain => gcode0[exp_gcode0]  -* 
   *---------------------------------------------------*/ 
 
   Gain_predict( past_qua_en, code, L_subfr, &gcode0, &exp_gcode0 ); 
 
  /*-----------------------------------------------------------------* 
   *  pre-selection                                                  * 
   *-----------------------------------------------------------------*/ 
  /*-----------------------------------------------------------------* 
   *  calculate best gain                                            * 
   *                                                                 * 
   *  tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ;           * 
   *  best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ;  * 
   *  best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ;  * 
   *  gbk_presel(best_gain,&cand1,&cand2,gcode0) ;                   * 
   *                                                                 * 
   *-----------------------------------------------------------------*/ 
 
  /*-----------------------------------------------------------------* 
   *  tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ;           * 
   *-----------------------------------------------------------------*/ 
   L_tmp1 = L_mult( g_coeff[0], g_coeff[2] ); 
   exp1   = add( add( exp_coeff[0], exp_coeff[2] ), 1-2 ); 
   L_tmp2 = L_mult( g_coeff[4], g_coeff[4] ); 
   exp2   = add( add( exp_coeff[4], exp_coeff[4] ), 1 ); 
 
   if( sub(exp1, exp2)>0 ){ 
      L_tmp = L_sub( L_shr( L_tmp1, sub(exp1,exp2) ), L_tmp2 ); 
      exp = exp2; 
   } 
   else{ 
      L_tmp = L_sub( L_tmp1, L_shr( L_tmp2, sub(exp2,exp1) ) ); 
      exp = exp1; 
   } 
   sft = norm_l( L_tmp ); 
   denom = extract_h( L_shl(L_tmp, sft) ); 
   exp_denom = sub( add( exp, sft ), 16 ); 
 
   inv_denom = div_s(16384,denom); 
   inv_denom = negate( inv_denom ); 
   exp_inv_denom = sub( 14+15, exp_denom ); 
 
  /*-----------------------------------------------------------------* 
   *  best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ;  * 
   *-----------------------------------------------------------------*/ 
   L_tmp1 = L_mult( g_coeff[2], g_coeff[1] ); 
   exp1   = add( exp_coeff[2], exp_coeff[1] ); 
   L_tmp2 = L_mult( g_coeff[3], g_coeff[4] ); 
   exp2   = add( add( exp_coeff[3], exp_coeff[4] ), 1 ); 
 
   if( sub(exp1, exp2)>0 ){ 
      L_tmp = L_sub( L_shr( L_tmp1, add(sub(exp1,exp2),1 )), L_shr( L_tmp2,1 ) ); 
      exp = sub(exp2,1); 
   } 
   else{ 
      L_tmp = L_sub( L_shr( L_tmp1,1 ), L_shr( L_tmp2, add(sub(exp2,exp1),1 )) ); 
      exp = sub(exp1,1); 
   } 
   sft = norm_l( L_tmp ); 
   nume = extract_h( L_shl(L_tmp, sft) ); 
   exp_nume = sub( add( exp, sft ), 16 ); 
 
   sft = sub( add( exp_nume, exp_inv_denom ), (9+16-1) ); 
   L_acc = L_shr( L_mult( nume,inv_denom ), sft ); 
   best_gain[0] = extract_h( L_acc );             /*-- best_gain[0]:Q9 --*/ 
 
   if (tameflag == 1){ 
     if(sub(best_gain[0], GPCLIP2) > 0) best_gain[0] = GPCLIP2; 
   } 
 
  /*-----------------------------------------------------------------* 
   *  best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ;  * 
   *-----------------------------------------------------------------*/ 
   L_tmp1 = L_mult( g_coeff[0], g_coeff[3] ); 
   exp1   = add( exp_coeff[0], exp_coeff[3] ) ; 
   L_tmp2 = L_mult( g_coeff[1], g_coeff[4] ); 
   exp2   = add( add( exp_coeff[1], exp_coeff[4] ), 1 ); 
 
   if( sub(exp1, exp2)>0 ){ 
      L_tmp = L_sub( L_shr( L_tmp1, add(sub(exp1,exp2),1) ), L_shr( L_tmp2,1 ) ); 
      exp = sub(exp2,1); 
   } 
   else{ 
      L_tmp = L_sub( L_shr( L_tmp1,1 ), L_shr( L_tmp2, add(sub(exp2,exp1),1) ) ); 
      exp = sub(exp1,1); 
   } 
   sft = norm_l( L_tmp ); 
   nume = extract_h( L_shl(L_tmp, sft) ); 
   exp_nume = sub( add( exp, sft ), 16 ); 
 
   sft = sub( add( exp_nume, exp_inv_denom ), (2+16-1) ); 
   L_acc = L_shr( L_mult( nume,inv_denom ), sft ); 
   best_gain[1] = extract_h( L_acc );             /*-- best_gain[1]:Q2 --*/ 
 
   /*--- Change Q-format of gcode0 ( Q[exp_gcode0] -> Q4 ) ---*/ 
   if( sub(exp_gcode0,4) >= 0 ){ 
      gcode0_org = shr( gcode0, sub(exp_gcode0,4) ); 
   } 
   else{ 
      L_acc = L_deposit_l( gcode0 ); 
      L_acc = L_shl( L_acc, sub( (4+16), exp_gcode0 ) ); 
      gcode0_org = extract_h( L_acc );              /*-- gcode0_org:Q4 --*/ 
   } 
 
  /*----------------------------------------------* 
   *   - presearch for gain codebook -            * 
   *----------------------------------------------*/ 
 
   Gbk_presel(best_gain, &cand1, &cand2, gcode0_org ); 
 
/*---------------------------------------------------------------------------* 
 *                                                                           * 
 * Find the best quantizer.                                                  * 
 *                                                                           * 
 *  dist_min = MAX_32;                                                       * 
 *  for ( i=0 ; i !!y */ 
   L_acc = L_shr( L_coef[1][1], 15 );                  /* L_acc:Q20     */ 
   L_acc = L_add( L_cfbg , L_acc ); 
   acc_h = extract_h( L_acc );                         /* acc_h:Q4      */ 
   L_preg = L_mult( acc_h, gcode0 );                   /* L_preg:Q9     */ 
   L_acc = L_shl( L_deposit_l( best_gain[1] ), 7 );    /* L_acc:Q9      */ 
   L_acc = L_sub( L_acc, L_preg ); 
   acc_h = extract_h( L_shl( L_acc,2 ) );              /* L_acc_h:Q[-5] */ 
   L_tmp_x = L_mult( acc_h, INV_COEF );                /* L_tmp_x:Q15   */ 
 
 /*--------------------------------------------------------------------------* 
   y = (coef[1][0]*(-coef[0][1]+best_gain[0]*coef[0][0])*gcode0 
                                      -coef[0][0]*best_gain[1]) * inv_coef; 
  *--------------------------------------------------------------------------*/ 
   L_acc = L_shr( L_coef[0][1], 10 );                  /* L_acc:Q20   */ 
   L_acc = L_sub( L_cfbg, L_acc );                     /* !!x -> L_cfbg:Q20 */ 
   acc_h = extract_h( L_acc );                         /* acc_h:Q4    */ 
   acc_h = mult( acc_h, gcode0 );                      /* acc_h:Q[-7] */ 
   L_tmp = L_mult( acc_h, coef[1][0] );                /* L_tmp:Q10   */ 
 
   L_preg = L_mult( coef[0][0], best_gain[1] );        /* L_preg:Q13  */ 
   L_acc = L_sub( L_tmp, L_shr(L_preg,3) );            /* L_acc:Q10   */ 
 
   acc_h = extract_h( L_shl( L_acc,2 ) );              /* acc_h:Q[-4] */ 
   L_tmp_y = L_mult( acc_h, INV_COEF );                /* L_tmp_y:Q16 */ 
 
   sft_y = (14+4+1)-16;         /* (Q[thr1]+Q[gcode0]+1)-Q[L_tmp_y] */ 
   sft_x = (15+4+1)-15;         /* (Q[thr2]+Q[gcode0]+1)-Q[L_tmp_x] */ 
 
   if(gcode0>0){ 
      /*-- pre select codebook #1 --*/ 
      *cand1 = 0 ; 
      do{ 
         L_temp = L_sub( L_tmp_y, L_shr(L_mult(thr1[*cand1],gcode0),sft_y)); 
         if(L_temp >0L  ){ 
        (*cand1) =myadd(*cand1,1); 
     } 
         else               break ; 
      } while(sub((*cand1),(NCODE1-NCAN1))<0) ; 
      /*-- pre select codebook #2 --*/ 
      *cand2 = 0 ; 
      do{ 
        L_temp = L_sub( L_tmp_x , L_shr(L_mult(thr2[*cand2],gcode0),sft_x)); 
         if( L_temp >0L) { 
        (*cand2) =myadd(*cand2,1); 
     } 
         else               break ; 
      } while(sub((*cand2),(NCODE2-NCAN2))<0) ; 
   } 
   else{ 
      /*-- pre select codebook #1 --*/ 
      *cand1 = 0 ; 
      do{ 
        L_temp = L_sub(L_tmp_y ,L_shr(L_mult(thr1[*cand1],gcode0),sft_y)); 
         if( L_temp <0L){ 
        (*cand1) =myadd(*cand1,1); 
     } 
         else               break ; 
      } while(sub((*cand1),(NCODE1-NCAN1))) ; 
      /*-- pre select codebook #2 --*/ 
      *cand2 = 0 ; 
      do{ 
         L_temp =L_sub(L_tmp_x ,L_shr(L_mult(thr2[*cand2],gcode0),sft_x)); 
         if( L_temp <0L){ 
        (*cand2) =myadd(*cand2,1); 
     } 
         else               break ; 
      } while(sub( (*cand2),(NCODE2-NCAN2))) ; 
   } 
 
   return ; 
}