if (gain_sum > tmp) { float fact = tmp/gain_sum; for (i=0;i<3;i++) gain[i]*=fact;  }
if (gain_sum > tmp) { spx_word16_t fact = DIV32_16(SHL32(EXTEND32(tmp),14),gain_sum); for (i=0;i<3;i++) gain[i]=MULT16_16_Q14(fact,gain[i]); }
void pitch_unquant_3tap(spx_sig_t exc[],                    /* Excitation */int   start,                    /* Smallest pitch value allowed */int   end,                      /* Largest pitch value allowed */spx_word16_t pitch_coef,               /* Voicing (pitch) coefficient */const void *par,int   nsf,                      /* Number of samples in subframe */int *pitch_val,spx_word16_t *gain_val,SpeexBits *bits,char *stack,int count_lost,int subframe_offset,spx_word16_t last_pitch_gain,int cdbk_offset){   int i;   int pitch;   int gain_index;   spx_word16_t gain[3];   const signed char *gain_cdbk;   int gain_cdbk_size;   const ltp_params *params;   params = (const ltp_params*) par;   gain_cdbk_size = 1<<params->gain_bits;   gain_cdbk = params->gain_cdbk + 3*gain_cdbk_size*cdbk_offset;   pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits);   pitch += start;   gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits);   /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/#ifdef FIXED_POINT   gain[0] = 32+(spx_word16_t)gain_cdbk[gain_index*3];   gain[1] = 32+(spx_word16_t)gain_cdbk[gain_index*3+1];   gain[2] = 32+(spx_word16_t)gain_cdbk[gain_index*3+2];#else   gain[0] = 0.015625*gain_cdbk[gain_index*3]+.5;   gain[1] = 0.015625*gain_cdbk[gain_index*3+1]+.5;   gain[2] = 0.015625*gain_cdbk[gain_index*3+2]+.5;#endif   if (count_lost && pitch > subframe_offset)   {      float gain_sum;      if (1) {	 float tmp = count_lost < 4 ? GAIN_SCALING_1*last_pitch_gain : 0.4 * GAIN_SCALING_1 * last_pitch_gain;         if (tmp>.95)            tmp=.95;         gain_sum = GAIN_SCALING_1*gain_3tap_to_1tap(gain);	 if (gain_sum > tmp) {	    float fact = tmp/gain_sum;	    for (i=0;i<3;i++)	       gain[i]*=fact;	 }      }   }   *pitch_val = pitch;   gain_val[0]=gain[0];   gain_val[1]=gain[1];   gain_val[2]=gain[2];   {      spx_sig_t *e[3];      VARDECL(spx_sig_t *tmp2);      ALLOC(tmp2, 3*nsf, spx_sig_t);      e[0]=tmp2;      e[1]=tmp2+nsf;      e[2]=tmp2+2*nsf;            for (i=0;i<3;i++)      {         int j;         int pp=pitch+1-i;#if 0         for (j=0;j<nsf;j++)         {            if (j-pp<0)               e[i][j]=exc[j-pp];            else if (j-pp-pitch<0)               e[i][j]=exc[j-pp-pitch];            else               e[i][j]=0;         }#else         {            int tmp1, tmp3;            tmp1=nsf;            if (tmp1>pp)               tmp1=pp;            for (j=0;j<tmp1;j++)               e[i][j]=exc[j-pp];            tmp3=nsf;            if (tmp3>pp+pitch)               tmp3=pp+pitch;            for (j=tmp1;j<tmp3;j++)               e[i][j]=exc[j-pp-pitch];            for (j=tmp3;j<nsf;j++)               e[i][j]=0;         }#endif      }#ifdef FIXED_POINT      {         for (i=0;i<nsf;i++)            exc[i]=SHL32(ADD32(ADD32(MULT16_32_Q15(SHL16(gain[0],7),e[2][i]), MULT16_32_Q15(SHL16(gain[1],7),e[1][i])),                               MULT16_32_Q15(SHL16(gain[2],7),e[0][i])), 2);      }#else      for (i=0;i<nsf;i++)         exc[i]=VERY_SMALL+gain[0]*e[2][i]+gain[1]*e[1][i]+gain[2]*e[0][i];#endif   }}