www.pudn.com > SMV_Code.rar > decoder.c


/*=========================================================================*/ 
/* Each of the companies; Ericsson, Lucent, Mindspeed, Motorola, Nokia,    */ 
/* Nortel Networks, and Qualcomm (hereinafter referred to individually as  */ 
/* “Source” or collectively as “Sources”) do hereby state:                 */ 
/*                                                                         */ 
/* To the extent to which the Source(s) may legally and freely do so,      */ 
/* the Source(s), upon submission of a Contribution, grant(s) a free,      */ 
/* irrevocable, non-exclusive, license to the Third Generation Partnership */ 
/* Project 2 (3GPP2) and its Organizational Partners: ARIB, CCSA, TIA,     */ 
/* TTA, and TTC, under the Source’s copyright or copyright license rights  */ 
/* in the Contribution, to, in whole or in part, copy, make derivative     */ 
/* works, perform, display and distribute the Contribution and derivative  */ 
/* works thereof consistent with 3GPP2’s and each Organizational Partner’s */ 
/* policies and procedures, with the right to (i) sublicense the foregoing */ 
/* rights consistent with 3GPP2’s and each Organizational Partner’s        */ 
/* policies and procedures and (ii) copyright and sell, if applicable) in  */ 
/* 3GPP2's name or each Organizational Partner’s name any 3GPP2 or         */ 
/* transposed Publication even though this Publication may contain the     */ 
/* Contribution or a derivative work thereof.  The Contribution shall      */ 
/* disclose any known limitations on the Source’s rights to license as     */ 
/* herein provided.                                                        */ 
/*                                                                         */ 
/* When a Contribution is submitted by the Source(s) to assist the         */ 
/* formulating groups of 3GPP2 or any of its Organizational Partners,      */ 
/* it is proposed to the Committee as a basis for discussion and is not    */ 
/* to be construed as a binding proposal on the Source(s).  The Source(s)  */ 
/* specifically reserve(s) the right to amend or modify the material       */ 
/* contained in the Contribution. Nothing contained in the Contribution    */ 
/* shall, except as herein expressly provided, be construed as conferring  */ 
/* by implication, estoppel or otherwise, any license or right under       */ 
/* (i) any existing or later issuing patent, whether or not the use of     */ 
/* information in the document necessarily employs an invention of any     */ 
/* existing or later issued patent, (ii) any copyright, (iii) any          */ 
/* trademark, or (iv) any other intellectual property right.               */ 
/*                                                                         */ 
/* With respect to the Software necessary for the practice of any or all   */ 
/* Normative portions of the Selectable Mode Vocoder (SMV) as it exists on */ 
/* the date of submittal of this form, should the SMV be approved as a     */ 
/* Specification or Report by 3GPP2, or as a transposed Standard by any of */ 
/* the 3GPP2’s Organizational Partners, the Source(s) state(s) that a      */ 
/* worldwide license to reproduce, use and distribute the Software, the    */ 
/* license rights to which are held by the Source(s), will be made         */ 
/* available to applicants under terms and conditions that are reasonable  */ 
/* and non-discriminatory, which may include monetary compensation,        */ 
/* and only to the extent necessary for the practice of any or all of the  */ 
/* Normative portions of the SMV or the field of use of practice of the    */ 
/* SMV Specification, Report, or Standard.  The statement contained above  */ 
/* is irrevocable and shall be binding upon the Source(s).  In the event   */ 
/* the rights of the Source(s) in and to copyright or copyright license    */ 
/* rights subject to such commitment are assigned or transferred,          */ 
/* the Source(s) shall notify the assignee or transferee of the existence  */ 
/* of such commitments.                                                    */ 
/*=========================================================================*/ 
/*                                                                   */ 
/*-------------------------------------------------------------------*/ 
/*===================================================================*/ 
/* FILE: decoder.c                                                   */ 
/*-------------------------------------------------------------------*/ 
/* PURPOSE : Speech Coding @ Selectable Bitrate (SMV)                */ 
/*===================================================================*/ 
 
/*----------------------------------------------------------------------------*/ 
/*-------------------------------- INCLUDE -----------------------------------*/ 
/*----------------------------------------------------------------------------*/ 
 
 
#include  "typedef.h" 
#include  "main.h" 
#include  "const.h" 
#include  "mcutil.h" 
#include  "gputil.h" 
 
#include  "ext_var.h" 
 
#include  "lib_ini.h" 
 
#include  "lib_lpc.h" 
#include  "lib_qlsf.h" 
#include  "lib_geq.h" 
#include  "lib_bit.h" 
#include  "lib_cla.h" 
#include  "lib_pit.h" 
#include  "lib_ltp.h" 
#include  "lib_ppr.h" 
#include  "lib_fcs.h" 
#include  "lib_gcb.h" 
#include  "lib_flt.h" 
#include  "lib_snr.h" 
#include  "nelp.h" 
 
#ifdef DATA 
#include  "tty.h" 
#include  "dtmf.h" 
#include  "tables.h" 
#endif 
 
#ifdef WMOPS 
 
#include  "lib_wmp.h" 
 
#endif 
 
 
/*----------------------------------------------------------------------------*/ 
/*--------------------------------- FUNCTIONS --------------------------------*/ 
/*----------------------------------------------------------------------------*/ 
 
/*===================================================================*/ 
/* FUNCTION  : dec_smv_frame ().                                     */ 
/*-------------------------------------------------------------------*/ 
/* PURPOSE   : Performs processing on one frame.                     */ 
/*-------------------------------------------------------------------*/ 
/* ALGORITHM :                                                       */ 
/*-------------------------------------------------------------------*/ 
/* INPUT ARGUMENTS  :                                                */ 
/*               _ (INT16  [])  serial:   intput frame bitstream.    */ 
/*-------------------------------------------------------------------*/ 
/* OUTPUT ARGUMENTS :                                                */ 
/*               _ (FLOAT64 []) sigout:   output decoded frame.      */ 
/*-------------------------------------------------------------------*/ 
/* INPUT/OUTPUT ARGUMENTS :                                          */ 
/*                      _ None.                                      */ 
/*-------------------------------------------------------------------*/ 
/* RETURN ARGUMENTS :                                                */ 
/*                      _ None.                                      */ 
/*===================================================================*/ 
 
void dec_smv_frame (INT16 PackedWords [], FLOAT64 *sigout, INT16 switch_flag) 
	{ 
	 /*-------------------------------------------------------------------*/ 
 
	 INT16 i_sf,i_s, l_sf, i,j, n_sf; 
         INT16 seed_dec_2k=0; 
 
	 /*-------------------------------------------------------------------*/ 
	 /*                Parameters for bitstream processing                */ 
	 /*-------------------------------------------------------------------*/ 
 
	 INT16 parm[3]; 
	 INT16 shft_count; 
 
	 INT16 PackWdsPtr[2]; 
	 PARAMETER channel; 
 
	 /*-------------------------------------------------------------------*/ 
	 /*                           Gain MA-VQ                              */ 
	 /*-------------------------------------------------------------------*/ 
 
	 FLOAT64 gainQ[N_SF_MAX]; 
         FLOAT64 *Ptr_gp_tab; 
 
	 /*-------------------------------------------------------------------*/ 
	 /*                          LSF quantisation                         */ 
	 /*-------------------------------------------------------------------*/ 
 
	 INT16 exp_flg; 
	 FLOAT64  lsfq_new_dec[NP], lpcgain_q; 
	 FLOAT64 **pdcfq_dec; 
 
	 /*-------------------------------------------------------------------*/ 
	 /*                      Parameters for excitation                    */ 
	 /*-------------------------------------------------------------------*/ 
 
	 FLOAT64 **qua_fcod, **unfcod_dec; 
 
	 /*-------------------------------------------------------------------*/ 
	 /*                      Parameters for synthesis                     */ 
	 /*-------------------------------------------------------------------*/ 
 
	 FLOAT64 *sigsyn_dec; 
 
	 /*-------------------------------------------------------------------*/ 
	 /*                       Bad Frame Concealement                      */ 
	 /*-------------------------------------------------------------------*/ 
 
	 INT16 bfi; 
	 INT16 update; 
	  
	 FLOAT64 enrg; 
	 FLOAT64 fec_refl[NP]; 
	 FLOAT64 temp_lagf; 
	 FLOAT64 ET_buf[N_SF_MAX]; 
	  
	 /*-------------------------------------------------------------------*/ 
 
	 FLOAT64 ForPitch_dec[L_FRM]; 
	 FLOAT64 ForPitch_decTEMP[L_FRM]; 
 
 
         static FLOAT64 prev_lpcg=0.0; 
         FLOAT64 SNR_dec; 
         FLOAT64 sub_refl[NP]; 
 
 
         FLOAT64 fec_e_lsf[NP]; 
#ifdef DATA 
	 /*-------------------------------------------------------------------*/ 
	 /*                        DATA,TTY DTMF                              */ 
	 /*-------------------------------------------------------------------*/ 
 
         INT16 sigout_16[L_FRM]; 
         INT16 dtmf_digit; 
         INT16 tty_type; 
         INT16 chk_data;    /*=0 speech, 1 data, 2 speech+data */ 
	 static Word16 chk_data_last=0; 
         Word16 SVS; 
         static Word16 dtmf_digit_last=-1; 
         static Word16 header_last=-1; 
#endif 
 
	 /*-------------------------------------------------------------------*/ 
	 /*                        Bad Rate Detection                         */ 
	 /*-------------------------------------------------------------------*/ 
 
	 FLOAT64 x=0.0, y=0.0, z=0.0; 
	 INT16 SavePackedWords[PACKWDSNUM]; 
	 UNS_INT16 unst_1; 
 
/*============================================================================*/ 
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */ 
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤                 ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */ 
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤        DECODER       ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */ 
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤                 ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */ 
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */ 
/*============================================================================*/ 
 
	 /*-------------------------------------------------------------------*/ 
	 /*                     Allocate temporary memory                     */ 
	 /*-------------------------------------------------------------------*/ 
 
	 pdcfq_dec = dmatrix (0, N_SF_MAX, 0, NP-1); 
	 MaxIdx_dec = svector (0, MAXPN-1); 
	 qua_fcod   = dmatrix (0, 1, 0, L_FRM-1); 
	 unfcod_dec = dmatrix (0, 1, 0, L_SF-1); 
	 wsp_m_dec = dvector (0, L_WSP-1); 
	 pred_energy_d38  = dvector (0, GVQ_VEC_SIZE_3D-1); 
	 pred_energy_d410 = dvector (0, GVQ_VEC_SIZE_4D-1); 
	 gain_code_vector = dvector (0, GVQ_VEC_SIZE_4D-1); 
	 sigsyn_dec = dvector (0, L_SF+NP-1); 
 
	 /*------------------------------------------------------------------*/ 
	 /*                        Pointers set-up                           */ 
	 /*------------------------------------------------------------------*/ 
 
	 INI_pointer_setup_dec  (); 
 
/*============================================================================*/ 
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ BFI MANAGEMENT ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */ 
/*============================================================================*/ 
 
#ifdef WMOPS 
 
	 WMP_cnt_move (3); 
	 WMP_cnt_test (6); 
	 WMP_cnt_add  (1); 
#endif 
 
	 bfi = 0; 
	 update = 0; 
 
	 /*-------------------------------------------------------------------*/ 
	 /*              Initalizing bit un-packing parameters                */ 
	 /*-------------------------------------------------------------------*/ 
   
	 PackWdsPtr[0] = 16; 
	 PackWdsPtr[1] = 1; 
 
	 switch (PackedWords[0]) 
	   { 
	    case 0:  
	      /* Blank frame rate. To be erased */ 
	      bfi = 1; 
	      break; 
 
	    case 1: channel.fix_rate = RATE0_8K;  
	      break; 
 
	    case 2: channel.fix_rate = RATE2_0K;  
	      break; 
 
	    case 3: channel.fix_rate = RATE4_0K; 
	      break; 
			 
	    case 4: channel.fix_rate = RATE8_5K; 
	      break; 
 
	    case 14: bfi = 1; 
	      break; 
 
	    case 15: 
	      /* Full-rate likely frame rate. To be erased*/ 
	      bfi = 1; 
	      break; 
 
	    default: 
	      /* Invalid frame rate. To be erased */ 
	      bfi = 1; 
	      break; 
	   } 
          
	 if (bfi == 0)  
	   { 
#ifdef DATA 
	     ini_svector(data_buf,0,DATA_SIZE+5-1,0); 
	     chk_data=0; 
	     if ((channel.fix_rate==RATE8_5K)||(channel.fix_rate==RATE4_0K)) 
	       { 
		 /*-----------------------------------------------------------*/ 
		 /*              Check for possible data bits                 */ 
		 /*-----------------------------------------------------------*/ 
 
		 cpy_svector(PackedWords,SavePackedWords,0,PACKWDSNUM-1); 
		 BIT_bits_to_data (PackedWords, PackWdsPtr,data_buf,&channel. 
				   fix_rate,&chk_data); 
		 cpy_svector(SavePackedWords,PackedWords,0,PACKWDSNUM-1); 
	       } 
 
	     PackWdsPtr[0] = 16; 
	     PackWdsPtr[1] = 1; 
 
	     /*---------------------------------------------------------------*/ 
	     /*           Get speech  bits if speech or speech+data           */ 
	     /*---------------------------------------------------------------*/ 
 
	     if  ((chk_data==2 )||(chk_data==0)) 
	       { 
		 /*-----------------------------------------------------------*/ 
		 /*                  If speech+data read SVS bit              */ 
		 /*-----------------------------------------------------------*/ 
		  
                 if (chk_data==2) 
		   BIT_bitunpack (&SVS, (UNS_INT16 *) PackedWords, 1,  
				  PackWdsPtr); 
 
		 /*----------------------------------------------------------*/ 
		 /* Use the remaining packet redundancy in the half-rate     */ 
		 /* type 0 2-pulse FCB for bad rate check                    */ 
		 /*----------------------------------------------------------*/ 
		  
		 if (channel.fix_rate==RATE4_0K)  
		   { 
		     /* Back up first */ 
		     cpy_svector(PackedWords,SavePackedWords,0,PACKWDSNUM-1); 
		     i = PackWdsPtr[0] ; 
		     j = PackWdsPtr[1] ; 
		      
		     /* Get the type bit first */ 
		     BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,  
				    1, PackWdsPtr); 
		     if (unst_1 == 0)  
		       {		      
			 BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,  
					16, PackWdsPtr); 
			 BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords, 
					16, PackWdsPtr); 
			 BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,  
					16, PackWdsPtr); 
			 BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,  
					1, PackWdsPtr); 
			  
			 /* Getting BIT 51 - BIT 65 if chk_data !=2 */ 
			 /* Getting BIT 52 - BIT 66 if chk_data ==2 */ 
			 BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,  
					15, PackWdsPtr); 
			 if ( (unst_1>=0x7FC8 && unst_1 <=0x7FFF)|| 
			      (unst_1>=0x5FC8 && unst_1 <=0x5FFF)  )  
			   bfi=1; 
 
			 /* Getting BIT 66 - BIT 80 if chk_data !=2 */ 
			 /* Getting BIT 67 - BIT 81 if chk_data ==2 */ 
			 /* Reminder:0x7FC8 is reserved for data transmission */ 
			 BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,  
					15, PackWdsPtr); 
			 if (unst_1 != 0x7FC8)  
			   { 
			     if ( (unst_1>=0x7FC9 && unst_1 <=0x7FFF)|| 
				  (unst_1>=0x5FC8 && unst_1 <=0x5FFF)  ) 
			       bfi=1; 
			   } 
		       } 
		     cpy_svector(SavePackedWords,PackedWords,0,PACKWDSNUM-1); 
		     PackWdsPtr[0] = i ; 
		     PackWdsPtr[1] = j ; 
		   }		  
 
		 bfi = BIT_bits_to_cdbk_index (PackedWords, PackWdsPtr,  
					       &channel); 
	       } 
#else 
	      
	     /*---------------------------------------------------------------*/ 
	     /* Use the remaining packet redundancy in the half-rate type 0   */ 
	     /* 2-pulse FCB for bad rate check                                */ 
	     /*---------------------------------------------------------------*/ 
	      
	     if (channel.fix_rate==RATE4_0K)  
	       { 
		 /* Back up first */ 
		 cpy_svector(PackedWords,SavePackedWords,0,PACKWDSNUM-1); 
		 i = PackWdsPtr[0] ; 
		 j = PackWdsPtr[1] ; 
		  
		 /* Get the type bit first */ 
		 BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords, 1,  
				PackWdsPtr); 
		 if (unst_1 == 0)  
		   {		      
		     BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,  
				    16, PackWdsPtr); 
		     BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,  
				    16, PackWdsPtr); 
		     BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,  
				    16, PackWdsPtr); 
		     BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,  
				    1, PackWdsPtr); 
		      
		     /* Getting BIT 51 - BIT 65 */ 
		     BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,  
				    15, PackWdsPtr); 
		     if ( (unst_1>=0x7FC8 && unst_1 <=0x7FFF)|| 
			  (unst_1>=0x5FC8 && unst_1 <=0x5FFF)  )  
		       bfi=1; 
 
		     /* Getting BIT 66 - BIT 80 */ 
		     /* Reminder: 0x7FC8 is reserved for data transmission */ 
		     BIT_bitunpack (&unst_1, (UNS_INT16 *) PackedWords,  
				    15, PackWdsPtr); 
		     if (unst_1 != 0x7FC8)  
		       { 
			 if ( (unst_1>=0x7FC9 && unst_1 <=0x7FFF)|| 
			      (unst_1>=0x5FC8 && unst_1 <=0x5FFF)  ) 			 
			   bfi=1; 
		       } 
		   } 
		 cpy_svector(SavePackedWords,PackedWords,0,PACKWDSNUM-1); 
		 PackWdsPtr[0] = i ; 
		 PackWdsPtr[1] = j ; 
	       }		  
 
	     /*---------------------------------------------------------------*/ 
	     /*            Decode bit-stream  if is a good frame              */ 
	     /*---------------------------------------------------------------*/ 
 
	     bfi = BIT_bits_to_cdbk_index (PackedWords, PackWdsPtr, &channel); 
 
#endif 
 
#ifdef DATA 
             /*---------------------------------------------------------------*/ 
             /*   do following checks for non data only cases */ 
             /*---------------------------------------------------------------*/ 
         if ((chk_data !=1) &&(dtmf_digit_last == -1)) 
             { 
  
#endif 
 
	      
	     /*---------------------------------------------------------------*/ 
	     /*          Check badrate flag in full-rate and 1/4-rate         */ 
	     /*---------------------------------------------------------------*/ 
 
	     if (channel.badrate_flag==1) 
	       bfi=1; 
 
	     /*---------------------------------------------------------------*/ 
	     /*             Filter type 3 in 1/4-rate NELP is illegal         */ 
	     /*---------------------------------------------------------------*/ 
 
	     if (channel.fix_rate==RATE2_0K && channel.idx_gainVQ[3]==3) 
	       bfi=1; 
 
	     /*---------------------------------------------------------------*/ 
	     /* Bad-rate detection schemes using illegal rate/type transitions*/ 
	     /*---------------------------------------------------------------*/ 
 
	     if (past_bfi==0)  
	       { 
		 /*-----------------------------------------------------------*/ 
		 /*            Type-1 frame to 1/8th rate is illegal          */ 
		 /*-----------------------------------------------------------*/ 
 
		 if (SVS_deci_mem==1 && channel.fix_rate==RATE0_8K)  
		     bfi=1;  
		  
		 /*-----------------------------------------------------------*/ 
		 /*             Type-1 frame to 1/4th rate is illegal         */ 
		 /*-----------------------------------------------------------*/ 
 
		 if (SVS_deci_mem==1 && channel.fix_rate==RATE2_0K) 
		   bfi=1;  
		  
		 /*-----------------------------------------------------------*/ 
		 /*                    Big lag change is illegal              */ 
		 /*-----------------------------------------------------------*/ 
 
		 if (SVS_deci_mem==1 && channel.idx_SVS_deci==1)  
		   { 
		     if (channel.fix_rate == RATE8_5K)  
		       { 
			 x = PitLagTab8b[channel.idx_pitch[0]]; 
			 if (fabs(x-pitchf_dec)>15)  
			   { 
			     /*-----------------------------------------------*/ 
			     /*       Note:pitchf_dec is the previous lag     */ 
			     /*-----------------------------------------------*/ 
			     bfi=1; 
			   } 
		       } 
		     else if (channel.fix_rate==RATE4_0K)  
		       { 
			 x = PitLagTab7b[channel.idx_pitch[0]]; 
			 if (fabs(x-pitchf_dec)>15 && x>40.0)  
			   { 
			     /*-----------------------------------------------*/ 
			     /*       Note:pitchf_dec is the previous lag     */ 
			     /*-----------------------------------------------*/ 
			     bfi=1; 
			   } 
		       } 
		   } 
		 if (ppast_bfi==0)  
		   { 
		     /*------------------------------------------------------*/ 
		     /*     Eighth/quarter-rate to Type-1 frame is illegal   */ 
		     /*------------------------------------------------------*/ 
 
		     if (channel.idx_SVS_deci==1 &&  
			 (fix_rate_dec_mem==RATE0_8K ||  
			  fix_rate_dec_mem==RATE2_0K))  
		       { 
			 if (fix_rate_dec_mem2  <= RATE2_0K)  
			   { 
			     bfi=1; 
			   } 
			 else  
			   { 
			     ini_dvector(ext_dec, 0, MAX_LAG+L_SF-1, 0.0); 
			     ini_dvector(ext_dec_fec, 0, MAX_LAG+L_SF-1, 0.0); 
			     ini_dvector(PF_mem_syn, 0, NP-1, 0.0); 
			     ini_dvector(synth_mem_dec, 0, NP-1, 0.0); 
			     past_energyq_2d[0]=past_energyq_2d[1]; 
			     past_energyq_4d[0]=past_energyq_4d[1]; 
			     past_fixed_energy = 0.0; 
			     for (i = 0; i < NP; i++)  
			       lsfq_old_dec[i] = lsf_ini [i]; 
			   } 
		       } 
		   } 
	       } 
#ifdef DATA 
             } 
#endif 
	   } 
 
	 if (bfi == 0) 
	   { 
#ifdef DATA 
             /*---------------------------------------------------------------*/ 
             /*   do following checks for non data cases and bfi=0 */ 
             /*---------------------------------------------------------------*/ 
            if ((chk_data !=1) &&(dtmf_digit_last == -1)) 
              { 
           
#endif 
 
	  
	      
#ifdef WMOPS 
	     WMP_cnt_move  (7); 
	     WMP_cnt_test  (3); 
	     WMP_cnt_sub   (2); 
	     WMP_cnt_logic (1); 
	     WMP_cnt_shift (1); 
#endif 
	     if (channel.fix_rate == RATE2_0K ) 
	       { 
		 parm[0] = channel.idx_lsf[0]; 
		 parm[1] = channel.idx_lsf[1]; 
		 parm[2] = channel.idx_lsf[2]; 
		 seed_dec_2k = 0x0000; 
		 shft_count = 14; 
		 for (j = 0; j < 3; j++) 
		   { 
		     shft_count -= bitno0_2k[j]; 
		     seed_dec_2k = seed_dec_2k ^ 
		       (((INT64) parm[j] ) << shft_count); 
		   } 
	       } 
	      
	     if (channel.fix_rate == RATE0_8K) 
	       { 
		 parm[0] = channel.idx_lsf[0]; 
		 parm[1] = channel.idx_lsf[1]; 
		 parm[2] = channel.idx_lsf[2]; 
		  
		 shft_count = 11; 
		 for (j = 0; j < 3; j++) 
		   { 
		     shft_count -= bitno1[j]; 
		     seed_dec = seed_dec ^(((long) parm[j] ) << shft_count); 
		   } 
 
		 /*-------------------------------------------------------*/ 
		 /*     Decode the 1/8 rate gain first to see whether     */ 
		 /*                it is a bad packet                     */ 
		 /*-------------------------------------------------------*/ 
		  
		 GCB_gauss_excit_dec (&seed_dec, L_FRM, qua_unfcod[1]); 
		  
		 if ((fix_rate_dec_mem == RATE4_0K) || 
		     (fix_rate_dec_mem == RATE2_0K)) 
		   { 
		     if (SVS_deci_mem == 0) 
		       GEQ_update_mem_2d_to_4d(); 
		     else 
		       GEQ_update_mem_3d_to_4d(); 
		   } 
		  
		 /*-------------------------------------------------------*/ 
		 /*     Decode  the fixed codebook gain for sub-frame     */ 
		 /*                 # 1  coded with 5 bits                */ 
		 /*-------------------------------------------------------*/ 
		  
		 if (GEQ_dec_gains_1_5 (channel.idx_gainVQ[0], qua_gainQ, 
				   qua_unfcod[1], 0)==1) 
		   { 
		     bfi=1; 
		   } 
		 for (i = 0; i < N_SF4; i++) qua_gainQ[1][i] = qua_gainQ[1][0]; 
	       } 
#ifdef DATA 
	   } 
#endif 
        } 
 
	  
	 if (bfi == 1) 
	   { 
	     N_bfi++; 
	     bfh_oh = BFH_OH+1; 
	     nbfi_count = 0; 
	     frm_erasure++; 
	     channel.fix_rate = fix_rate_dec_mem; 
	     channel.idx_SVS_deci = SVS_deci_mem; 
#ifdef DATA 
             /*------------------------------------------------------------*/ 
             /* Use last chk_data (0=speech,1=data,2=data+speech and header */ 
             /*------------------------------------------------------------*/ 
             chk_data=chk_data_last; 
             data_buf[0]=header_last; 
             for (i=1; i 0) {N_bfi = 0; bfh_oh--;} 
	     if (nbfi_count < 5) nbfi_count++; 
	   } 
	  
	 if (nbfi_count > 3) bfi_caution = 0; 
	  
         if (channel.fix_rate != RATE0_8K && fix_rate_dec_mem == RATE0_8K &&  
              SNR_dec_mem > 50.0 && past_bfi == 1) 
		 ini_dvector(past_energyq_4d, 0, GVQ_VEC_SIZE_4D-1, -30.0); 
 
	 /*-------------------------------------------------------------------*/ 
	 /*                   Reset the seed for 0.8 Kbs                      */ 
	 /*-------------------------------------------------------------------*/ 
 
         if (channel.fix_rate != RATE0_8K ) 
	   seed_dec = (INT16)0x0E76; 
 
/*============================================================================*/ 
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ LSF INVERSE QUANTIZATION AND INTERPOLATION ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/ 
/*============================================================================*/ 
   
	 /*-------------------------------------------------------------------*/ 
	 /*                       Get the quantized lsf                       */ 
	 /*-------------------------------------------------------------------*/ 
 
#ifdef DATA 
	 /*-------------------------------------------------------------------*/ 
	 /*                  If only data, skip decoding code                 */ 
	 /*-------------------------------------------------------------------*/ 
	  
	 if ((chk_data !=1) &&(dtmf_digit_last==-1)) 
	   { 
#endif 
 
	 LSF_Q_lsf_decode (bfi_caution, &exp_flg, lsfq_new_dec, 
			   channel.idx_lsf, bfi, nbfi_count, channel.fix_rate); 
 
	 /*-------------------------------------------------------------------*/ 
	 /*      Interpolate the QUANTIZED lsf and calculate corresponding    */ 
	 /*                        the LPC coefficients                       */ 
	 /*-------------------------------------------------------------------*/ 
 
#ifdef WMOPS 
 
	 WMP_cnt_test (5); 
#endif 
 
	 if (channel.fix_rate == RATE4_0K)  
	   {  
	     LPC_interpolation (lsfq_new_dec, (FLOAT64 *)NULL, lsfq_old_dec,  
				pdcfq_dec, 1, channel.idx_SVS_deci); 
	   } 
	 else 
	   {  
	     if (channel.fix_rate==RATE8_5K && channel.idx_SVS_deci==0) 
	       { 
		 if (bfi == 0) 
		   { 
		     LPC_adptive_interp_dec (lsfq_new_dec, lsfq_old_dec, 
					     pdcfq_dec,  
					     channel.idx_lpc_int); 
		   }	 	 
		 else 
		   LPC_adptive_interp_dec (lsfq_new_dec, lsfq_old_dec,  
					   pdcfq_dec, 0); 
	       } 
	     else  
	       LPC_adptive_interp_dec (lsfq_new_dec, lsfq_old_dec,  
				       pdcfq_dec, 0); 
	   } 
	  
   
         if (channel.fix_rate != RATE4_0K) 
	   LPC_pred2refl (pdcfq_dec[3], fec_refl, NP); 
         else 
	   { 
	     if (channel.idx_SVS_deci == 1) 
	       LPC_pred2refl (pdcfq_dec[2], fec_refl, NP); 
	     else 
	       LPC_pred2refl (pdcfq_dec[1], fec_refl, NP); 
	   } 
 
	 /*-------------------------------------------------------------------*/ 
	 /*          Determination of the flatness of the input speech        */ 
	 /*-------------------------------------------------------------------*/ 
                            
	 CLA_Identify_Input (channel.idx_SVS_deci, pdcfq_dec[0],  
			     lsfq_new_dec[0], pgain_past_dec, &lpcgain_q, 
			     channel.fix_rate, &FlatSp_Flag_dec, 
			     &SVS_Count_dec, &Vad_0_Count_dec, &Av_value_dec); 
                              
	 /*-------------------------------------------------------------------*/ 
	 /*                      Interpolation of Pitch Lag                   */ 
	 /*-------------------------------------------------------------------*/ 
 
#ifdef WMOPS 
 
	 WMP_cnt_test (1); 
#endif 
 
	 if (channel.idx_SVS_deci == 1) 
	   {		 
	     PIT_pitch_track_recons (fix_rate_dec_mem, bfi, past_bfi, ppast_bfi, 
				     lag_f, SVS_deci_mem, qua_gainQ, channel, 
				     &pitchf_dec, pitch_f_mem, ForPitch_decTEMP); 
	      
	     PIT_PitchInterpolat (pitchf_dec, pitch_f_mem,  ForPitch_dec, 0); 
	      
	   } 
 
#ifdef WMOPS 
	 WMP_cnt_test (3); 
#endif 
 
	 if (bfi == 0) 
	   { 
	     if (channel.idx_SVS_deci == 0) 
		 {  
		   if (channel.fix_rate == RATE8_5K) 
		     temp_lagf = PitLagTab8b[channel.idx_pitch[0]]; 
		   else if (channel.fix_rate == RATE4_0K) 
		     temp_lagf = PitLagTab7b[channel.idx_pitch[0]]; 
		 } 
	   } 
 
	 LTP_adap_cbk_correction (fix_rate_dec_mem, bfi, past_bfi, ppast_bfi, 
				  qua_gainQ, gainQ, SVS_deci_mem, temp_lagf, 
				  &update, pitchf_dec, pitch_f_mem, lag, lag_f, 
				  ForPitch_decTEMP, ext_dec_fec, ext_dec, 
				  unfcod_dec, qua_unfcod, channel); 
 
         /*-------------------------------------------------------------------*/ 
         /*              Gaussian excitation for very low bit rates           */ 
	 /*-------------------------------------------------------------------*/ 
 
#ifdef  WMOPS 
	WMP_cnt_test (3); 
#endif 
	if ((channel.fix_rate == RATE2_0K) || (channel.fix_rate == RATE0_8K)) 
	  { 
	    cpy_dvector(gp_buf+4,gp_buf, 0, 4-1); 
	    ini_dvector(gp_buf+4, 0, 4-1, 0.0); 
	    if (channel.fix_rate == RATE2_0K) 
	      { 
#ifdef  WMOPS 
		WMP_cnt_test (4); 
#endif 
		if( (fix_rate_dec_mem == RATE8_5K || fix_rate_dec_mem ==RATE0_8K) ) 
		  GEQ_update_mem_4d_to_2d();           
		else if( fix_rate_dec_mem == RATE4_0K && SVS_deci_mem != 0 ) 
		  GEQ_update_mem_3d_to_2d();  
#ifdef  WMOPS 
		WMP_fwc (""); 
#endif 
		 
		nelp_decoder(seed_dec_2k, fix_rate_dec_mem, qua_unfcod[1], 
			     qua_gainQ[1], channel.idx_gainVQ, N_bfi); 
 
#ifdef  WMOPS 
		WMP_fwc ("nelp_decoder"); 
#endif 
 
	      } 
	    else if (bfi != 0) 
	      { /* only in FER frames */ 
#ifdef  WMOPS 
		WMP_cnt_move (N_SF4); 
#endif 
		 
		GCB_gauss_excit_dec (&seed_dec, L_FRM, qua_unfcod[1]); 
		 
		/*-------------------------------------------------------*/ 
		/*     Decode  the fixed codebook gain for sub-frame     */ 
		/*                 # 1  coded with 6 bits                */ 
		/*-------------------------------------------------------*/ 
 
		GEQ_dec_gains_1_5 (channel.idx_gainVQ[0], qua_gainQ, 
				   qua_unfcod[1], N_bfi); 
		 
		for (i = 0; i < N_SF4; i++) 
		  qua_gainQ[1][i] = qua_gainQ[1][0]; 
	      } 
	  } 
 
/*============================================================================*/ 
/* ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ SUB-FRAME PROCESSING ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ */ 
/*============================================================================*/ 
 
/*----------------------------------------------------------------------------*/ 
/*-----------------------------VARIABLE DESCRIPTION --------------------------*/ 
/*----------------------------------------------------------------------------*/ 
/*	                                                                      */ 
/*	pdcfq_dec      -  quantized prediction coefficients                   */ 
/*	unfcod_dec[0]  -  adaptive codebook (ACB) vector                      */ 
/*	unfcod_dec[1]  -  algebraic codebook (CDBK) vector                    */ 
/*	gainQ[0]       -  ACB gain                                            */ 
/*	gainQ[1]       -  CDBK gain                                           */ 
/*	                                                                      */ 
/*	ext_dec        -  adaptive codebook                                   */ 
/*	lag[i_sf]      -  integral lag of the current subframe                */ 
/*	lagf[i_sf]     -  fractional lag of the current subframe              */ 
/*	                                                                      */ 
/*----------------------------------------------------------------------------*/ 
 
 
	 /*-------------------------------------------------------------------*/ 
	 /*                      Set number of subframes                      */ 
	 /*-------------------------------------------------------------------*/ 
         
#ifdef  WMOPS 
	WMP_cnt_test (2); 
	WMP_cnt_move (1); 
#endif 
	 if (channel.fix_rate != RATE4_0K) 
	 	n_sf=N_SF4; 
	 else 
	 	{ 
		 if (channel.idx_SVS_deci == 1) 
		 	n_sf = N_SF3; 
		 else 
		 	n_sf = N_SF2; 
		} 
 
/*----------------------------------------------------------------------------*/ 
/*¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤ Decoding loop on the sub-frames ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤*/ 
/*----------------------------------------------------------------------------*/ 
		 
	 /*-------------------------------------------------------------------*/ 
	 /*              Restoring the memory for the synthesis               */ 
	 /*-------------------------------------------------------------------*/ 
 
	 cpy_dvector(sigsyn_dec_mem, sigsyn_dec, 0, NP-1); 
 
	 i_s = 0; 
	 for (i_sf = 0; i_sf < n_sf; i_sf++) 
	 	{ 
		 /*===========================================================*/ 
		  
		 /*-----------------------------------------------------------*/ 
		 /*                   Set length of subframe                  */ 
		 /*-----------------------------------------------------------*/ 
 
#ifdef  WMOPS 
		 WMP_cnt_test (3); 
		 WMP_cnt_move (1); 
#endif 
		 if (channel.fix_rate != RATE4_0K) 
		 	l_sf = L_SF4;  
		 else 
		 	{    
			 if (channel.idx_SVS_deci == 1) 
			 	{     
				 if (i_sf == N_SF3-1) 
				 	l_sf = L_SF3; 
				 else 
				 	l_sf = L_SF0; 
				} 
			 else 
			 	l_sf = L_SF; 
			} 
   
		 /*-----------------------------------------------------------*/ 
		 /*                Adaptive Codebook Contribution             */ 
		 /*-----------------------------------------------------------*/ 
 
#ifdef  WMOPS 
		 WMP_cnt_test (3); 
		 WMP_cnt_move (4); 
#endif 
		 if ((channel.fix_rate == RATE8_5K) || 
		     (channel.fix_rate == RATE4_0K)) 
		   { 
		     if (channel.idx_SVS_deci == 1) 
		       {   
			 LTP_PP_pitch_ext_decod (ForPitch_dec+i_s, ext_dec, 
						 i_sf, unfcod_dec[0], lag,  
						 lag_f, l_sf); 
			  
 
			 cpy_dvector (unfcod_dec[0], qua_unfcod[0]+i_s, 0, 
				      l_sf-1); 
 
		       } 
		     else 
		       { 
			 if (channel.fix_rate == RATE8_5K)  
			   LTP_8_5k_pitch_decod (fec_refl[0],bfi, ext_dec, i_sf, 
						 unfcod_dec[0], lag, lag_f, l_sf, 
						 channel.idx_pitch); 
			 else  
			   LTP_7b_pitch_decod (fec_refl[0], bfi, ext_dec, i_sf, 
					       unfcod_dec[0], lag, lag_f, l_sf, 
					       channel.idx_pitch); 
 
			 cpy_dvector(unfcod_dec[0], qua_unfcod[0]+i_s, 
				     0, l_sf-1); 
		       } 
		   } 
		 else 
		   { 
		     gainQ[0] = 0.0; 
		     qua_gainQ[0][i_sf] = 0.0; 
		      
		     ini_dvector(unfcod_dec[0], 0, l_sf-1, 0.0); 
		     ini_dvector(qua_unfcod[0]+i_s, 0, l_sf-1, 0.0); 
		   } 
		  
		 /*-----------------------------------------------------------*/ 
		 /*                  Fixed Codebook Contribution              */ 
		 /*-----------------------------------------------------------*/ 
 
#ifdef  WMOPS 
		 WMP_cnt_test (3); 
		 WMP_cnt_move (1); 
#endif 
		 switch (channel.fix_rate) 
		   { 
		     /*-------------------------------------------------------*/ 
		     /*                      RATE 8.5 kps                     */ 
		     /*-------------------------------------------------------*/ 
 
		    case RATE8_5K: 
		       
		      if (channel.idx_SVS_deci == 1) 
			{ 
			  Ptr_gp_tab = gp4_tab; 
			  GEQ_Dec_PitchGain (N_bfi, i_sf,  channel.idx_Gp_VQ,  
					     gainQ,Ptr_gp_tab, GVQ_VEC_SIZE_4D); 
			   
			  if (bfi == 0) 
			    FCS_cdbk_decod_8500BPS (unfcod_dec[1], 
						    l_sf, i_sf, lag[i_sf], 
						    gainQ[0], &channel, 1); 
 
			} 
		      else 
			{ 
			  if (bfi == 0)  
 
			    FCS_cdbk_decod_8500BPS (unfcod_dec[1], 
						    l_sf, i_sf, lag[i_sf],  
						    pgain_past_dec, 
						    &channel, 0); 
		} 
		       
		      break; 
 
		      /*-------------------------------------------------------*/ 
		      /*                      RATE 4.0 kps                     */ 
		      /*-------------------------------------------------------*/ 
 
		    case RATE4_0K:    
		       
		      if (channel.idx_SVS_deci == 1) 
			{ 
			  Ptr_gp_tab = gp3_tab; 
			  GEQ_Dec_PitchGain (N_bfi, i_sf, channel.idx_Gp_VQ,  
					     gainQ, Ptr_gp_tab,  GVQ_VEC_SIZE_3D); 
			   
			  if (bfi == 0) 
			    FCS_cdbk_decod_4000BPS (ext_dec, 
						    pdcfq_dec[i_sf], 
						    unfcod_dec[1], l_sf, 
						    i_sf, lag[i_sf], gainQ[0], 
						    fix_rate_dec_mem, lpcgain_q, 
						    &channel, 1); 
 
			} 
		      else 
			{ 
			  if (bfi == 0)  
			    FCS_cdbk_decod_4000BPS (ext_dec, 
						    pdcfq_dec[i_sf],  
						    unfcod_dec[1], l_sf, 
						    i_sf, lag[i_sf],  
						    pgain_past_dec, 
						    fix_rate_dec_mem, lpcgain_q, 
						    &channel, 0); 
			} 
			   
		      break; 
			   
		      /*-------------------------------------------------------*/ 
		      /*                      RATE 2.0 kps                     */ 
		      /*-------------------------------------------------------*/ 
			   
		    case RATE2_0K: 
		      cpy_dvector (qua_unfcod[1]+i_s, unfcod_dec[1], 0, 
				   l_sf-1); 
		      gainQ[1]=qua_gainQ[1][i_sf]=1.0; 
		      break; 
			   
		      /*------------------------------------------------------*/ 
		      /*                     RATE 0.8 kps                     */ 
		      /*------------------------------------------------------*/ 
 
		    case RATE0_8K:	 
		      break; 
 
		    default: nrerror ("Invalid rate !!"); 
		      break; 
		   } 
 
		 /*-----------------------------------------------------------*/ 
#ifdef  WMOPS 
		 WMP_cnt_test (3); 
 
#endif 
		 if ((bfi == 1) && ((channel.fix_rate == RATE8_5K) || 
				    (channel.fix_rate == RATE4_0K))) 
		   { 
		     GCB_gauss_excit_dec (&seed_bfi_exc, l_sf, unfcod_dec[1]); 
		   } 
 
		 /*-----------------------------------------------------------*/ 
		 /*             Adaptive and Fixed Codebook Gains             */ 
		 /*-----------------------------------------------------------*/ 
#ifdef  WMOPS 
		 WMP_cnt_test (12); 
		 WMP_cnt_move (4); 
#endif 
		 if ((channel.fix_rate == RATE8_5K) || 
		     (channel.fix_rate == RATE4_0K)) 
		   { 
		     /*------------------------------------------------------*/ 
		     /*              RATE 8.5 kbps and 4.0 kbps              */ 
		     /*------------------------------------------------------*/ 
 
		     cpy_dvector (unfcod_dec[1], qua_unfcod[1]+i_s, 0, l_sf-1); 
	 
		     if (channel.idx_SVS_deci == 0) 
		       {  
			 if (i_sf==0 && type0count<32767)  
			   type0count++; 
			 if (channel.fix_rate == RATE8_5K) 
			   { 
			     if (fix_rate_dec_mem==RATE0_8K && ppast_bfi==0 && i_sf==0)  
			       { 
				 past_energyq_4d[1] = past_energyq_4d[0]; 
				 past_energyq_4d[2] = past_energyq_4d[0]; 
				 past_energyq_4d[3] = past_energyq_4d[0]; 
			       } 
			     if (((fix_rate_dec_mem == RATE4_0K) ||  
				  (fix_rate_dec_mem == RATE2_0K)) && 
				 (i_sf == 0)) 
			       { 
				 if (SVS_deci_mem == 0) 
				   GEQ_update_mem_2d_to_4d(); 
				 else 
				   GEQ_update_mem_3d_to_4d(); 
			       } 
				GEQ_dec_gains_2_7(channel.fix_rate,lag[0],  
						  enrg_buff[2], onset_flg_dec,  
						  fec_refl[0], 
						  channel.idx_gainVQ[i_sf], 
						  gainQ, N_bfi, unfcod_dec[1], 
						  i_sf, l_sf); 
 
				if (type0count<50)  
				  { 
				    LPC_pred2refl (pdcfq_dec[i_sf], sub_refl, NP); 
				    for(i=0,x=1.0;i21000.0 ) 
				      { 
					type0count=50; 
					gainQ[1]=0.0; 
					past_energyq_4d[0] = -20.0;  
				      } 
				  } 
			   } 
			 else 
			   { 
			     if (fix_rate_dec_mem==RATE0_8K && ppast_bfi==0 && i_sf==0)  
			       { 
				 past_energyq_4d[1] = past_energyq_4d[0]; 
				 past_energyq_4d[2] = past_energyq_4d[0]; 
				 past_energyq_4d[3] = past_energyq_4d[0]; 
			       } 
			     if (((fix_rate_dec_mem == RATE8_5K) || 
				  (fix_rate_dec_mem ==RATE0_8K)) && 
				 (i_sf == 0)) 
			       { 
				 GEQ_update_mem_4d_to_2d(); 
			       } 
			     else 
			       { 
				 if ((fix_rate_dec_mem == RATE4_0K) && 
				     (SVS_deci_mem != 0) && 
				     (i_sf == 0)) 
				   { 
				     GEQ_update_mem_3d_to_2d(); 
				   } 
			       } 
			     GEQ_dec_gains_2_7(channel.fix_rate,lag[0], 
					       enrg_buff[2], onset_flg_dec, 
					       fec_refl[0], 
					       channel.idx_gainVQ[i_sf], 
					       gainQ, N_bfi, unfcod_dec[1], 
					       i_sf, l_sf); 
 
			     if (type0count<50)  
			       { 
				 LPC_pred2refl (pdcfq_dec[i_sf], sub_refl, NP); 
				 for(i=0,x=1.0;i18000.0 )  
				   { 
				     type0count=50; 
				     gainQ[1]=0.0; 
				     past_energyq_2d[0] = -20.0; 
				   } 
			       } 
			   } 
		       } 
		     else 
		       { 
			 if (channel.fix_rate == RATE8_5K) 
			   { 
			     if (((fix_rate_dec_mem == RATE4_0K) ||  
				  (fix_rate_dec_mem == RATE2_0K))&& (i_sf == 0)) 
			       { 
				 if (SVS_deci_mem == 0) 
				   GEQ_update_mem_2d_to_4d(); 
				 else 
				   GEQ_update_mem_3d_to_4d(); 
			       } 
 
			     GEQ_dec_gc_4_10 (channel.idx_Gc_VQ, &(gainQ[1]), 
					      N_bfi, unfcod_dec, i_sf); 
			   } 
			 else 
			   { 
			     if (((fix_rate_dec_mem == RATE8_5K) || 
				  (fix_rate_dec_mem == RATE0_8K)) && (i_sf == 0)) 
			       GEQ_update_mem_4d_to_3d(); 
			     else if (SVS_deci_mem == 0) 
			       GEQ_update_mem_2d_to_3d(); 
 
			     GEQ_dec_gc_3_8(channel.idx_Gc_VQ, &(gainQ[1]), 
					    N_bfi,unfcod_dec, i_sf);      
			   } 
		       } 
		     qua_gainQ[1][i_sf] = gainQ[1]; 
		      
		     qua_gainQ[0][i_sf] = gainQ[0]; 
		     pgain_past_dec = gainQ[0];  
		     if (pgain_past_dec < PAST_PGAIN_MIN) 
		       pgain_past_dec = PAST_PGAIN_MIN; 
		      
		     if (pgain_past_dec > PAST_PGAIN_MAX) 
		       pgain_past_dec = PAST_PGAIN_MAX; 
		   } 
		 else 
		   { 
		     /*---------------------------------------------------*/ 
		     /*               RATE 2.0 kbps and 0.8 kbps          */ 
		     /*---------------------------------------------------*/ 
		      
		     gainQ[0] = 0.0; 
		     pgain_past_dec = 0.0; 
		     qua_gainQ[0][i_sf]=0.0; 
		     gainQ[1]=qua_gainQ[1][i_sf]; 
		     if (channel.fix_rate== RATE2_0K) 
		       gainQ[1]=qua_gainQ[1][i_sf]=1.0; 
		   }		 
		   
		 /*-------------------------------------------------------*/ 
		 /*                   Build the excitation                */ 
		 /*-------------------------------------------------------*/ 
 
#ifdef  WMOPS 
		 WMP_cnt_test (1); 
#endif 
		 if (exp_flg == 1) 
		   wad_dvector(qua_unfcod[0]+i_s, gainQ[0], 
			       qua_unfcod[1]+i_s, 0.7*gainQ[1],  
			       ext_dec+MAX_LAG, 0, l_sf-1);	 
		 else 
		   wad_dvector(qua_unfcod[0]+i_s, gainQ[0], 
			       qua_unfcod[1]+i_s, gainQ[1],  
			       ext_dec+MAX_LAG, 0, l_sf-1);	 
 
 
 
		 if (N_bfi <= 2) 
		   { 
		     GEQ_energy_extrapolation (i_s, i_sf, l_sf, gainQ,  
					       qua_unfcod, bfi, lag_f, ext_dec, 
					       Prev_Beta_Pitch, ET_buf, 
					       ForPitch_dec, channel); 
		   } 
 
	 	 /*-----------------------------------------------------------*/ 
		 /*                       Synthesis filter                    */ 
	 	 /*-----------------------------------------------------------*/ 
 
		 FLT_filterAP (pdcfq_dec[i_sf], ext_dec+MAX_LAG, sigsyn_dec+NP, 
			        synth_mem_dec, NP, l_sf); 
 
		 if (channel.idx_SVS_deci == 1 && bfi ==0)  
		   { 
		     if (i_sf==0)  
		       y=0.0; 
		     dot_dvector (sigsyn_dec+NP, sigsyn_dec+NP, 
				  &z, 0, l_sf-1); 
		     y += z; 
		     if (i_sf==n_sf-1)  
		       { 
			 type1en[arrayindex]=(INT16)(10.0*log10(y)+0.5); 
			 arrayindex = (++arrayindex)%LEN_TYPE1EN; 
			 maxenergy = type1en[0]; 
			 for (i=1;imaxenergy)  
			     maxenergy = (FLOAT64) type1en[i]; 
		       } 
		     type0count=0; 
		 }		  
 
	 	 /*-----------------------------------------------------------*/ 
		 /*                       Post processing                     */ 
	 	 /*-----------------------------------------------------------*/ 
 
                 PPR_post_process (sigsyn_dec, pdcfq_dec[i_sf], lag_f[i_sf],  
				   l_sf, FlatSp_Flag_dec, channel.fix_rate, 
				   bfi, N_bfi);	 
 
	 	 /*-----------------------------------------------------------*/ 
		 /*              Update the synthesized speech buffer         */ 
	 	 /*-----------------------------------------------------------*/ 
 
		 cpy_dvector(sigsyn_dec+NP, sigout+i_s, 0, l_sf-1); 
 
		 /*-----------------------------------------------------------*/ 
		 /*                Update the adaptive codebook               */ 
		 /*-----------------------------------------------------------*/ 
 
		 cpy_dvector(ext_dec+l_sf, ext_dec, 0, MAX_LAG-1); 
 
		 i_s += l_sf; 
		  
		 /*===========================================================*/ 
		} 
	  
#ifdef  WMOPS 
		 WMP_cnt_test (17); 
		 WMP_cnt_move (4); 
#endif 
 
		 if ((channel.fix_rate == RATE4_0K) &&  
		     (channel.idx_SVS_deci == 1)) 
		   { 
		     cpy_dvector(gp_buf+4, gp_buf, 0, 4-1); 
		     gp_buf[4] = qua_gainQ[0][0]; 
		     gp_buf[5] = gp_buf[6] = qua_gainQ[0][1]; 
		     gp_buf[7] = qua_gainQ[0][2]; 
		   } 
		 else 
		   { 
		     if ((channel.fix_rate == RATE4_0K) && 
			 (channel.idx_SVS_deci!=1)) 
		       { 
			 cpy_dvector(gp_buf+4,gp_buf, 0, 4-1); 
			  
			 if ((ET_buf[0] < 40.0) && (qua_gainQ[0][0] > 0.7)) 
			   gp_buf[4] = gp_buf[5] = 0.4; 
			 else 
			   gp_buf[4] = gp_buf[5] = qua_gainQ[0][0]; 
			  
			 if ((ET_buf[1] < 40.0) && (qua_gainQ[0][1] > 0.7)) 
			   gp_buf[6] = gp_buf[7] = 0.4; 
			 else 
			   gp_buf[6] = gp_buf[7] = qua_gainQ[0][1]; 
		       } 
		     else 
		       { 
			 if (channel.fix_rate == RATE8_5K) 
			   { 
			     cpy_dvector(gp_buf+4, gp_buf, 0, 4-1); 
			     for (i = 0; i < 4; i++) 
			       { 
				 if ((ET_buf[i] < 40.0) && (qua_gainQ[0][i] > 0.7) 
				     && (channel.idx_SVS_deci != 1)) 
				   gp_buf[i+4] = 0.4; 
				 else 
				   gp_buf[i+4] = qua_gainQ[0][i]; 
			       } 
			   } 
		       } 
		   } 
 
	 /*-------------------------------------------------------------------*/ 
	 /*                     Estimation of LPC gain for FEC                */ 
	 /*-------------------------------------------------------------------*/ 
 
#ifdef  WMOPS 
	 WMP_cnt_mac    (NP); 
	 WMP_cnt_mult   (NP+1); 
	 WMP_cnt_transc (1); 
#endif 
        
	 LPC_pred2refl (pdcfq_dec[n_sf-1], sub_refl, NP); 
	 sub_lpcg = 1.0; 
	 for (i = 0; i < NP; i++) 
	   sub_lpcg *= (1.0-sqr(sub_refl[i])); 
	 sub_lpcg = -10.0*log10(sub_lpcg+EPSI); 
	  
#ifdef  WMOPS 
	 WMP_cnt_move   (1); 
	 WMP_cnt_mult   (1); 
	 WMP_cnt_transc (1); 
 
	 WMP_cnt_test   (4); 
	 WMP_cnt_sub    (3); 
	 WMP_cnt_move   (2); 
 
#endif 
 
         SNR_Calc_SNR_dec(channel.fix_rate, sigout, &SNR_dec, &enrg); 
 
	 enrg_buff[0] = enrg_buff[1]; 
	 enrg_buff[1] = enrg_buff[2]; 
	 enrg_buff[2] = 10.0*log10(enrg/L_FRM+EPSI); 
 
 
         if( ((enrg_buff[2] - enrg_buff[1] > 13.0) ||  
	      (enrg_buff[2] - enrg_buff[0] > 13.0) 
	      || (sub_lpcg-prev_lpcg > 7.0)) && enrg_buff[2]> 45.0) 
	   onset_flg_dec = 1; 
         else 
	   onset_flg_dec = 0; 
	  
         prev_lpcg = sub_lpcg; 
 
#ifdef  WMOPS 
	 WMP_cnt_test (7); 
	 WMP_cnt_move (5); 
#endif 
 
         if( (fec_refl[0] > 0.4 || (channel.fix_rate == RATE0_8K && 
				    SNR_dec > 50.0)) && bfi == 1) 
	   { 
 
	     LSF_Q_lsf_predict(&B_40k[LQMA_40k*NP], qes_dec, LQMA_40k, 
			       fec_e_lsf); 
	     dif_dvector(Mean_removed_flat_lsf, fec_e_lsf, qes_dec[0],  
			 0, NP-1); 
 
	     bfi_caution = 1;	      
	   } 
 
	 ppast_bfi = past_bfi; 
	 past_bfi = bfi;  
 
	 /*-------------------------------------------------------------------*/ 
	 /*                 Update the memories for next frame                */ 
	 /*-------------------------------------------------------------------*/ 
         
	 SVS_deci_mem = channel.idx_SVS_deci; 
	 fix_rate_dec_mem2 = fix_rate_dec_mem; 
	 fix_rate_dec_mem = channel.fix_rate;      
	 SNR_dec_mem = SNR_dec; 
 
#ifdef DATA   
      } 
   else 
     { 
       INI_reset_decoder (); 
       ini_dvector(sigout, 0, L_FRM-1, 0.0); 
     } 
	 /*-------------------------------------------------------------------*/ 
	 /*                       Generate DTMF, TTY tones                    */ 
	 /*-------------------------------------------------------------------*/ 
	  
	 /*-------------------------------------------------------------------*/ 
	 /*                    Zero out speech if only data or               */ 
         /*                     first frame after dtmf                        */ 
	 /*-------------------------------------------------------------------*/ 
	 if (chk_data == 0) 
           data_buf[0] = -1; 
         if (chk_data == 1 )  
	   ini_dvector(sigout, 0, L_FRM-1, 0.0); 
         for (i = 0; i < L_FRM; i++) 
	   sigout_16[i] = (INT16) sigout[i]; 
 
         if (chk_data >= 1) 
	   { 
	     if (data_buf[0] == TTY_HEADER)  
	       { 
		 tty_dec_header = data_buf[1]&0x00ff; 
		 tty_type = data_buf[1]>>8; 
		 tty_dec_char = data_buf[2]; 
		  
		 tty_dec_baud_rate = data_buf[3]; 
		 tty_dec_flag = tty_dec (sigout_16, 0, tty_dec_header, 
					 tty_dec_char, tty_dec_baud_rate,  
					 bfi, 
					 0,   /* Subframe index */ 
					 1,   /* Num of subframes */ 
					 L_FRM);  
                if (tty_dec_flag !=0) 
		 for (i = 0; i < L_FRM; i++) 
		   sigout[i] = (FLOAT64)sigout_16[i]; 
	       } 
 
	     /*---------------------------------------------------------------*/ 
	     /*   If 00)&&(N_bfi<3)&&(dtmf_digit_last>0))  
	       { 
		 data_buf[0] = DTMF_HEADER; 
		 data_buf[1] = dtmf_digit_last; 
	       } 
	     /*---------------------------------------------------------------*/ 
	     /*    If more than 2 bad frames, stop generating dtmf tones      */ 
	     /*---------------------------------------------------------------*/ 
 
	     if  ((data_buf[0] == DTMF_HEADER)&&(N_bfi<3)) 
	       { 
		 /*-----------------------------------------------------------*/ 
		 /*                       Get dtmf_digit                      */ 
		 /*-----------------------------------------------------------*/ 
 
		 dtmf_digit = (INT16)data_buf[1]; 
		 if (dtmf_digit > 0)  
		   { 
	 	     /*-------------------------------------------------------*/ 
                     /*                  Generate dtmf tones                  */ 
                     /*-------------------------------------------------------*/ 
                      dtmf_tone_gen(dtmf_digit,dtmf_digit_last,L_FRM,sigout); 
		   }  
		 else  
		   { 
		     /*-------------------------------------------------------*/ 
		     /*              Silence frame after dtmf tone            */ 
		     /*-------------------------------------------------------*/ 
 
		     ini_dvector(sigout, 0, L_FRM-1, 0.0); 
		   } 
		 dtmf_digit_last = dtmf_digit; 
	       } 
	     else 
	       { 
		 dtmf_digit_last = -1; 
	       } 
	   }  
	 else  
	   { 
	     dtmf_digit_last = -1; 
	     tty_dec_flag = tty_dec( sigout_16, 1, tty_dec_header, 
				     tty_dec_char, tty_dec_baud_rate, bfi, 
				     0,              /* Subframe index */ 
				     1,              /* Num of subframes */ 
				     L_FRM); 
 
	     if (tty_dec_flag !=0) 
	       for (i=0; i