Example #1
0
void acf_averaging (
    Word16 r_h[],
    Word16 r_l[],
    Word16 scal_acf,
    Word32 L_av0[],
    Word32 L_av1[]
)
{
    Word32 L_temp;
    Word16 scale;
    Word16 i;

    scale = add (9, scal_acf);

    for (i = 0; i <= 8; i++)
    {
		if(scale<0)
			L_temp = L_shl (L_Comp (r_h[i], r_l[i]), -scale);
		else
			L_temp = L_shr (L_Comp (r_h[i], r_l[i]), scale);
        L_av0[i] = L_add (L_sacf[i], L_temp);            
        L_av0[i] = L_add (L_sacf[i + 9], L_av0[i]);      
        L_av0[i] = L_add (L_sacf[i + 18], L_av0[i]);     
        L_sacf[pt_sacf + i] = L_temp;                    
        L_av1[i] = L_sav0[pt_sav0 + i];                  
        L_sav0[pt_sav0 + i] = L_av0[i];                  
    }

    /* Update the array pointers */
    
    if (sub (pt_sacf, 18) == 0)
    {
        pt_sacf = 0;                                     
    }
    else
    {
        pt_sacf = add (pt_sacf, 9);
    }

     
    if (sub (pt_sav0, 27) == 0)
    {
        pt_sav0 = 0;                                     
    }
    else
    {
        pt_sav0 = add (pt_sav0, 9);
    }
    return;
}
Example #2
0
/*---------------------------------------------------------------------------*
 * Function  Gain_update                                                     *
 * ~~~~~~~~~~~~~~~~~~~~~~                                                    *
 * update table of past quantized energies                                   *
 *---------------------------------------------------------------------------*/
void Gain_update(
   Word16 past_qua_en[],   /* (io) Q10 :Past quantized energies           */
   Word32  L_gbk12         /* (i) Q13 : gbk1[indice1][1]+gbk2[indice2][1] */
)
{
   Word16  i, tmp;
   Word16  exp, frac;
   Word32  L_acc;

   for(i=3; i>0; i--){
      past_qua_en[i] = past_qua_en[i-1];         /* Q10 */
   }
  /*----------------------------------------------------------------------*
   * -- past_qua_en[0] = 20*log10(gbk1[index1][1]+gbk2[index2][1]); --    *
   *    2 * 10 log10( gbk1[index1][1]+gbk2[index2][1] )                   *
   *  = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] )                *
   *  = 2 * 3.0103 log2( gbk1[index1][1]+gbk2[index2][1] )                *
   *                                                 24660:Q12(6.0205)    *
   *----------------------------------------------------------------------*/

   Log2( L_gbk12, &exp, &frac );               /* L_gbk12:Q13       */
   L_acc = L_Comp( sub(exp,13), frac);         /* L_acc:Q16           */
   tmp = extract_h( L_shl( L_acc,13 ) );       /* tmp:Q13           */
   past_qua_en[0] = mult( tmp, 24660 );        /* past_qua_en[]:Q10 */
}
Example #3
0
/*-----------------------------------------------------------------*
 * Functions vad                                                   *
 *           ~~~                                                   *
 * Input:                                                          *
 *   rc            : reflection coefficient                        *
 *   lsf[]         : unquantized lsf vector                        *
 *   r_h[]         : upper 16-bits of the autocorrelation vector   *
 *   r_l[]         : lower 16-bits of the autocorrelation vector   *
 *   exp_R0        : exponent of the autocorrelation vector        *
 *   sigpp[]       : preprocessed input signal                     *
 *   frm_count     : frame counter                                 *
 *   prev_marker   : VAD decision of the last frame                *
 *   pprev_marker  : VAD decision of the frame before last frame   *
 *                                                                 *
 * Output:                                                         *
 *                                                                 *
 *   marker        : VAD decision of the current frame             * 
 *                                                                 *
 *-----------------------------------------------------------------*/
void vadg(
         Word16 rc,
         Word16 *lsf, 
         Word16 *r_h,
         Word16 *r_l, 
         Word16 exp_R0,
         Word16 *sigpp,
         Word16 frm_count,
         Word16 prev_marker,
         Word16 pprev_marker,
         Word16 *marker,
         Word16 *ENERGY_db)
{
 /* scalar */
  Word32 acc0;
  Word16 i, j, exp, frac;
  Word16 ENERGY, ENERGY_low, SD, ZC, dSE, dSLE, dSZC;
  Word16 COEF, C_COEF, COEFZC, C_COEFZC, COEFSD, C_COEFSD;

  /* compute the frame energy */
  acc0 = L_Comp(r_h[0], r_l[0]);
  Log2(acc0, &exp, &frac);
  acc0 = Mpy_32_16(exp, frac, 9864);
  i = sub(exp_R0, 1);  
  i = sub(i, 1);
  acc0 = L_mac(acc0, 9864, i);
  acc0 = L_shl(acc0, 11);
  ENERGY = extract_h(acc0);
  ENERGY = sub(ENERGY, 4875);
  *ENERGY_db = ENERGY;

  /* compute the low band energy */
  acc0 = 0;
  for (i=1; i<=NP; i++)
    acc0 = L_mac(acc0, r_h[i], lbf_corr[i]);
  acc0 = L_shl(acc0, 1);
  acc0 = L_mac(acc0, r_h[0], lbf_corr[0]);
  Log2(acc0, &exp, &frac);
  acc0 = Mpy_32_16(exp, frac, 9864);
  i = sub(exp_R0, 1);  
  i = sub(i, 1);
  acc0 = L_mac(acc0, 9864, i);
  acc0 = L_shl(acc0, 11);
  ENERGY_low = extract_h(acc0);
  ENERGY_low = sub(ENERGY_low, 4875);
  
  /* compute SD */
  acc0 = 0;
  for (i=0; i<M; i++){
    j = sub(lsf[i], MeanLSF[i]);
    acc0 = L_mac(acc0, j, j);
  }
  SD = extract_h(acc0);      /* Q15 */
  
  /* compute # zero crossing */
  ZC = 0;
  for (i=ZC_START+1; i<=ZC_END; i++)
    if (mult(sigpp[i-1], sigpp[i]) < 0){
      ZC = add(ZC, 410);     /* Q15 */
    }

  /* Initialize and update Mins */
  if(sub(frm_count, 129) < 0){
    if (sub(ENERGY, Min) < 0){
      Min = ENERGY;
      Prev_Min = ENERGY;
    }
    
    if((frm_count & 0x0007) == 0){
      i = sub(shr(frm_count,3),1);
      Min_buffer[i] = Min;
      Min = MAX_16;
    }
  }

  if((frm_count & 0x0007) == 0){
    Prev_Min = Min_buffer[0];
    for (i=1; i<16; i++){
      if (sub(Min_buffer[i], Prev_Min) < 0){
        Prev_Min = Min_buffer[i];
      }
    }
  }
  
  if(sub(frm_count, 129) >= 0){
    if(((frm_count & 0x0007) ^ (0x0001)) == 0){
      Min = Prev_Min;
      Next_Min = MAX_16;
    }

    if (sub(ENERGY, Min) < 0){
      Min = ENERGY;
    }

    if (sub(ENERGY, Next_Min) < 0){
      Next_Min = ENERGY;
    }
    
    if((frm_count & 0x0007) == 0){
      for (i=0; i<15; i++)
        Min_buffer[i] = Min_buffer[i+1]; 
      Min_buffer[15] = Next_Min; 
      Prev_Min = Min_buffer[0];
      for (i=1; i<16; i++) 
        if (sub(Min_buffer[i], Prev_Min) < 0){
          Prev_Min = Min_buffer[i];
        }
    }
    
  }

  if (sub(frm_count, INIT_FRAME) <= 0){
    if(sub(ENERGY, 3072) < 0){
      *marker = NOISE;
      less_count++;
    }
    else{
      *marker = VOICE;
      acc0 = L_deposit_h(MeanE);
      acc0 = L_mac(acc0, ENERGY, 1024);
      MeanE = extract_h(acc0);
      acc0 = L_deposit_h(MeanSZC);
      acc0 = L_mac(acc0, ZC, 1024);
      MeanSZC = extract_h(acc0);
      for (i=0; i<M; i++){
        acc0 = L_deposit_h(MeanLSF[i]);
        acc0 = L_mac(acc0, lsf[i], 1024);
        MeanLSF[i] = extract_h(acc0);
      }
    }
  }

  if (sub(frm_count, INIT_FRAME) >= 0){
    if (sub(frm_count, INIT_FRAME) == 0){
      acc0 = L_mult(MeanE, factor_fx[less_count]);
      acc0 = L_shl(acc0, shift_fx[less_count]);
      MeanE = extract_h(acc0);

      acc0 = L_mult(MeanSZC, factor_fx[less_count]);
      acc0 = L_shl(acc0, shift_fx[less_count]);
      MeanSZC = extract_h(acc0);

      for (i=0; i<M; i++){
        acc0 = L_mult(MeanLSF[i], factor_fx[less_count]);
        acc0 = L_shl(acc0, shift_fx[less_count]);
        MeanLSF[i] = extract_h(acc0);
      }

      MeanSE = sub(MeanE, 2048);   /* Q11 */
      MeanSLE = sub(MeanE, 2458);  /* Q11 */
    }

    dSE = sub(MeanSE, ENERGY);
    dSLE = sub(MeanSLE, ENERGY_low);
    dSZC = sub(MeanSZC, ZC);

    if(sub(ENERGY, 3072) < 0){
      *marker = NOISE;
    }
    else {
      *marker = MakeDec(dSLE, dSE, SD, dSZC);
    }

    v_flag = 0;
    if((prev_marker==VOICE) && (*marker==NOISE) && (add(dSE,410)<0) 
       && (sub(ENERGY, 3072)>0)){
      *marker = VOICE;
      v_flag = 1;
    }

    if(flag == 1){
      if((pprev_marker == VOICE) && 
         (prev_marker == VOICE) && 
         (*marker == NOISE) && 
         (sub(abs_s(sub(prev_energy,ENERGY)), 614) <= 0)){
        count_ext++;
        *marker = VOICE;
        v_flag = 1;
        if(sub(count_ext, 4) <= 0){
          flag=1;
        }
        else{
          count_ext=0;
          flag=0;
        }
      }
    }
    else{
      flag=1;
    }
    
    if(*marker == NOISE){
      count_sil++;
    }

    if((*marker == VOICE) && (sub(count_sil, 10) > 0) && 
       (sub(sub(ENERGY,prev_energy), 614) <= 0)){
      *marker = NOISE;
      count_sil=0;
    }

    if(*marker == VOICE){
      count_sil=0;
    }

    if ((sub(sub(ENERGY, 614), MeanSE)<0) && (sub(frm_count, 128) > 0)
        && (!v_flag) && (sub(rc, 19661) < 0)){
      *marker = NOISE;
    }

    if ((sub(sub(ENERGY,614),MeanSE) < 0) && (sub(rc, 24576) < 0)
        && (sub(SD, 83) < 0)){ 
      count_update++;
      if (sub(count_update, INIT_COUNT) < 0){
        COEF = 24576;
        C_COEF = 8192;
        COEFZC = 26214;
        C_COEFZC = 6554;
        COEFSD = 19661;
        C_COEFSD = 13017;
      } 
      else
        if (sub(count_update, INIT_COUNT+10) < 0){
          COEF = 31130;
          C_COEF = 1638;
          COEFZC = 30147;
          C_COEFZC = 2621;
          COEFSD = 21299;
          C_COEFSD = 11469;
        }
        else
          if (sub(count_update, INIT_COUNT+20) < 0){
            COEF = 31785;
            C_COEF = 983;
            COEFZC = 30802;
            C_COEFZC = 1966;
            COEFSD = 22938;
            C_COEFSD = 9830;
          }
          else
            if (sub(count_update, INIT_COUNT+30) < 0){
              COEF = 32440;
              C_COEF = 328;
              COEFZC = 31457;
              C_COEFZC = 1311;
              COEFSD = 24576;
              C_COEFSD = 8192;
            }
            else
              if (sub(count_update, INIT_COUNT+40) < 0){
                COEF = 32604;
                C_COEF = 164;
                COEFZC = 32440;
                C_COEFZC = 328;
                COEFSD = 24576;
                C_COEFSD = 8192;
              }
              else{
                COEF = 32604;
                C_COEF = 164;
                COEFZC = 32702;
                C_COEFZC = 66;
                COEFSD = 24576;
                C_COEFSD = 8192;
              }
      

      /* compute MeanSE */
      acc0 = L_mult(COEF, MeanSE);
      acc0 = L_mac(acc0, C_COEF, ENERGY);
      MeanSE = extract_h(acc0);

      /* compute MeanSLE */
      acc0 = L_mult(COEF, MeanSLE);
      acc0 = L_mac(acc0, C_COEF, ENERGY_low);
      MeanSLE = extract_h(acc0);

      /* compute MeanSZC */
      acc0 = L_mult(COEFZC, MeanSZC);
      acc0 = L_mac(acc0, C_COEFZC, ZC);
      MeanSZC = extract_h(acc0);
      
      /* compute MeanLSF */
      for (i=0; i<M; i++){
        acc0 = L_mult(COEFSD, MeanLSF[i]);
        acc0 = L_mac(acc0, C_COEFSD, lsf[i]);
        MeanLSF[i] = extract_h(acc0);
      }
    }

    if((sub(frm_count, 128) > 0) && (((sub(MeanSE,Min) < 0) && (sub(SD, 83) < 0)
 ) || (sub(MeanSE,Min) > 2048))){
      MeanSE = Min;
      count_update = 0;
    }
  }

  prev_energy = ENERGY;
}
Example #4
0
/*************************************************************************
 *
 * FUNCTION:  gc_pred()
 *
 * PURPOSE: MA prediction of the innovation energy
 *          (in dB/(20*log10(2))) with mean  removed).
 *
 *************************************************************************/
void
gc_pred(
    gc_predState *st,   /* i/o: State struct                           */
    enum Mode mode,     /* i  : AMR mode                               */
    Word16 *code,       /* i  : innovative codebook vector (L_SUBFR)   */
    /*      MR122: Q12, other modes: Q13           */
    Word16 *exp_gcode0, /* o  : exponent of predicted gain factor, Q0  */
    Word16 *frac_gcode0,/* o  : fraction of predicted gain factor  Q15 */
    Word16 *exp_en,     /* o  : exponent of innovation energy,     Q0  */
    /*      (only calculated for MR795)            */
    Word16 *frac_en     /* o  : fraction of innovation energy,     Q15 */
    /*      (only calculated for MR795)            */
)
{
    Word16 i;
    Word32 ener_code;
    Word16 exp, frac;

    /*-------------------------------------------------------------------*
     *  energy of code:                                                  *
     *  ~~~~~~~~~~~~~~~                                                  *
     *  ener_code = sum(code[i]^2)                                       *
     *-------------------------------------------------------------------*/
    ener_code = L_mac((Word32) 0, code[0], code[0]);
    /* MR122:  Q12*Q12 -> Q25 */
    /* others: Q13*Q13 -> Q27 */
    for (i = 1; i < L_SUBFR; i++)
        ener_code = L_mac(ener_code, code[i], code[i]);

    test ();
    if (sub (mode, MR122) == 0)
    {
        Word32 ener;

        /* ener_code = ener_code / lcode; lcode = 40; 1/40 = 26214 Q20       */
        ener_code = L_mult (round (ener_code), 26214);   /* Q9  * Q20 -> Q30 */

        /*-------------------------------------------------------------------*
         *  energy of code:                                                  *
         *  ~~~~~~~~~~~~~~~                                                  *
         *  ener_code(Q17) = 10 * Log10(energy) / constant                   *
         *                 = 1/2 * Log2(energy)                              *
         *                                           constant = 20*Log10(2)  *
         *-------------------------------------------------------------------*/
        /* ener_code = 1/2 * Log2(ener_code); Note: Log2=log2+30 */
        Log2(ener_code, &exp, &frac);
        ener_code = L_Comp (sub (exp, 30), frac);     /* Q16 for log()    */
        /* ->Q17 for 1/2 log()*/

        /*-------------------------------------------------------------------*
         *  predicted energy:                                                *
         *  ~~~~~~~~~~~~~~~~~                                                *
         *  ener(Q24) = (Emean + sum{pred[i]*past_en[i]})/constant           *
         *            = MEAN_ENER + sum(pred[i]*past_qua_en[i])              *
         *                                           constant = 20*Log10(2)  *
         *-------------------------------------------------------------------*/

        ener = MEAN_ENER_MR122;
        move32 ();                  /* Q24 (Q17) */
        for (i = 0; i < NPRED; i++)
        {
            ener = L_mac (ener, st->past_qua_en_MR122[i], pred_MR122[i]);
            /* Q10 * Q13 -> Q24 */
            /* Q10 * Q6  -> Q17 */
        }

        /*-------------------------------------------------------------------*
         *  predicted codebook gain                                          *
         *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *
         *  gc0     = Pow10( (ener*constant - ener_code*constant) / 20 )     *
         *          = Pow2(ener-ener_code)                                   *
         *          = Pow2(int(d)+frac(d))                                   *
         *                                                                   *
         *  (store exp and frac for pow2())                                  *
         *-------------------------------------------------------------------*/

        ener = L_shr (L_sub (ener, ener_code), 1);                /* Q16 */
        L_Extract(ener, exp_gcode0, frac_gcode0);
    }
    else /* all modes except 12.2 */
    {
        Word32 L_tmp;
        Word16 exp_code, gcode0;

        /*-----------------------------------------------------------------*
         *  Compute: means_ener - 10log10(ener_code/ L_sufr)               *
         *-----------------------------------------------------------------*/

        exp_code = norm_l (ener_code);
        ener_code = L_shl (ener_code, exp_code);

        /* Log2 = log2 + 27 */
        Log2_norm (ener_code, exp_code, &exp, &frac);

        /* fact = 10/log2(10) = 3.01 = 24660 Q13 */
        L_tmp = Mpy_32_16(exp, frac, -24660); /* Q0.Q15 * Q13 -> Q14 */

        /*   L_tmp = means_ener - 10log10(ener_code/L_SUBFR)
         *         = means_ener - 10log10(ener_code) + 10log10(L_SUBFR)
         *         = K - fact * Log2(ener_code)
         *         = K - fact * log2(ener_code) - fact*27
         *
         *   ==> K = means_ener + fact*27 + 10log10(L_SUBFR)
         *
         *   means_ener =       33    =  540672    Q14  (MR475, MR515, MR59)
         *   means_ener =       28.75 =  471040    Q14  (MR67)
         *   means_ener =       30    =  491520    Q14  (MR74)
         *   means_ener =       36    =  589824    Q14  (MR795)
         *   means_ener =       33    =  540672    Q14  (MR102)
         *   10log10(L_SUBFR) = 16.02 =  262481.51 Q14
         *   fact * 27                = 1331640    Q14
         *   -----------------------------------------
         *   (MR475, MR515, MR59)   K = 2134793.51 Q14 ~= 16678 * 64 * 2
         *   (MR67)                 K = 2065161.51 Q14 ~= 32268 * 32 * 2
         *   (MR74)                 K = 2085641.51 Q14 ~= 32588 * 32 * 2
         *   (MR795)                K = 2183945.51 Q14 ~= 17062 * 64 * 2
         *   (MR102)                K = 2134793.51 Q14 ~= 16678 * 64 * 2
         */

        if (test (), sub (mode, MR102) == 0)
        {
            /* mean = 33 dB */
            L_tmp = L_mac(L_tmp, 16678, 64);     /* Q14 */
        }
        else if (test (), sub (mode, MR795) == 0)
        {
            /* ener_code  = <xn xn> * 2^27*2^exp_code
               frac_en    = ener_code / 2^16
                          = <xn xn> * 2^11*2^exp_code
               <xn xn>    = <xn xn>*2^11*2^exp * 2^exp_en
                         := frac_en            * 2^exp_en

               ==> exp_en = -11-exp_code;
             */
            *frac_en = extract_h (ener_code);
            move16 ();
            *exp_en = sub (-11, exp_code);
            move16 ();

            /* mean = 36 dB */
            L_tmp = L_mac(L_tmp, 17062, 64);     /* Q14 */
        }
        else if (test (), sub (mode, MR74) == 0)
        {
            /* mean = 30 dB */
            L_tmp = L_mac(L_tmp, 32588, 32);     /* Q14 */
        }
        else if (test (), sub (mode, MR67) == 0)
        {
            /* mean = 28.75 dB */
            L_tmp = L_mac(L_tmp, 32268, 32);     /* Q14 */
        }
        else /* MR59, MR515, MR475 */
        {
            /* mean = 33 dB */
            L_tmp = L_mac(L_tmp, 16678, 64);     /* Q14 */
        }

        /*-----------------------------------------------------------------*
         * Compute gcode0.                                                 *
         *  = Sum(i=0,3) pred[i]*past_qua_en[i] - ener_code + mean_ener    *
         *-----------------------------------------------------------------*/

        L_tmp = L_shl(L_tmp, 10);                /* Q24 */
        for (i = 0; i < 4; i++)
            L_tmp = L_mac(L_tmp, pred[i], st->past_qua_en[i]);
        /* Q13 * Q10 -> Q24 */

        gcode0 = extract_h(L_tmp);               /* Q8  */

        /*-----------------------------------------------------------------*
         * gcode0 = pow(10.0, gcode0/20)                                   *
         *        = pow(2, 3.3219*gcode0/20)                               *
         *        = pow(2, 0.166*gcode0)                                   *
         *-----------------------------------------------------------------*/

        /* 5439 Q15 = 0.165985                                        */
        /* (correct: 1/(20*log10(2)) 0.166096 = 5443 Q15)             */
        test ();
        if (sub (mode, MR74) == 0) /* For IS641 bitexactness */
            L_tmp = L_mult(gcode0, 5439);  /* Q8 * Q15 -> Q24 */
        else
            L_tmp = L_mult(gcode0, 5443);  /* Q8 * Q15 -> Q24 */

        L_tmp = L_shr(L_tmp, 8);                   /*          -> Q16 */
        L_Extract(L_tmp, exp_gcode0, frac_gcode0); /*       -> Q0.Q15 */
    }
}
/*************************************************************************
 *
 * FUNCTION: calc_unfilt_energies
 *
 * PURPOSE:  calculation of several energy coefficients for unfiltered
 *           excitation signals and the LTP coding gain
 *
 *       frac_en[0]*2^exp_en[0] = <res res>   // LP residual energy
 *       frac_en[1]*2^exp_en[1] = <exc exc>   // LTP residual energy
 *       frac_en[2]*2^exp_en[2] = <exc code>  // LTP/CB innovation dot product
 *       frac_en[3]*2^exp_en[3] = <lres lres> // LTP residual energy
 *                                            // (lres = res - gain_pit*exc)
 *       ltpg = log2(LP_res_en / LTP_res_en)
 *
 *************************************************************************/
void
calc_unfilt_energies(
    Word16 res[],     /* i  : LP residual,                               Q0  */
    Word16 exc[],     /* i  : LTP excitation (unfiltered),               Q0  */
    Word16 code[],    /* i  : CB innovation (unfiltered),                Q13 */
    Word16 gain_pit,  /* i  : pitch gain,                                Q14 */
    Word16 L_subfr,   /* i  : Subframe length                                */

    Word16 frac_en[], /* o  : energy coefficients (4), fraction part,    Q15 */
    Word16 exp_en[],  /* o  : energy coefficients (4), exponent part,    Q0  */
    Word16 *ltpg      /* o  : LTP coding gain (log2()),                  Q13 */
)
{
    Word32 s, L_temp;
    Word16 i, exp, tmp;
    Word16 ltp_res_en, pred_gain;
    Word16 ltpg_exp, ltpg_frac;

    /* Compute residual energy */
    s = L_mac((Word32) 0, res[0], res[0]);
    for (i = 1; i < L_subfr; i++)
        s = L_mac(s, res[i], res[i]);

    /* ResEn := 0 if ResEn < 200.0 (= 400 Q1) */
    test();
    if (L_sub (s, 400L) < 0)
    {
        frac_en[0] = 0;                      move16 ();
        exp_en[0] = -15;                     move16 ();
    }
    else
    {
        exp = norm_l(s);
        frac_en[0] = extract_h(L_shl(s, exp));   move16 ();
        exp_en[0] = sub(15, exp);                move16 ();
    }
    
    /* Compute ltp excitation energy */
    s = L_mac((Word32) 0, exc[0], exc[0]);
    for (i = 1; i < L_subfr; i++)
        s = L_mac(s, exc[i], exc[i]);

    exp = norm_l(s);
    frac_en[1] = extract_h(L_shl(s, exp));   move16 ();
    exp_en[1] = sub(15, exp);                move16 ();

    /* Compute scalar product <exc[],code[]> */
    s = L_mac((Word32) 0, exc[0], code[0]);
    for (i = 1; i < L_subfr; i++)
        s = L_mac(s, exc[i], code[i]);

    exp = norm_l(s);
    frac_en[2] = extract_h(L_shl(s, exp));   move16 ();
    exp_en[2] = sub(16-14, exp);             move16 ();

    /* Compute energy of LTP residual */
    s = 0L;                                  move32 ();
    for (i = 0; i < L_subfr; i++)
    {
        L_temp = L_mult(exc[i], gain_pit);
        L_temp = L_shl(L_temp, 1);
        tmp = sub(res[i], round(L_temp));           /* LTP residual, Q0 */
        s = L_mac (s, tmp, tmp);
    }

    exp = norm_l(s);
    ltp_res_en = extract_h (L_shl (s, exp));
    exp = sub (15, exp);

    frac_en[3] = ltp_res_en;                 move16 ();
    exp_en[3] = exp;                         move16 ();
    
    /* calculate LTP coding gain, i.e. energy reduction LP res -> LTP res */
    test (); test ();
    if (ltp_res_en > 0 && frac_en[0] != 0)
    {
        /* gain = ResEn / LTPResEn */
        pred_gain = div_s (shr (frac_en[0], 1), ltp_res_en);
        exp = sub (exp, exp_en[0]);

        /* L_temp = ltpGain * 2^(30 + exp) */
        L_temp = L_deposit_h (pred_gain);
        /* L_temp = ltpGain * 2^27 */
        L_temp = L_shr (L_temp, add (exp, 3));

        /* Log2 = log2() + 27 */
        Log2(L_temp, &ltpg_exp, &ltpg_frac);

        /* ltpg = log2(LtpGain) * 2^13 --> range: +- 4 = +- 12 dB */
        L_temp = L_Comp (sub (ltpg_exp, 27), ltpg_frac);
        *ltpg = round (L_shl (L_temp, 13)); /* Q13 */
    }
    else
    {
        *ltpg = 0;                           move16 ();
    }
}
Example #6
0
void Levinson(int32_t r32[],	/* (i)  : r32[] double precision vector of autocorrelation coefficients   */
	      int16_t a[],	/* (o)  : a[] in Q12 - LPC coefficients                                   */
	      int16_t old_a[],	/* (i/o): old_a[] in Q12 - previous LPC coefficients                      */
	      int16_t m		/* (i)  : LPC order                                                       */
    )
{
	int16_t i, j, high, low, alpha_hi, alpha_lo, alpha_exp;
	int16_t exp, r_hi[LPCO + 1], r_lo[LPCO + 1];
	int16_t a_hi[LPCO + 1], a_lo[LPCO + 1], anew_hi[LPCO + 1],
	    anew_lo[LPCO + 1];
	int16_t rc_hi, rc_lo;
	int32_t a0, a1, alpha_man;

	memzero(r_hi, (LPCO + 1) * sizeof(int16_t));
	memzero(r_lo, (LPCO + 1) * sizeof(int16_t));
	memzero(anew_hi, (LPCO + 1) * sizeof(int16_t));
	memzero(anew_lo, (LPCO + 1) * sizeof(int16_t));

	/* Normalization of autocorrelation coefficients */
	exp = bv_norm_l(r32[0]);
	for (i = 0; i <= m; i++) {
		r32[i] = L_bv_shl(r32[i], exp);
		L_Extract(r32[i], r_hi + i, r_lo + i);
	}

	/* a[1] = rc = -r[1]/r[0] */
	a1 = bv_L_abs(r32[1]);
	a0 = Div_32(a1, r_hi[0], r_lo[0]);	// rc in Q31
	if (r32[1] > 0)
		a0 = L_bv_negate(a0);
	L_Extract(L_bv_shr(a0, 4), a_hi + 1, a_lo + 1);	// Q27

	/*  alpha = r[0]*(1-rc*rc) */
	L_Extract(a0, &high, &low);
	a0 = Mpy_32(high, low, high, low);	// rc^2 in Q31
	a0 = bv_L_abs(a0);	// Lesson from G.729
	a0 = L_bv_sub(0x40000000, L_bv_shr(a0, 1));	// 1-rc*rc in Q30
	L_Extract(a0, &high, &low);
	a0 = Mpy_32(r_hi[0], r_lo[0], high, low);	// alpha in Q30
	alpha_exp = bv_norm_l(a0);
	alpha_man = L_bv_shl(a0, alpha_exp);
	alpha_exp = bv_sub(alpha_exp, 1);	// alpha: Q(31+alpha_exp)

	/* Recursive solution of Yule-Walker equations */
	for (i = 2; i <= m; i++) {

		/* s =  r[i] + sum{r[j]*a[i-j], j=1,2,...,i-1} */
		a0 = 0;
		for (j = 1; j < i; j++) {
			a1 = Mpy_32(r_hi[j], r_lo[j], a_hi[i - j], a_lo[i - j]);	// Q27
			a0 = L_bv_add(a0, a1);	// Q27
		}
		a0 = L_bv_shl(a0, 4);	// Q31
		a0 = L_bv_add(a0, r32[i]);	// Q31

		/* rc = -s/alpha */
		exp = bv_norm_l(a0);
		a0 = L_bv_shl(a0, exp);
		a1 = bv_L_abs(a0);
		if (L_bv_sub(a1, alpha_man) >= 0) {
			a1 = L_bv_shr(a1, 1);
			exp = bv_sub(exp, 1);
		}
		L_Extract(alpha_man, &alpha_hi, &alpha_lo);
		a1 = Div_32(a1, alpha_hi, alpha_lo);
		if (a0 > 0)
			a1 = L_bv_negate(a1);	// rc in Q(31+exp-alpha_exp)
		a1 = L_bv_shr(a1, bv_sub(exp, alpha_exp));	// rc in Q31
		L_Extract(a1, &rc_hi, &rc_lo);	// rc in Q31

		/* Check for absolute value of reflection coefficient - stability */
		if (bv_sub(bv_abs_s(intround(a1)), 32750) > 0) {
			a[0] = 4096;
			for (j = 1; j <= m; j++)
				a[j] = old_a[j];

			return;
		}

		/* anew[j]=a[j]+rc*a[i-j], j=1,2,...i-1 */
		/* anew[i]=rc                           */
		for (j = 1; j < i; j++) {
			a0 = Mpy_32(a_hi[i - j], a_lo[i - j], rc_hi, rc_lo);	// Q27
			a0 = L_bv_add(a0, L_Comp(a_hi[j], a_lo[j]));	// Q27
			L_Extract(a0, anew_hi + j, anew_lo + j);	// Q27
		}
		L_Extract(L_bv_shr(a1, 4), anew_hi + i, anew_lo + i);	// Q27

		/* alpha = alpha*(1-rc*rc) */
		a0 = Mpy_32(rc_hi, rc_lo, rc_hi, rc_lo);	// rc*rc in Q31
		a0 = bv_L_abs(a0);	// Lesson from G.729
		a0 = L_bv_shr(a0, 1);	// rc*rc in Q30
		a0 = L_bv_sub(0x40000000, a0);	// 1-rc*rc in Q30
		L_Extract(a0, &high, &low);
		a0 = Mpy_32(alpha_hi, alpha_lo, high, low);	// Q(30+alpha_exp)
		exp = bv_norm_l(a0);
		alpha_man = L_bv_shl(a0, exp);	// Q(30+exp+alpha_exp)
		alpha_exp = bv_sub(bv_add(alpha_exp, exp), 1);	// alpha: Q(31+alpha_exp)

		/* a[j] = anew[j] in Q(12+a1_exp) */
		for (j = 1; j <= i; j++) {
			a_hi[j] = anew_hi[j];
			a_lo[j] = anew_lo[j];
		}
	}

	/* convert lpc coefficients to Q12 and save new lpc as old lpc for next frame */
	a[0] = 4096;
	for (j = 1; j <= m; j++) {
		a[j] = intround(L_bv_shl(L_Comp(a_hi[j], a_lo[j]), 1));	// Q12
		old_a[j] = a[j];
	}

	return;
}
Example #7
0
void Levinsone(
  Word16 m,        /* (i)    : LPC order                         */
  Word16 Rh[],      /* (i)     : Rh[M+1] Vector of autocorrelations (msb) */
  Word16 Rl[],      /* (i)     : Rl[M+1] Vector of autocorrelations (lsb) */
  Word16 A[],       /* (o) Q12 : A[M]    LPC coefficients  (m = 10)       */
  Word16 rc[],      /* (o) Q15 : rc[M]   Reflection coefficients.         */
  Word16 old_A[],   /* (i/o) Q12 : last stable filter LPC coefficients  */
  Word16 old_rc[]   /* (i/o) Q15 : last stable filter Reflection coefficients.         */

)
{
 Word16 i, j;
 Word16 hi, lo;
 Word16 Kh, Kl;                /* reflection coefficient; hi and lo           */
 Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent         */
 Word16 Ah[M_BWDP1], Al[M_BWDP1];      /* LPC coef. in double prec.                   */
 Word16 Anh[M_BWDP1], Anl[M_BWDP1];    /* LPC coef.for next iteration in double prec. */
 Word32 t0, t1, t2;            /* temporary variable                          */
 Word32 tmp;

/* K = A[1] = -R[1] / R[0] */

  t1  = L_Comp(Rh[1], Rl[1]);           /* R[1] in Q31      */
  tmp = L_Comp(Rh[0], Rl[0]);
  if (t1 > tmp) t1 = tmp;

  t2  = L_abs(t1);                      /* abs R[1]         */
  t0  = Div_32(t2, Rh[0], Rl[0]);       /* R[1]/R[0] in Q31 */
  if(t1 > 0) t0= L_negate(t0);          /* -R[1]/R[0]       */
  L_Extract(t0, &Kh, &Kl);              /* K in DPF         */
  rc[0] = Kh;
  t0 = L_shr(t0,4);                     /* A[1] in Q27      */
  L_Extract(t0, &Ah[1], &Al[1]);        /* A[1] in DPF      */

/*  Alpha = R[0] * (1-K**2) */

  t0 = Mpy_32(Kh ,Kl, Kh, Kl);          /* K*K      in Q31 */
  t0 = L_abs(t0);                       /* Some case <0 !! */
  t0 = L_sub( (Word32)0x7fffffffL, t0 ); /* 1 - K*K  in Q31 */
  L_Extract(t0, &hi, &lo);              /* DPF format      */
  t0 = Mpy_32(Rh[0] ,Rl[0], hi, lo);    /* Alpha in Q31    */

/* Normalize Alpha */

  alp_exp = norm_l(t0);
  t0 = L_shl(t0, alp_exp);
  L_Extract(t0, &alp_h, &alp_l);         /* DPF format    */

/*--------------------------------------*
 * ITERATIONS  I=2 to m                 *
 *--------------------------------------*/

  for(i= 2; i<=m; i++)
  {

    /* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) +  R[i] */

    t0 = 0;
    for(j=1; j<i; j++)
      t0 = L_add(t0, Mpy_32(Rh[j], Rl[j], Ah[i-j], Al[i-j]));

    t0 = L_shl(t0,4);                  /* result in Q27 -> convert to Q31 */
                                       /* No overflow possible            */
    t1 = L_Comp(Rh[i],Rl[i]);

    t0 = L_add(t0, t1);                /* add R[i] in Q31                 */

    /* K = -t0 / Alpha */

    t1 = L_abs(t0);
    tmp = L_Comp(alp_h, alp_l);
    if (t1 > tmp) t1 = tmp;
    t2 = Div_32(t1, alp_h, alp_l);     /* abs(t0)/Alpha                   */
    if(t0 > 0) t2= L_negate(t2);       /* K =-t0/Alpha                    */
    t2 = L_shl(t2, alp_exp);           /* denormalize; compare to Alpha   */
    L_Extract(t2, &Kh, &Kl);           /* K in DPF                        */
    rc[i-1] = Kh;

    /* Test for unstable filter. If unstable keep old A(z) */

    if (sub(abs_s(Kh), 32750) > 0)
    {
      for(j=0; j<=m; j++)
      {
        A[j] = old_A[j];
      }
      rc[0] = old_rc[0];        /* only two rc coefficients are needed */
      rc[1] = old_rc[1];
      return;
    }

    /*------------------------------------------*
     *  Compute new LPC coeff. -> An[i]         *
     *  An[j]= A[j] + K*A[i-j]     , j=1 to i-1 *
     *  An[i]= K                                *
     *------------------------------------------*/


    for(j=1; j<i; j++)
    {
      t0 = Mpy_32(Kh, Kl, Ah[i-j], Al[i-j]);
      t0 = L_add(t0, L_Comp(Ah[j], Al[j]));
      L_Extract(t0, &Anh[j], &Anl[j]);
    }
    t2 = L_shr(t2, 4);                  /* t2 = K in Q31 ->convert to Q27  */
    L_Extract(t2, &Anh[i], &Anl[i]);    /* An[i] in Q27                    */

    /*  Alpha = Alpha * (1-K**2) */

    t0 = Mpy_32(Kh ,Kl, Kh, Kl);          /* K*K      in Q31 */
    t0 = L_abs(t0);                       /* Some case <0 !! */
    t0 = L_sub( (Word32)0x7fffffffL, t0 ); /* 1 - K*K  in Q31 */
    L_Extract(t0, &hi, &lo);              /* DPF format      */
    t0 = Mpy_32(alp_h , alp_l, hi, lo);   /* Alpha in Q31    */

    /* Normalize Alpha */

    j = norm_l(t0);
    t0 = L_shl(t0, j);
    L_Extract(t0, &alp_h, &alp_l);         /* DPF format    */
    alp_exp = add(alp_exp, j);             /* Add normalization to alp_exp */

    /* A[j] = An[j] */

    for(j=1; j<=i; j++)
    {
      Ah[j] =Anh[j];
      Al[j] =Anl[j];
    }
  }

  /* Truncate A[i] in Q27 to Q12 with rounding */

  A[0] = 4096;
  for(i=1; i<=m; i++)
  {
    t0   = L_Comp(Ah[i], Al[i]);
    old_A[i] = A[i] = round(L_shl(t0, 1));
  }
  old_rc[0] = rc[0];
  old_rc[1] = rc[1];

  return;
}
Example #8
0
/*----------------------------------------------------------------------------
 *  search_del: computes best (shortest) integer LTP delay + fine search
 *----------------------------------------------------------------------------
 */
static void search_del(
    Word16 t0,                /* input : pitch delay given by coder */
    Word16 *ptr_sig_in,       /* input : input signal (with delay line) */
    Word16 *ltpdel,           /* output: delay = *ltpdel - *phase / f_up */
    Word16 *phase,            /* output: phase */
    Word16 *num_gltp,         /* output: 16 bits numerator of LTP gain */
    Word16 *den_gltp,         /* output: 16 bits denominator of LTP gain */
    Word16 *sh_num_gltp,      /* output: justification for num_gltp */
    Word16 *sh_den_gltp,      /* output: justification for den_gltp */
    Word16 *y_up,             /* output: LT delayed signal if fract. delay */
    Word16 *off_yup           /* output: offset in y_up */
)
{

    /* Tables of constants */
    extern Word16 tab_hup_s[SIZ_TAB_HUP_S];

    Word32 L_den0[F_UP_PST-1];
    Word32 L_den1[F_UP_PST-1];
    Word32 *ptr_L_den0, *ptr_L_den1;

    int i, n;
    Word16 *ptr_h;
    Word16 *ptr_sig_past, *ptr_sig_past0;
    Word16 *ptr1, *ptr_y_up;
    Word16 num, den0, den1;
    Word16 den_max, num_max;
    Word32 L_num_int, L_den_int, L_den_max;
    Word16 hi_numsq, hi_numsq_max;
    Word16 lo_numsq, lo_numsq_max;
    Word16 ener;
    Word16 sh_num, sh_den, sh_ener;
    Word16 i_max, lambda, phi, phi_max, ioff;
    Word16 temp;
    Word32 L_temp0, L_temp1;
    Word32 L_acc;
    Word32 L_temp;


    /* Computes energy of current signal */
    /*************************************/

    L_acc = 0L;
    for(i=0; i<L_SUBFR; i++) {
        L_acc = L_mac( L_acc, ptr_sig_in[i] , ptr_sig_in[i]);
    }
    if(L_acc == 0) {
        *num_gltp = 0;
        *den_gltp = 1;
        *ltpdel = 0;
        *phase = 0;
        return;
    }
    sh_ener = sub(16, norm_l(L_acc));
    /* save energy for final decision */
    if(sh_ener > 0) {
        ener = extract_l(L_shr(L_acc, sh_ener));
    }
    else {
        sh_ener = 0;
        ener = extract_l(L_acc);
    }

    /*************************************/
    /* Selects best of 3 integer delays  */
    /* Maximum of 3 numerators around t0 */
    /*************************************/
    lambda = sub(t0,1);
    ptr_sig_past = ptr_sig_in - lambda;

    L_num_int = -1L;

    /* initialization used only to suppress Microsoft Visual C++ warnings */
    i_max = (Word16)0;

    for(i=0; i<3; i++) {
        L_acc = 0L;
        for(n=0; n<L_SUBFR; n++) {
            L_acc = L_mac( L_acc, ptr_sig_in[n] , ptr_sig_past[n]);
        }
        if(L_acc < 0) {
            L_acc = 0L;
        }
        L_temp =L_sub(L_acc ,L_num_int);
        if(L_temp > 0L) {
            L_num_int = L_acc;
            i_max = (Word16)i;
        }
        ptr_sig_past--;
    }

    if(L_num_int == 0) {
        *num_gltp = 0;
        *den_gltp = 1;
        *ltpdel = 0;
        *phase = 0;
        return;
    }

    /* Compute den for i_max */
    lambda = add(lambda, (Word16)i_max);
    ptr_sig_past = ptr_sig_in - lambda;
    L_acc = 0L;
    for(i=0; i<L_SUBFR; i++) {
        temp = *ptr_sig_past++;
        L_acc = L_mac( L_acc, temp, temp);
    }
    if(L_acc == 0L) {
        *num_gltp = 0;
        *den_gltp = 1;
        *ltpdel = 0;
        *phase = 0;
        return;
    }
    L_den_int = L_acc;


    /***********************************/
    /* Select best phase around lambda */
    /***********************************/

    /* Compute y_up & denominators */
    /*******************************/

    ptr_y_up = y_up;
    L_den_max = L_den_int;
    ptr_L_den0 = L_den0;
    ptr_L_den1 = L_den1;
    ptr_h = tab_hup_s;
    temp = sub(lambda, LH_UP_SM1);
    ptr_sig_past0 = ptr_sig_in - temp;

    /* Loop on phase */
    for(phi=1; phi<F_UP_PST; phi++) {

        /* Compute y_up for lambda+1 - phi/F_UP_PST */
        /* and lambda - phi/F_UP_PST                */

        ptr_sig_past = ptr_sig_past0;
        for(n = 0; n<=L_SUBFR; n++) {
            ptr1 = ptr_sig_past++;
            L_acc = 0L;
            for(i=0; i<LH2_S; i++) {
                L_acc = L_mac(L_acc, ptr_h[i], ptr1[-i]);
            }
            ptr_y_up[n] = round(L_acc);
        }

        /* compute den0 (lambda+1) and den1 (lambda) */

        /* part common to den0 and den1 */
        L_acc = 0L;
        for(n=1; n<L_SUBFR; n++) {
            L_acc = L_mac(L_acc, ptr_y_up[n] ,ptr_y_up[n]);
        }
        L_temp0 = L_acc;        /* saved for den1 */

        /* den0 */
        L_acc = L_mac(L_acc, ptr_y_up[0] ,ptr_y_up[0]);
        *ptr_L_den0 = L_acc;

        /* den1 */
        L_acc = L_mac(L_temp0, ptr_y_up[L_SUBFR] ,ptr_y_up[L_SUBFR]);
        *ptr_L_den1 = L_acc;

        if(sub(abs_s(ptr_y_up[0]),abs_s(ptr_y_up[L_SUBFR])) >0) {
            L_temp =L_sub(*ptr_L_den0 ,L_den_max );
            if(L_temp> 0L) {
                L_den_max = *ptr_L_den0;
            }
        }
        else {
            L_temp =L_sub(*ptr_L_den1 ,L_den_max );
            if(L_temp> 0L) {
                L_den_max = *ptr_L_den1;
            }
        }
        ptr_L_den0++;
        ptr_L_den1++;
        ptr_y_up += L_SUBFRP1;
        ptr_h += LH2_S;
    }

    if(L_den_max == 0) {
        *num_gltp = 0;
        *den_gltp = 1;
        *ltpdel = 0;
        *phase = 0;
        return;
    }

    sh_den = sub(16, norm_l(L_den_max));
    /* if sh_den <= 0 :  dynamic between current frame */
    /* and delay line too high                         */
    if(sh_den <= 0) {
        *num_gltp = 0;
        *den_gltp = 1;
        *ltpdel = 0;
        *phase = 0;
        return;
    }

    /* search sh_num to justify correlations   */
    /* sh_num = Max(sh_den, sh_ener)           */
    sh_num = (sub( sh_den , sh_ener)>=0) ? sh_den : sh_ener;

    /* Computation of the numerators                */
    /* and selection of best num*num/den            */
    /* for non null phases                          */

    /* Initialize with null phase */
    L_acc        = L_shr(L_den_int, sh_den);   /* sh_den > 0 */
    den_max      = extract_l(L_acc);
    L_acc        = L_shr(L_num_int, sh_num);   /* sh_num > 0 */
    num_max      = extract_l(L_acc);
    L_acc        = L_mult(num_max, num_max);
    L_Extract(L_acc, &hi_numsq_max, &lo_numsq_max);
    phi_max      = 0;
    ioff         = 1;

    ptr_L_den0   = L_den0;
    ptr_L_den1   = L_den1;
    ptr_y_up     = y_up;

    /* if den_max = 0 : will be selected and declared unvoiced */
    /* if num!=0 & den=0 : will be selected and declared unvoiced */
    /* degenerated seldom cases, switch off LT is OK */

    /* Loop on phase */
    for(phi=1; phi<F_UP_PST; phi++) {

        /* compute num for lambda+1 - phi/F_UP_PST */
        L_acc = 0L;
        for(n = 0; n<L_SUBFR; n++) {
            L_acc = L_mac(L_acc, ptr_sig_in[n] ,ptr_y_up[n]);
        }
        L_acc = L_shr(L_acc, sh_num);       /* sh_num > 0 */
        if(L_acc < 0L) {
            num = 0;
        }
        else {
            num  = extract_l(L_acc);
        }

        /* selection if num**2/den0 max */
        L_acc    = L_mult(num, num);
        L_Extract(L_acc, &hi_numsq, &lo_numsq);
        L_temp0  = Mpy_32_16(hi_numsq, lo_numsq, den_max);
        L_acc    = *ptr_L_den0++;
        L_acc    = L_shr(L_acc, sh_den);        /* sh_den > 0 */
        den0     = extract_l(L_acc);
        L_temp1  = Mpy_32_16(hi_numsq_max, lo_numsq_max, den0);
        L_temp = L_sub(L_temp0, L_temp1);
        if(L_temp>0L) {
            num_max      = num;
            hi_numsq_max = hi_numsq;
            lo_numsq_max = lo_numsq;
            den_max      = den0;
            ioff         = 0;
            phi_max      = phi;
        }

        /* compute num for lambda - phi/F_UP_PST */
        ptr_y_up++;
        L_acc = 0L;
        for(n = 0; n<L_SUBFR; n++) {
            L_acc = L_mac(L_acc, ptr_sig_in[n] ,ptr_y_up[n]);
        }
        L_acc = L_shr(L_acc, sh_num);   /* sh_num > 0 */
        if(L_acc < 0L) {
            num = 0;
        }
        else {
            num  = extract_l(L_acc);
        }

        /* selection if num**2/den1 max */
        L_acc    = L_mult(num, num);
        L_Extract(L_acc, &hi_numsq, &lo_numsq);
        L_temp0  = Mpy_32_16(hi_numsq, lo_numsq, den_max);
        L_acc    = *ptr_L_den1++;
        L_acc    = L_shr(L_acc, sh_den);        /* sh_den > 0 */
        den1     = extract_l(L_acc);
        L_temp1  = Mpy_32_16(hi_numsq_max, lo_numsq_max, den1);
        L_temp = L_sub(L_temp0,L_temp1);
        if(L_temp> 0L) {
            num_max      = num;
            hi_numsq_max = hi_numsq;
            lo_numsq_max = lo_numsq;
            den_max     = den1;
            ioff        = 1;
            phi_max     = phi;
        }

        ptr_y_up += L_SUBFR;
    }

    /***************************************************/
    /*** test if normalized crit0[iopt] > THRESHCRIT ***/
    /***************************************************/
    if((num_max == 0) || (sub(den_max,1) <= 0)) {
        *num_gltp = 0;
        *den_gltp = 1;
        *ltpdel = 0;
        *phase = 0;
        return;
    }

    /* compare num**2               */
    /* to ener * den * 0.5          */
    /* (THRESHCRIT = 0.5)           */
    L_temp1 = L_mult(den_max, ener);
    L_temp0 = L_Comp(hi_numsq_max, lo_numsq_max);

    /* temp = 2 * sh_num - sh_den - sh_ener + 1 */
    /* 16 bits with no overflows  */
    temp = shl(sh_num,1);
    temp = sub(temp, sh_den);
    temp = sub(temp, sh_ener);
    temp = add(temp, 1);
    if(temp < 0) {
        temp    = negate(temp);             /* no overflow */
        L_temp0 = L_shr(L_temp0, temp);
    }
    else {
        if(temp > 0) L_temp1 = L_shr(L_temp1, temp);
    }
    L_temp = L_sub(L_temp0 ,L_temp1);
    if(L_temp >= 0L) {
        temp         = add(lambda, 1);
        *ltpdel      = sub(temp, ioff);
        *off_yup     = ioff;
        *phase       = phi_max;
        *num_gltp    = num_max;
        *den_gltp    = den_max;
        *sh_den_gltp = sh_den;
        *sh_num_gltp = sh_num;
    }
    else {
        *num_gltp = 0;
        *den_gltp = 1;
        *ltpdel = 0;
        *phase = 0;
    }
    return;

}
Example #9
0
/*************************************************************************
 *
 *   FUNCTION:  Levinson()
 *
 *   PURPOSE:  Levinson-Durbin algorithm in double precision. To compute the
 *             LP filter parameters from the speech autocorrelations.
 *
 *   DESCRIPTION:
 *       R[i]    autocorrelations.
 *       A[i]    filter coefficients.
 *       K       reflection coefficients.
 *       Alpha   prediction gain.
 *
 *       Initialisation:
 *               A[0] = 1
 *               K    = -R[1]/R[0]
 *               A[1] = K
 *               Alpha = R[0] * (1-K**2]
 *
 *       Do for  i = 2 to M
 *
 *            S =  SUM ( R[j]*A[i-j] ,j=1,i-1 ) +  R[i]
 *
 *            K = -S / Alpha
 *
 *            An[j] = A[j] + K*A[i-j]   for j=1 to i-1
 *                                      where   An[i] = new A[i]
 *            An[i]=K
 *
 *            Alpha=Alpha * (1-K**2)
 *
 *       END
 *
 *************************************************************************/
int Levinson (
    LevinsonState *st,
    Word16 Rh[],       /* i : Rh[m+1] Vector of autocorrelations (msb) */
    Word16 Rl[],       /* i : Rl[m+1] Vector of autocorrelations (lsb) */
    Word16 A[],        /* o : A[m]    LPC coefficients  (m = 10)       */
    Word16 rc[]        /* o : rc[4]   First 4 reflection coefficients  */
)
{
    Word16 i, j;
    Word16 hi, lo;
    Word16 Kh, Kl;                /* reflexion coefficient; hi and lo      */
    Word16 alp_h, alp_l, alp_exp; /* Prediction gain; hi lo and exponent   */
    Word16 Ah[M + 1], Al[M + 1];  /* LPC coef. in double prec.             */
    Word16 Anh[M + 1], Anl[M + 1];/* LPC coef.for next iteration in double
                                     prec. */
    Word32 t0, t1, t2;            /* temporary variable                    */

    /* K = A[1] = -R[1] / R[0] */

    t1 = L_Comp (Rh[1], Rl[1]);
    t2 = L_abs (t1);                    /* abs R[1]         */
    t0 = Div_32 (t2, Rh[0], Rl[0]);     /* R[1]/R[0]        */

    if (t1 > 0)
       t0 = L_negate (t0);             /* -R[1]/R[0]       */
    L_Extract (t0, &Kh, &Kl);           /* K in DPF         */
    
    rc[0] = round (t0);

    t0 = L_shr (t0, 4);                 /* A[1] in          */
    L_Extract (t0, &Ah[1], &Al[1]);     /* A[1] in DPF      */

    /*  Alpha = R[0] * (1-K**2) */

    t0 = Mpy_32 (Kh, Kl, Kh, Kl);       /* K*K             */
    t0 = L_abs (t0);                    /* Some case <0 !! */
    t0 = L_sub ((Word32) 0x7fffffffL, t0); /* 1 - K*K        */
    L_Extract (t0, &hi, &lo);           /* DPF format      */
    t0 = Mpy_32 (Rh[0], Rl[0], hi, lo); /* Alpha in        */

    /* Normalize Alpha */

    alp_exp = norm_l (t0);
    t0 = L_shl (t0, alp_exp);
    L_Extract (t0, &alp_h, &alp_l);     /* DPF format    */

    /*--------------------------------------*
     * ITERATIONS  I=2 to M                 *
     *--------------------------------------*/

    for (i = 2; i <= M; i++)
    {
       /* t0 = SUM ( R[j]*A[i-j] ,j=1,i-1 ) +  R[i] */
       
       t0 = 0;
       for (j = 1; j < i; j++)
       {
          t0 = L_add (t0, Mpy_32 (Rh[j], Rl[j], Ah[i - j], Al[i - j]));
       }
       t0 = L_shl (t0, 4);
       
       t1 = L_Comp (Rh[i], Rl[i]);
       t0 = L_add (t0, t1);            /* add R[i]        */
       
       /* K = -t0 / Alpha */
       
       t1 = L_abs (t0);
       t2 = Div_32 (t1, alp_h, alp_l); /* abs(t0)/Alpha              */

       if (t0 > 0)
          t2 = L_negate (t2);         /* K =-t0/Alpha                */
       t2 = L_shl (t2, alp_exp);       /* denormalize; compare to Alpha */
       L_Extract (t2, &Kh, &Kl);       /* K in DPF                      */
       

       if (sub (i, 5) < 0)
       {
          rc[i - 1] = round (t2);
       }
       /* Test for unstable filter. If unstable keep old A(z) */
       

       if (sub (abs_s (Kh), 32750) > 0)
       {
          for (j = 0; j <= M; j++)
          {
             A[j] = st->old_A[j];
          }
          
          for (j = 0; j < 4; j++)
          {
             rc[j] = 0;
          }
          
          return 0;
       }
       /*------------------------------------------*
        *  Compute new LPC coeff. -> An[i]         *
        *  An[j]= A[j] + K*A[i-j]     , j=1 to i-1 *
        *  An[i]= K                                *
        *------------------------------------------*/
       
       for (j = 1; j < i; j++)
       {
          t0 = Mpy_32 (Kh, Kl, Ah[i - j], Al[i - j]);
          t0 = L_add(t0, L_Comp(Ah[j], Al[j]));
          L_Extract (t0, &Anh[j], &Anl[j]);
       }
       t2 = L_shr (t2, 4);
       L_Extract (t2, &Anh[i], &Anl[i]);
       
       /*  Alpha = Alpha * (1-K**2) */
       
       t0 = Mpy_32 (Kh, Kl, Kh, Kl);           /* K*K             */
       t0 = L_abs (t0);                        /* Some case <0 !! */
       t0 = L_sub ((Word32) 0x7fffffffL, t0);  /* 1 - K*K        */
       L_Extract (t0, &hi, &lo);               /* DPF format      */
       t0 = Mpy_32 (alp_h, alp_l, hi, lo);
       
       /* Normalize Alpha */
       
       j = norm_l (t0);
       t0 = L_shl (t0, j);
       L_Extract (t0, &alp_h, &alp_l);         /* DPF format    */
       alp_exp = add (alp_exp, j);             /* Add normalization to
                                                  alp_exp */
       
       /* A[j] = An[j] */
       
       for (j = 1; j <= i; j++)
       {
          Ah[j] = Anh[j];
          Al[j] = Anl[j];
       }
    }
    
    A[0] = 4096;
    for (i = 1; i <= M; i++)
    {
       t0 = L_Comp (Ah[i], Al[i]);
       st->old_A[i] = A[i] = round (L_shl (t0, 1));
    }
    
    return 0;
}
Example #10
0
INT16 q_gain_code (    /* Return quantization index                  */
    INT16 code[],      /* (i)      : fixed codebook excitation       */
    INT16 lcode,       /* (i)      : codevector size                 */
    INT16 *gain,       /* (i/o)    : quantized fixed codebook gain   */
    INT16 txdtx_ctrl,
    INT16 i_subfr
)
{
    INT16 i, index=0;
    INT16 gcode0, err, err_min, exp, frac;
    INT32 ener, ener_code;
    register INT32 ener_code_hi=0;
    register UINT32 ener_code_lo=0;
    INT16 aver_gain;
    static INT16 gcode0_CN;

    VPP_EFR_PROFILE_FUNCTION_ENTER(q_gain_code);



    if ((txdtx_ctrl & TX_SP_FLAG) != 0)
    {

        /*-------------------------------------------------------------------*
         *  energy of code:                                                   *
         *  ~~~~~~~~~~~~~~~                                                   *
         *  ener_code(Q17) = 10 * Log10(energy/lcode) / constant              *
         *                 = 1/2 * Log2(energy/lcode)                         *
         *                                           constant = 20*Log10(2)   *
         *-------------------------------------------------------------------*/

        /* ener_code = log10(ener_code/lcode) / (20*log10(2))       */
        //ener_code = 0;
        ener_code_lo = 0;
        for (i = 0; i < lcode; i++)
        {
            //ener_code = L_mac (ener_code, code[i], code[i]);
			//ener_code = L_MAC(ener_code, code[i], code[i]);
			VPP_MLA16(ener_code_hi,ener_code_lo,code[i], code[i]);

        }
        /* ener_code = ener_code / lcode */
        ener_code = VPP_SCALE64_TO_16(ener_code_hi,ener_code_lo);

		//ener_code = L_mult (round(ener_code), 26214);
        ener_code = L_MULT(ROUND(ener_code), 26214);

        /* ener_code = 1/2 * Log2(ener_code) */
        Log2 (ener_code, &exp, &frac);
        //ener_code = L_Comp (sub (exp, 30), frac);
		ener_code = L_Comp (SUB (exp, 30), frac);

        /* predicted energy */

        //ener = MEAN_ENER;
        ener_code_lo = MEAN_ENER>>1;
        ener_code_hi =0;

        for (i = 0; i < 4; i++)
        {
            //ener = L_mac (ener, past_qua_en[i], pred[i]);
			//ener = L_MAC(ener, past_qua_en[i], pred[i]);
			VPP_MLA16(ener_code_hi,ener_code_lo, past_qua_en[i], pred[i]);
        }

        ener = VPP_SCALE64_TO_16(ener_code_hi,ener_code_lo);

        /*-------------------------------------------------------------------*
         *  predicted codebook gain                                           *
         *  ~~~~~~~~~~~~~~~~~~~~~~~                                           *
         *  gcode0(Qx) = Pow10( (ener*constant - ener_code*constant) / 20 )   *
         *             = Pow2(ener-ener_code)                                 *
         *                                           constant = 20*Log10(2)   *
         *-------------------------------------------------------------------*/

        //ener = L_shr (L_SUB(ener, ener_code), 1);
        ener = L_SHR_D(L_SUB(ener, ener_code), 1);


        L_Extract (ener, &exp, &frac);

        //gcode0 = extract_l (Pow2 (exp, frac));  /* predicted gain */
		gcode0 = EXTRACT_L(Pow2 (exp, frac));

        //gcode0 = shl (gcode0, 4);
		gcode0 = SHL(gcode0, 4);

        /*-------------------------------------------------------------------*
         *                   Search for best quantizer                        *
         *-------------------------------------------------------------------*/

        //err_min = abs_s (sub (*gain, mult (gcode0, qua_gain_code[0])));
		err_min = ABS_S(SUB (*gain, MULT(gcode0, qua_gain_code[0])));
        index = 0;

        for (i = 1; i < NB_QUA_CODE; i++)
        {
            //err = abs_s (sub (*gain, mult (gcode0, qua_gain_code[i])));
			err = ABS_S(SUB (*gain, MULT (gcode0, qua_gain_code[i])));


            //if (sub (err, err_min) < 0)
			if (SUB (err, err_min) < 0)
            {
                err_min = err;
                index = i;
            }
        }

         //*gain = mult (gcode0, qua_gain_code[index]);
		 *gain = MULT(gcode0, qua_gain_code[index]);


        /*------------------------------------------------------------------*
         *  update table of past quantized energies                         *
         *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                         *
         *  past_qua_en(Q12) = 20 * Log10(qua_gain_code) / constant         *
         *                   = Log2(qua_gain_code)                          *
         *                                           constant = 20*Log10(2) *
         *------------------------------------------------------------------*/

        for (i = 3; i > 0; i--)
        {
            past_qua_en[i] = past_qua_en[i - 1];
        }
        //Log2 (L_deposit_l (qua_gain_code[index]), &exp, &frac);
		Log2 (L_DEPOSIT_L(qua_gain_code[index]), &exp, &frac);

        //past_qua_en[0] = shr (frac, 5);
		past_qua_en[0] = SHR_D(frac, 5);

        //past_qua_en[0] = add (past_qua_en[0], shl (sub (exp, 11), 10));
        past_qua_en[0] = ADD (past_qua_en[0], SHL(SUB (exp, 11), 10));


        update_gain_code_history_tx (*gain, gain_code_old_tx);
    }