Example #1
0
/*-------------------------------------------------------------------*
* Function  set_sign()                                              *
* ~~~~~~~~~~~~~~~~~~~~                                              *
* Set the sign of each pulse position.                              *
*-------------------------------------------------------------------*/
static void set_sign(
  Word16 fac_cn,     /* (i) Q15: residual weight for sign determination */
  Word16 cn[],       /* (i) Q0 : residual after long term prediction    */
  Word16 dn[],       /* (i) Q0 : correlation between target and h[]     */
  Word16 sign[],     /* (o) Q15: sign vector (sign of each position)    */
  Word16 inv_sign[], /* (o) Q15: inverse of sign[]                      */
  Word16 pos_max[],  /* (o)    : pos of max of correlation              */
  Word32 corr[]      /* (o)    : correlation of each track              */
)
{
    Word16 i, k, pos, k_cn, k_dn, val;
    Word32 s, max;

    /* calculate energy for normalization of cn[] and dn[] */
    s = 0;
    for (i=0; i<L_SUBFR; i++) s = L_mac(s, cn[i], cn[i]);
    if (s < 512) s = 512;
    s = Inv_sqrt(s);
    k_cn = extract_h(L_shl(s, 5));     /* k_cn = 11..23170 */
    k_cn = mult(k_cn, fac_cn);

    s = 0;
    for (i=0; i<L_SUBFR; i++) s = L_mac(s, dn[i], dn[i]);
    if (s < 512) s = 512;
    s = Inv_sqrt(s);
    k_dn = extract_h(L_shl(s, 5));     /* k_dn = 11..23170 */

    /* set sign according to en[] = k_cn*cn[] + k_dn*dn[]    */

    /* find position of maximum of correlation in each track */
    for (k=0; k<NB_TRACK; k++) {
        max = -1;
        for (i=k; i<L_SUBFR; i+=STEP) {
            val = dn[i];
            s = L_mac(L_mult(k_cn, cn[i]), k_dn, val);
            if (s >= 0) {
                sign[i] = 32767L;         /* sign = +1 (Q15) */
                inv_sign[i] = -32768L;
            }
            else {
                sign[i] = -32768L;        /* sign = -1 (Q15) */
                inv_sign[i] = 32767L;
                val = negate(val);
            }
            dn[i] = val;      /* modify dn[] according to the fixed sign */
            s = L_abs(s);
            if (s > max) {
                max = s;
                pos = i;
            }
        }
        pos_max[k] = pos;
        corr[k] = max;
    }

    return;
}
Example #2
0
static Word16 Lag_max( /* output: lag found                                  */
  Word16 signal[],     /* input : signal used to compute the open loop pitch */
  Word16 L_frame,      /* input : length of frame to compute pitch           */
  Word16 lag_max,      /* input : maximum lag                                */
  Word16 lag_min,      /* input : minimum lag                                */
  Word16 *cor_max)     /* output: normalized correlation of selected lag     */
{
  Word16  i, j;
  Word16  *p, *p1;
  Word32  max, t0, L_temp;
  Word16  max_h, max_l, ener_h, ener_l;
  Word16  p_max;

  max = MIN_32;

   /* initialization used only to suppress Microsoft Visual C++  warnings */

  p_max = lag_max;

  for (i = lag_max; i >= lag_min; i--)
  {
    p  = signal;
    p1 = &signal[-i];
    t0 = 0;

    for (j=0; j<L_frame; j++, p++, p1++)
      t0 = L_mac(t0, *p, *p1);

    L_temp = L_sub(t0,max);
    if (L_temp >= 0L)
    {
      max    = t0;
      p_max = i;
    }
  }

  /* compute energy */

  t0 = 0;
  p = &signal[-p_max];
  for(i=0; i<L_frame; i++, p++)
    t0 = L_mac(t0, *p, *p);

  /* 1/sqrt(energy),    result in Q30 */

  t0 = Inv_sqrt(t0);

  /* max = max/sqrt(energy)                   */
  /* This result will always be on 16 bits !! */

  L_Extract(max, &max_h, &max_l);
  L_Extract(t0, &ener_h, &ener_l);

  t0 = Mpy_32(max_h, max_l, ener_h, ener_l);
  *cor_max = extract_l(t0);

  return(p_max);
}
Example #3
0
void agc(
  Word16 *sig_in,   /* (i)     : postfilter input signal  */
  Word16 *sig_out,  /* (i/o)   : postfilter output signal */
  Word16 l_trm      /* (i)     : subframe size            */
)
{
#if 0 	
  static Word16 past_gain=4096;         /* past_gain = 1.0 (Q12) */
#endif  
  Word16 i, exp;
  Word16 gain_in, gain_out, g0, gain;                     /* Q12 */
  Word32 s;

  Word16 signal[L_SUBFR];

  /* calculate gain_out with exponent */

  for(i=0; i<l_trm; i++)
    signal[i] = shr(sig_out[i], 2);

  s = 0;
  for(i=0; i<l_trm; i++)
    s = L_mac(s, signal[i], signal[i]);

  if (s == 0) {
    pg729dec->ppost_filt->past_gain = 0;
    return;
  }
  exp = sub(norm_l(s), 1);
  if(exp>0)
  gain_out = round(L_shl(s, exp));
  else
  	gain_out = round(L_shr(s, abs_s(exp)));
  /* calculate gain_in with exponent */

  for(i=0; i<l_trm; i++)
    signal[i] = shr(sig_in[i], 2);

  s = 0;
  for(i=0; i<l_trm; i++)
    s = L_mac(s, signal[i], signal[i]);

  if (s == 0) {
    g0 = 0;
  }
  else {
    i = norm_l(s);
    if(i>=0)
    gain_in = round(L_shl(s, i));
    else
    	gain_in = round(L_shr(s, abs_s(i)));
    exp = sub(exp, i);

   /*---------------------------------------------------*
    *  g0(Q12) = (1-AGC_FAC) * sqrt(gain_in/gain_out);  *
    *---------------------------------------------------*/

    s = L_deposit_l(div_s(gain_out,gain_in));   /* Q15 */
    s = L_shl(s, 7);           /* s(Q22) = gain_out / gain_in */
    if(exp>0)
    s = L_shr(s, exp);         /* Q22, add exponent */
	else
		s = L_shl(s, abs_s(exp));

    /* i(Q12) = s(Q19) = 1 / sqrt(s(Q22)) */
    s = Inv_sqrt(s);           /* Q19 */
    i = round(L_shl(s,9));     /* Q12 */

    /* g0(Q12) = i(Q12) * (1-AGC_FAC)(Q15) */
    g0 = mult(i, AGC_FAC1);       /* Q12 */
  }

  /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */
  /* sig_out(n) = gain(n) sig_out(n)                                   */

  gain = pg729dec->ppost_filt->past_gain;
  for(i=0; i<l_trm; i++) {
    gain = mult(gain, AGC_FAC);
    gain = add(gain, g0);
    sig_out[i] = extract_h(L_shl(L_mult(sig_out[i], gain), 3));
  }
  pg729dec->ppost_filt->past_gain = gain;

  return;
}
Example #4
0
static void Norm_Corr(Word16 exc[], Word16 xn[], Word16 h[], Word16 L_subfr,
               Word16 t_min, Word16 t_max, Word16 corr_norm[])
{
  Word16 i,j,k;
  Word16 corr_h, corr_l, norm_h, norm_l;
  Word32 s, L_temp;

  Word16 excf[L_SUBFR];
  Word16 scaling, h_fac, *s_excf, scaled_excf[L_SUBFR];


  k =  negate(t_min);

  /* compute the filtered excitation for the first delay t_min */

  Convolve(&exc[k], h, excf, L_subfr);

  /* scaled "excf[]" to avoid overflow */

  for(j=0; j<L_subfr; j++)
    scaled_excf[j] = shr(excf[j], 2);

  /* Compute energy of excf[] for danger of overflow */

  s = 0;
  for (j = 0; j < L_subfr; j++)
    s = L_mac(s, excf[j], excf[j]);

  L_temp = L_sub(s, 67108864L);
  if (L_temp <= 0L)      /* if (s <= 2^26) */
  {
    s_excf = excf;
    h_fac = 15-12;               /* h in Q12 */
    scaling = 0;
  }
  else {
    s_excf = scaled_excf;        /* "excf[]" is divide by 2 */
    h_fac = 15-12-2;             /* h in Q12, divide by 2 */
    scaling = 2;
  }

  /* loop for every possible period */

  for (i = t_min; i <= t_max; i++)
  {
    /* Compute 1/sqrt(energy of excf[]) */

    s = 0;
    for (j = 0; j < L_subfr; j++)
      s = L_mac(s, s_excf[j], s_excf[j]);

    s = Inv_sqrt(s);                     /* Result in Q30 */
    L_Extract(s, &norm_h, &norm_l);

    /* Compute correlation between xn[] and excf[] */

    s = 0;
    for (j = 0; j < L_subfr; j++)
      s = L_mac(s, xn[j], s_excf[j]);

    L_Extract(s, &corr_h, &corr_l);

    /* Normalize correlation = correlation * (1/sqrt(energy)) */

    s = Mpy_32(corr_h, corr_l, norm_h, norm_l);

    corr_norm[i] = extract_h(L_shl(s, 16));   /* Result is on 16 bits */

    /* modify the filtered excitation excf[] for the next iteration */

    if( sub(i, t_max) != 0)
    {
      k=sub(k,1);
      for (j = L_subfr-(Word16)1; j > 0; j--)
      {
        s = L_mult(exc[k], h[j]);
        s = L_shl(s, h_fac);             /* h is in Q(12-scaling) */
        s_excf[j] = add(extract_h(s), s_excf[j-1]);
      }
      s_excf[0] = shr(exc[k], scaling);
    }
  }
  return;
}
Example #5
0
/*************************************************************************
 *
 *  FUNCTION:  Lag_max
 *
 *  PURPOSE: Find the lag that has maximum correlation of scal_sig[] in a
 *           given delay range.
 *
 *  DESCRIPTION:
 *      The correlation is given by
 *           cor[t] = <scal_sig[n],scal_sig[n-t]>,  t=lag_min,...,lag_max
 *      The functions outputs the maximum correlation after normalization
 *      and the corresponding lag.
 *
 *************************************************************************/
Word16 Lag_max ( /* o   : lag found                               */
    vadState1 *vadSt,    /* i/o : VAD state struct                        */
    Word32 corr[],      /* i   : correlation vector.                     */
    Word16 scal_sig[],  /* i   : scaled signal.                          */    
    Word16 scal_fac,    /* i   : scaled signal factor.                   */
    Word16 scal_flag,   /* i   : if 1 use EFR compatible scaling         */
    Word16 L_frame,     /* i   : length of frame to compute pitch        */
    Word16 lag_max,     /* i   : maximum lag                             */
    Word16 lag_min,     /* i   : minimum lag                             */
    Word16 *cor_max,    /* o   : normalized correlation of selected lag  */
    Flag dtx            /* i   : dtx flag; use dtx=1, do not use dtx=0   */
    )
{
    Word16 i, j;
    Word16 *p;
    Word32 max, t0;
    Word16 max_h, max_l, ener_h, ener_l;
    Word16 p_max = 0; /* initialization only needed to keep gcc silent */
    
    long lTemp;

	max = MIN_32;                
    p_max = lag_max;            
   
    for (i = lag_max, j = (PIT_MAX-lag_max-1); i >= lag_min; i--, j--)  
    {
         
       if (corr[-i] >= max) 
       { 
          max = corr[-i];         
          p_max = i;              
       } 
    }
    
    /* compute energy */

    t0 = 0;                          
    p = &scal_sig[-p_max];       
    for (i = 0; i < L_frame; i++, p++)
    {
        //t0 = L_mac (t0, *p, *p);
		lTemp = (*p) * (*p);

		if (lTemp != 0x40000000)
		{
			lTemp = lTemp * 2;
		}
		else
		{
			lTemp = MAX_32;
		}

		lTemp = lTemp + t0;

		if (lTemp > MAX_32)
		{
			t0 = MAX_32;
		}
		else if (lTemp < MIN_32)
		{
			t0 = MIN_32;
		}
		else 
		{
			t0 = (Word32)lTemp;
		}

    }
    /* 1/sqrt(energy) */

    if (dtx)
    {  /* no test() call since this if is only in simulation env */
       /* check tone */
       vad_tone_detection (vadSt, max, t0);
    }
    
    t0 = Inv_sqrt (t0);  /* function result */

    
    if (scal_flag)
    {
       t0 = L_shl (t0, 1);
    }
    
    /* max = max/sqrt(energy)  */

    L_Extract (max, &max_h, &max_l);
    L_Extract (t0, &ener_h, &ener_l);

    t0 = Mpy_32 (max_h, max_l, ener_h, ener_l);
    
    
    if (scal_flag)
    {
      t0 = L_shr (t0, scal_fac);
      *cor_max = extract_h (L_shl (t0, 15)); /* divide by 2 */
    }
    else
    {
      *cor_max = extract_l(t0);
    }

    return (p_max);
}
Example #6
0
/*************************************************************************
 *
 *  FUNCTION  set_sign12k2()
 *
 *  PURPOSE: Builds sign[] vector according to "dn[]" and "cn[]", and modifies
 *           dn[] to include the sign information (dn[i]=sign[i]*dn[i]).
 *           Also finds the position of maximum of correlation in each track
 *           and the starting position for each pulse.
 *
 *************************************************************************/
void set_sign12k2 (
    Word16 dn[],      /* i/o : correlation between target and h[]         */
    Word16 cn[],      /* i   : residual after long term prediction        */
    Word16 sign[],    /* o   : sign of d[n]                               */
    Word16 pos_max[], /* o   : position of maximum correlation            */
    Word16 nb_track,  /* i   : number of tracks tracks                    */        
    Word16 ipos[],    /* o   : starting position for each pulse           */
    Word16 step       /* i   : the step size in the tracks                */        
)
{
    Word16 i, j;
    Word16 val, cor, k_cn, k_dn, max, max_of_all;
    Word16 pos = 0; /* initialization only needed to keep gcc silent */
    Word16 en[L_CODE];                  /* correlation vector */
    Word32 s;
 
    /* calculate energy for normalization of cn[] and dn[] */
 
    s = 256;                                     move32 (); 
    for (i = 0; i < L_CODE; i++)
    {
        s = L_mac (s, cn[i], cn[i]);
    }
    s = Inv_sqrt (s);                            move32 (); 
    k_cn = extract_h (L_shl (s, 5));
    
    s = 256;                                     move32 (); 
    for (i = 0; i < L_CODE; i++)
    {
        s = L_mac (s, dn[i], dn[i]);
    }
    s = Inv_sqrt (s);                            move32 (); 
    k_dn = extract_h (L_shl (s, 5));
    
    for (i = 0; i < L_CODE; i++)
    {
        val = dn[i];                             move16 (); 
        cor = round (L_shl (L_mac (L_mult (k_cn, cn[i]), k_dn, val), 10));
 
        test (); 
        if (cor >= 0)
        {
            sign[i] = 32767;                     move16 (); /* sign = +1 */
        }
        else
        {
            sign[i] = -32767;                    move16 (); /* sign = -1 */
            cor = negate (cor);
            val = negate (val);
        }
        /* modify dn[] according to the fixed sign */        
        dn[i] = val;                             move16 (); 
        en[i] = cor;                             move16 (); 
    }
    
    max_of_all = -1;                             move16 (); 
    for (i = 0; i < nb_track; i++)
    {
        max = -1;                                move16 (); 
        
        for (j = i; j < L_CODE; j += step)
        {
            cor = en[j];                         move16 (); 
            val = sub (cor, max);
            test (); 
            if (val > 0)
            {
                max = cor;                       move16 (); 
                pos = j;                         move16 (); 
            }
        }
        /* store maximum correlation position */
        pos_max[i] = pos;                        move16 (); 
        val = sub (max, max_of_all);
        test (); 
        if (val > 0)
        {
            max_of_all = max;                    move16 ();
            /* starting position for i0 */            
            ipos[0] = i;                         move16 (); 
        }
    }
    
    /*----------------------------------------------------------------*
     *     Set starting position of each pulse.                       *
     *----------------------------------------------------------------*/
    
    pos = ipos[0];                               move16 (); 
    ipos[nb_track] = pos;                        move16 (); 
    
    for (i = 1; i < nb_track; i++)
    {
        pos = add (pos, 1);
        test ();
        if (sub (pos, nb_track) >= 0)
        {
           pos = 0;                              move16 (); 
        }
        ipos[i] = pos;                           move16 (); 
        ipos[add(i, nb_track)] = pos;            move16 (); 
    }
}
Example #7
0
Word16 Pitch_ol_fast(  /* output: open loop pitch lag                        */
   Word16 signal[],    /* input : signal used to compute the open loop pitch */
                       /*     signal[-pit_max] to signal[-1] should be known */
   Word16   pit_max,   /* input : maximum pitch lag                          */
   Word16   L_frame    /* input : length of frame to compute pitch           */
)
{
  Word16  i, j;
  Word16  max1, max2, max3;
  Word16  max_h, max_l, ener_h, ener_l;
  Word16  T1, T2, T3;
  Word16  *p, *p1;
  Word32  max, sum, L_temp;

  /* Scaled signal */

  Word16 scaled_signal[L_FRAME+PIT_MAX];
  Word16 *scal_sig;

  scal_sig = &scaled_signal[pit_max];

  /*--------------------------------------------------------*
   *  Verification for risk of overflow.                    *
   *--------------------------------------------------------*/

   Overflow = 0;
   sum = 0;

   for(i= -pit_max; i< L_frame; i+=2)
     sum = L_mac(sum, signal[i], signal[i]);

  /*--------------------------------------------------------*
   * Scaling of input signal.                               *
   *                                                        *
   *   if Overflow        -> scal_sig[i] = signal[i]>>3     *
   *   else if sum < 1^20 -> scal_sig[i] = signal[i]<<3     *
   *   else               -> scal_sig[i] = signal[i]        *
   *--------------------------------------------------------*/

   if(Overflow == 1)
   {
     for(i=-pit_max; i<L_frame; i++)
     {
       scal_sig[i] = shr(signal[i], 3);
     }
   }
   else {
     L_temp = L_sub(sum, (Word32)1048576L);
     if ( L_temp < (Word32)0 )  /* if (sum < 2^20) */
     {
        for(i=-pit_max; i<L_frame; i++)
        {
          scal_sig[i] = shl(signal[i], 3);
        }
     }
     else
     {
       for(i=-pit_max; i<L_frame; i++)
       {
         scal_sig[i] = signal[i];
       }
     }
   }

   /*--------------------------------------------------------------------*
    *  The pitch lag search is divided in three sections.                *
    *  Each section cannot have a pitch multiple.                        *
    *  We find a maximum for each section.                               *
    *  We compare the maxima of each section by favoring small lag.      *
    *                                                                    *
    *  First section:  lag delay = 20 to 39                              *
    *  Second section: lag delay = 40 to 79                              *
    *  Third section:  lag delay = 80 to 143                             *
    *--------------------------------------------------------------------*/

    /* First section */

    max = MIN_32;
    T1  = 20;    /* Only to remove warning from some compilers */
    for (i = 20; i < 40; i++) {
        p  = scal_sig;
        p1 = &scal_sig[-i];
        sum = 0;
        for (j=0; j<L_frame; j+=2, p+=2, p1+=2)
            sum = L_mac(sum, *p, *p1);
        L_temp = L_sub(sum, max);
        if (L_temp > 0) { max = sum; T1 = i;   }
    }

    /* compute energy of maximum */

    sum = 1;                   /* to avoid division by zero */
    p = &scal_sig[-T1];
    for(i=0; i<L_frame; i+=2, p+=2)
        sum = L_mac(sum, *p, *p);

    /* max1 = max/sqrt(energy)                  */
    /* This result will always be on 16 bits !! */

    sum = Inv_sqrt(sum);            /* 1/sqrt(energy),    result in Q30 */
    L_Extract(max, &max_h, &max_l);
    L_Extract(sum, &ener_h, &ener_l);
    sum  = Mpy_32(max_h, max_l, ener_h, ener_l);
    max1 = extract_l(sum);

    /* Second section */

    max = MIN_32;
    T2  = 40;    /* Only to remove warning from some compilers */
    for (i = 40; i < 80; i++) {
        p  = scal_sig;
        p1 = &scal_sig[-i];
        sum = 0;
        for (j=0; j<L_frame; j+=2, p+=2, p1+=2)
            sum = L_mac(sum, *p, *p1);
        L_temp = L_sub(sum, max);
        if (L_temp > 0) { max = sum; T2 = i;   }
    }

    /* compute energy of maximum */

    sum = 1;                   /* to avoid division by zero */
    p = &scal_sig[-T2];
    for(i=0; i<L_frame; i+=2, p+=2)
        sum = L_mac(sum, *p, *p);

    /* max2 = max/sqrt(energy)                  */
    /* This result will always be on 16 bits !! */

    sum = Inv_sqrt(sum);            /* 1/sqrt(energy),    result in Q30 */
    L_Extract(max, &max_h, &max_l);
    L_Extract(sum, &ener_h, &ener_l);
    sum  = Mpy_32(max_h, max_l, ener_h, ener_l);
    max2 = extract_l(sum);

    /* Third section */

    max = MIN_32;
    T3  = 80;    /* Only to remove warning from some compilers */
    for (i = 80; i < 143; i+=2) {
        p  = scal_sig;
        p1 = &scal_sig[-i];
        sum = 0;
        for (j=0; j<L_frame; j+=2, p+=2, p1+=2)
            sum = L_mac(sum, *p, *p1);
        L_temp = L_sub(sum, max);
        if (L_temp > 0) { max = sum; T3 = i;   }
    }

     /* Test around max3 */

     i = T3;
     p  = scal_sig;
     p1 = &scal_sig[-(i+1)];
     sum = 0;
     for (j=0; j<L_frame; j+=2, p+=2, p1+=2)
         sum = L_mac(sum, *p, *p1);
     L_temp = L_sub(sum, max);
     if (L_temp > 0) { max = sum; T3 = i+(Word16)1;   }

     p  = scal_sig;
     p1 = &scal_sig[-(i-1)];
     sum = 0;
     for (j=0; j<L_frame; j+=2, p+=2, p1+=2)
         sum = L_mac(sum, *p, *p1);
     L_temp = L_sub(sum, max);
     if (L_temp > 0) { max = sum; T3 = i-(Word16)1;   }

    /* compute energy of maximum */

    sum = 1;                   /* to avoid division by zero */
    p = &scal_sig[-T3];
    for(i=0; i<L_frame; i+=2, p+=2)
        sum = L_mac(sum, *p, *p);

    /* max1 = max/sqrt(energy)                  */
    /* This result will always be on 16 bits !! */

    sum = Inv_sqrt(sum);            /* 1/sqrt(energy),    result in Q30 */
    L_Extract(max, &max_h, &max_l);
    L_Extract(sum, &ener_h, &ener_l);
    sum  = Mpy_32(max_h, max_l, ener_h, ener_l);
    max3 = extract_l(sum);

   /*-----------------------*
    * Test for multiple.    *
    *-----------------------*/

    /* if( abs(T2*2 - T3) < 5)  */
    /*    max2 += max3 * 0.25;  */

    i = sub(shl(T2,1), T3);
    j = sub(abs_s(i), 5);
    if(j < 0)
      max2 = add(max2, shr(max3, 2));

    /* if( abs(T2*3 - T3) < 7)  */
    /*    max2 += max3 * 0.25;  */

    i = add(i, T2);
    j = sub(abs_s(i), 7);
    if(j < 0)
      max2 = add(max2, shr(max3, 2));

    /* if( abs(T1*2 - T2) < 5)  */
    /*    max1 += max2 * 0.20;  */

    i = sub(shl(T1,1), T2);
    j = sub(abs_s(i), 5);
    if(j < 0)
      max1 = add(max1, mult(max2, 6554));

    /* if( abs(T1*3 - T2) < 7)  */
    /*    max1 += max2 * 0.20;  */

    i = add(i, T1);
    j = sub(abs_s(i), 7);
    if(j < 0)
      max1 = add(max1, mult(max2, 6554));

   /*--------------------------------------------------------------------*
    * Compare the 3 sections maxima.                                     *
    *--------------------------------------------------------------------*/

    if( sub(max1, max2) < 0 ) {max1 = max2; T1 = T2;  }
    if( sub(max1, max3) <0 )  {T1 = T3; }

    return T1;
}
Example #8
0
/*-------------------------------------------------------------------*
* Function  cor_h_e()                                                 *
* ~~~~~~~~~~~~~~~~~                                                 *
* Compute correlations of h[] needed for the codebook search.       *
*-------------------------------------------------------------------*/
static void cor_h_e(
  Word16 H[],              /* (i) Q12 :Impulse response of filters */
  Word16 sign[],           /* (i) Q15: sign vector                 */
  Word16 inv_sign[],       /* (i) Q15: inverse of sign[]           */
  Word16 h[],              /* (o)     : scaled h[]                 */
  Word16 h_inv[],          /* (o)     : inverse of scaled h[]      */
  Word16 rrixix[][NB_POS], /* (o) energy of h[].                   */
  Word16 rrixiy[][MSIZE]   /* (o) correlation between 2 pulses.    */
)
{
    Word16 i, j, k, pos;
    Word16 *ptr_h1, *ptr_h2, *ptr_hf, *psign;
    Word16 *p0, *p1, *p2, *p3, *p4;
    Word32 cor;

    /*------------------------------------------------------------*
    * normalize h[] for maximum precision on correlation.        *
    *------------------------------------------------------------*/
    cor = 0;
    for(i=0; i<L_SUBFR; i++) cor = L_mac(cor, H[i], H[i]);

    /* scale h[] with shift operation */
    k = norm_l(cor);
    k = shr(k, 1);
    for(i=0; i<L_SUBFR; i++) h[i] = shl(H[i], k);
    cor = L_shl(cor, add(k, k));

    /*------------------------------------------------------------*
    * Scaling h[] with a factor (0.5 < fac < 0.25)               *
    * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~               *
    * extract_h(cor) = 8192 .. 32768 --> scale to 4096 (1/8 Q15) *
    *                                                            *
    * 4096 (1/8) = fac^2 * extract_h(cor)                        *
    * fac = sqrt(4096/extract_h(cor))                            *
    *                                                            *
    * fac = 1/sqrt(cor/4096) * 256 = 0.125 to 0.5                *
    *------------------------------------------------------------*/
    cor = L_shr(cor, 12);
    k = extract_h(L_shl(Inv_sqrt(cor), 8));
    for(i=0; i<L_SUBFR; i++) {
        h[i] = mult(h[i], k);
        h_inv[i] = negate(h[i]);
    }

    /*------------------------------------------------------------*
    * Compute rrixix[][] needed for the codebook search.         *
    * This algorithm compute impulse response energy of all      *
    * positions (8) in each track (5).         Total = 5x8 = 40. *
    *------------------------------------------------------------*/
    /* storage order --> i4i4, i3i3, i2i2, i1i1, i0i0 */
    /* Init pointers to last position of rrixix[] */
    p0 = &rrixix[0][NB_POS-1];
    p1 = &rrixix[1][NB_POS-1];
    p2 = &rrixix[2][NB_POS-1];
    p3 = &rrixix[3][NB_POS-1];
    p4 = &rrixix[4][NB_POS-1];
    ptr_h1 = h;
    cor    = 0x00010000L;           /* 1.0 (for rounding) */
    for(i=0; i<NB_POS; i++) {
        cor = L_mac(cor, *ptr_h1, *ptr_h1);  ptr_h1++;
        *p4-- = extract_h(cor);
        cor = L_mac(cor, *ptr_h1, *ptr_h1);  ptr_h1++;
        *p3-- = extract_h(cor);
        cor = L_mac(cor, *ptr_h1, *ptr_h1);  ptr_h1++;
        *p2-- = extract_h(cor);
        cor = L_mac(cor, *ptr_h1, *ptr_h1);  ptr_h1++;
        *p1-- = extract_h(cor);
        cor = L_mac(cor, *ptr_h1, *ptr_h1);  ptr_h1++;
        *p0-- = extract_h(cor);
    }

    /* Divide all elements of rrixix[][] by 2. */
    p0 = &rrixix[0][0];
    for(i=0; i<L_SUBFR; i++) 
    {
      *p0 = shr(*p0, 1);
      p0++;
    }

    /*------------------------------------------------------------*
    * Compute rrixiy[][] needed for the codebook search.         *
    * This algorithm compute correlation between 2 pulses        *
    * (2 impulses responses) in 5 possible adjacents tracks.     *
    * (track 0-1, 1-2, 2-3, 3-4 and 4-0).   Total = 5x8x8 = 320. *
    *------------------------------------------------------------*/
    /* storage order --> i3i4, i2i3, i1i2, i0i1, i4i0 */
    pos = MSIZE-1;
    ptr_hf = h + 1;
    for(k=0; k<NB_POS; k++) {
        p4 = &rrixiy[3][pos];
        p3 = &rrixiy[2][pos];
        p2 = &rrixiy[1][pos];
        p1 = &rrixiy[0][pos];
        p0 = &rrixiy[4][pos-NB_POS];
        cor = 0x00008000L;            /* 0.5 (for rounding) */
        ptr_h1 = h;
        ptr_h2 = ptr_hf;
        for(i=k+(Word16)1; i<NB_POS; i++ ) {
            cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
            *p4 = extract_h(cor);
            cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
            *p3 = extract_h(cor);
            cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
            *p2 = extract_h(cor);
            cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
            *p1 = extract_h(cor);
            cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
            *p0 = extract_h(cor);
            p4 -= (NB_POS+1);
            p3 -= (NB_POS+1);
            p2 -= (NB_POS+1);
            p1 -= (NB_POS+1);
            p0 -= (NB_POS+1);
        }

        cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
        *p4 = extract_h(cor);
        cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
        *p3 = extract_h(cor);
        cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
        *p2 = extract_h(cor);
        cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
        *p1 = extract_h(cor);
        pos -= NB_POS;
        ptr_hf += STEP;
    }

    /* storage order --> i4i0, i3i4, i2i3, i1i2, i0i1 */
    pos = MSIZE-1;
    ptr_hf = h + 4;
    for(k=0; k<NB_POS; k++) {
        p4 = &rrixiy[4][pos];
        p3 = &rrixiy[3][pos-1];
        p2 = &rrixiy[2][pos-1];
        p1 = &rrixiy[1][pos-1];
        p0 = &rrixiy[0][pos-1];

        cor = 0x00008000L;            /* 0.5 (for rounding) */
        ptr_h1 = h;
        ptr_h2 = ptr_hf;
        for(i=k+(Word16)1; i<NB_POS; i++ ) {
            cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
            *p4 = extract_h(cor);
            cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
            *p3 = extract_h(cor);
            cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
            *p2 = extract_h(cor);
            cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
            *p1 = extract_h(cor);
            cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
            *p0 = extract_h(cor);

            p4 -= (NB_POS+1);
            p3 -= (NB_POS+1);
            p2 -= (NB_POS+1);
            p1 -= (NB_POS+1);
            p0 -= (NB_POS+1);
        }
        cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
        *p4 = extract_h(cor);
        pos--;
        ptr_hf += STEP;
    }

    /*------------------------------------------------------------*
    * Modification of rrixiy[][] to take signs into account.     *
    *------------------------------------------------------------*/
    p0 = &rrixiy[0][0];
    for (k=0; k<NB_TRACK; k++) {
        for(i=k; i<L_SUBFR; i+=STEP) {
            psign = sign;
            if (psign[i] < 0) psign = inv_sign;
            for(j=(Word16)((k+(Word16)1)%NB_TRACK); j<(Word16)L_SUBFR; j+=(Word16)STEP) {
                *p0 = mult(*p0, psign[j]); p0++;
            }
        }
    }

    return;
}
Example #9
0
/*-----------------------------------------------------------*
 * procedure Calc_exc_rand                                   *
 *           ~~~~~~~~~~~~~                                   *
 *   Computes comfort noise excitation                       *
 *   for SID and not-transmitted frames                      *
 *-----------------------------------------------------------*/
void Calc_exc_rand(
  Word32 L_exc_err[4],
  Word16 cur_gain,      /* (i)   :   target sample gain                 */
  Word16 *exc,          /* (i/o) :   excitation array                   */
  Word16 *seed,         /* (i)   :   current Vad decision               */
  Flag flag_cod         /* (i)   :   encoder/decoder flag               */
)
{
  Word16 i, j, i_subfr;
  Word16 temp1, temp2;
  Word16 pos[4];
  Word16 sign[4];
  Word16 t0, frac;
  Word16 *cur_exc;
  Word16 g, Gp, Gp2;
  Word16 excg[L_SUBFR], excs[L_SUBFR];
  Word32 L_acc, L_ener, L_k;
  Word16 max, hi, lo, inter_exc;
  Word16 sh;
  Word16 x1, x2;
  
  if(cur_gain == 0) {

    for(i=0; i<L_FRAME; i++) {
      exc[i] = 0;
    }
    Gp = 0;
    t0 = add(L_SUBFR,1);
    for (i_subfr = 0;  i_subfr < L_FRAME; i_subfr += L_SUBFR) {
      if(flag_cod != FLAG_DEC) update_exc_err(L_exc_err, Gp, t0);
    }

    return;
  }

  
  
  /* Loop on subframes */
  
  cur_exc = exc;
  
  for (i_subfr = 0;  i_subfr < L_FRAME; i_subfr += L_SUBFR) {

    /* generate random adaptive codebook & fixed codebook parameters */
    /*****************************************************************/
    temp1 = Random(seed);
    frac = sub((temp1 & (Word16)0x0003), 1);
    if(sub(frac, 2) == 0) frac = 0;
    temp1 = shr(temp1, 2);
    t0 = add((temp1 & (Word16)0x003F), 40);
    temp1 = shr(temp1, 6);
    temp2 = temp1 & (Word16)0x0007;
    pos[0] = add(shl(temp2, 2), temp2); /* 5 * temp2 */
    temp1 = shr(temp1, 3);
    sign[0] = temp1 & (Word16)0x0001;
    temp1 = shr(temp1, 1);
    temp2 = temp1 & (Word16)0x0007;
    temp2 = add(shl(temp2, 2), temp2);
    pos[1] = add(temp2, 1);     /* 5 * x + 1 */
    temp1 = shr(temp1, 3);
    sign[1] = temp1 & (Word16)0x0001;
    temp1 = Random(seed);
    temp2 = temp1 & (Word16)0x0007;
    temp2 = add(shl(temp2, 2), temp2);
    pos[2] = add(temp2, 2);     /* 5 * x + 2 */
    temp1 = shr(temp1, 3);
    sign[2] = temp1 & (Word16)0x0001;
    temp1 = shr(temp1, 1);
    temp2 = temp1 & (Word16)0x000F;
    pos[3] = add((temp2 & (Word16)1), 3); /* j+3*/
    temp2 = (shr(temp2, 1)) & (Word16)7;
    temp2 = add(shl(temp2, 2), temp2); /* 5i */
    pos[3] = add(pos[3], temp2);
    temp1 = shr(temp1, 4);
    sign[3] = temp1 & (Word16)0x0001;
    Gp = Random(seed) & (Word16)0x1FFF; /* < 0.5 Q14 */
    Gp2 = shl(Gp, 1);           /* Q15 */


    /* Generate gaussian excitation */
    /********************************/
    L_acc = 0L;
    for(i=0; i<L_SUBFR; i++) {
      temp1 = Gauss(seed);
      L_acc = L_mac(L_acc, temp1, temp1);
      excg[i] = temp1;
    }

/*
    Compute fact = alpha x cur_gain * sqrt(L_SUBFR / Eg)
    with Eg = SUM(i=0->39) excg[i]^2
    and alpha = 0.5
    alpha x sqrt(L_SUBFR)/2 = 1 + FRAC1
*/
    L_acc = Inv_sqrt(L_shr(L_acc,1));  /* Q30 */
    L_Extract(L_acc, &hi, &lo);
    /* cur_gain = cur_gainR << 3 */
    temp1 = mult_r(cur_gain, FRAC1);
    temp1 = add(cur_gain, temp1);
    /* <=> alpha x cur_gainR x 2^2 x sqrt(L_SUBFR) */

    L_acc = Mpy_32_16(hi, lo, temp1);   /* fact << 17 */
    sh = norm_l(L_acc);
    temp1 = extract_h(L_shl(L_acc, sh));  /* fact << (sh+1) */

    sh = sub(sh, 14);
    for(i=0; i<L_SUBFR; i++) {
      temp2 = mult_r(excg[i], temp1);
      temp2 = shr_r(temp2, sh);   /* shl if sh < 0 */
      excg[i] = temp2;
    }

    /* generate random  adaptive excitation */
    /****************************************/
    Pred_lt_3(cur_exc, t0, frac, L_SUBFR);


    /* compute adaptive + gaussian exc -> cur_exc */
    /**********************************************/
    max = 0;
    for(i=0; i<L_SUBFR; i++) {
      temp1 = mult_r(cur_exc[i], Gp2);
      temp1 = add(temp1, excg[i]); /* may overflow */
      cur_exc[i] = temp1;
      temp1 = abs_s(temp1);
      if(sub(temp1,max) > 0) max = temp1;
    }

    /* rescale cur_exc -> excs */
    if(max == 0) sh = 0;
    else {
      sh = sub(3, norm_s(max));
      if(sh <= 0) sh = 0;
    }
    for(i=0; i<L_SUBFR; i++) {
      excs[i] = shr(cur_exc[i], sh);
    }

    /* Compute fixed code gain */
    /***************************/

    /**********************************************************/
    /*** Solve EQ(X) = 4 X**2 + 2 b X + c                     */
    /**********************************************************/

    L_ener = 0L;
    for(i=0; i<L_SUBFR; i++) {
      L_ener = L_mac(L_ener, excs[i], excs[i]);
    } /* ener x 2^(-2sh + 1) */

    /* inter_exc = b >> sh */
    inter_exc = 0;
    for(i=0; i<4; i++) {
      j = pos[i];
      if(sign[i] == 0) {
        inter_exc = sub(inter_exc, excs[j]);
      }
      else {
        inter_exc = add(inter_exc, excs[j]);
      }
    }

    /* Compute k = cur_gainR x cur_gainR x L_SUBFR */
    L_acc = L_mult(cur_gain, L_SUBFR);
    L_acc = L_shr(L_acc, 6);
    temp1 = extract_l(L_acc);   /* cur_gainR x L_SUBFR x 2^(-2) */
    L_k   = L_mult(cur_gain, temp1); /* k << 2 */
    temp1 = add(1, shl(sh,1));
    L_acc = L_shr(L_k, temp1);  /* k x 2^(-2sh+1) */

    /* Compute delta = b^2 - 4 c */
    L_acc = L_sub(L_acc, L_ener); /* - 4 c x 2^(-2sh-1) */
    inter_exc = shr(inter_exc, 1);
    L_acc = L_mac(L_acc, inter_exc, inter_exc); /* 2^(-2sh-1) */
    sh = add(sh, 1);
    /* inter_exc = b x 2^(-sh) */
    /* L_acc = delta x 2^(-2sh+1) */

    if(L_acc < 0) {

      /* adaptive excitation = 0 */
      Copy(excg, cur_exc, L_SUBFR);
      temp1 = abs_s(excg[(int)pos[0]]) | abs_s(excg[(int)pos[1]]);
      temp2 = abs_s(excg[(int)pos[2]]) | abs_s(excg[(int)pos[3]]);
      temp1 = temp1 | temp2;
      sh = ((temp1 & (Word16)0x4000) == 0) ? (Word16)1 : (Word16)2;
      inter_exc = 0;
      for(i=0; i<4; i++) {
        temp1 = shr(excg[(int)pos[i]], sh);
        if(sign[i] == 0) {
          inter_exc = sub(inter_exc, temp1);
        }
        else {
          inter_exc = add(inter_exc, temp1);
        }
      } /* inter_exc = b >> sh */
      L_Extract(L_k, &hi, &lo);
      L_acc = Mpy_32_16(hi, lo, K0); /* k x (1- alpha^2) << 2 */
      temp1 = sub(shl(sh, 1), 1); /* temp1 > 0 */
      L_acc = L_shr(L_acc, temp1); /* 4k x (1 - alpha^2) << (-2sh+1) */
      L_acc = L_mac(L_acc, inter_exc, inter_exc); /* delta << (-2sh+1) */
      Gp = 0;
    }

    temp2 = Sqrt(L_acc);        /* >> sh */
    x1 = sub(temp2, inter_exc);
    x2 = negate(add(inter_exc, temp2)); /* x 2^(-sh+2) */
    if(sub(abs_s(x2),abs_s(x1)) < 0) x1 = x2;
    temp1 = sub(2, sh);
    g = shr_r(x1, temp1);       /* shl if temp1 < 0 */
    if(g >= 0) {
      if(sub(g, G_MAX) > 0) g = G_MAX;
    }
    else {
      if(add(g, G_MAX) < 0) g = negate(G_MAX);
    }

    /* Update cur_exc with ACELP excitation */
    for(i=0; i<4; i++) {
      j = pos[i];
      if(sign[i] != 0) {
        cur_exc[j] = add(cur_exc[j], g);
      }
      else {
        cur_exc[j] = sub(cur_exc[j], g);
      }
    }

    if(flag_cod != FLAG_DEC) update_exc_err(L_exc_err, Gp, t0);

    cur_exc += L_SUBFR;


  } /* end of loop on subframes */
  
  return;
}
Example #10
0
void agc(
  int16_t *sig_in,   /* (i)     : postfilter input signal  */
  int16_t *sig_out,  /* (i/o)   : postfilter output signal */
  int16_t l_trm      /* (i)     : subframe size            */
)
{
  static int16_t past_gain=4096;         /* past_gain = 1.0 (Q12) */
  int16_t i, exp;
  int16_t gain_in, gain_out, g0, gain;                     /* Q12 */
  int32_t s;

  int16_t signal[L_SUBFR];

  /* calculate gain_out with exponent */

  for(i=0; i<l_trm; i++)
    signal[i] = shr(sig_out[i], 2);

  s = 0;
  for(i=0; i<l_trm; i++)
    s = L_mac(s, signal[i], signal[i]);

  if (s == 0) {
    past_gain = 0;
    return;
  }
  exp = sub(norm_l(s), 1);
  gain_out = _round(L_shl(s, exp));

  /* calculate gain_in with exponent */

  for(i=0; i<l_trm; i++)
    signal[i] = shr(sig_in[i], 2);

  s = 0;
  for(i=0; i<l_trm; i++)
    s = L_mac(s, signal[i], signal[i]);

  if (s == 0) {
    g0 = 0;
  }
  else {
    i = norm_l(s);
    gain_in = _round(L_shl(s, i));
    exp = sub(exp, i);

   /*---------------------------------------------------*
    *  g0(Q12) = (1-AGC_FAC) * sqrt(gain_in/gain_out);  *
    *---------------------------------------------------*/

    s = L_deposit_l(div_s(gain_out,gain_in));   /* Q15 */
    s = L_shl(s, 7);           /* s(Q22) = gain_out / gain_in */
    s = L_shr(s, exp);         /* Q22, add exponent */

    /* i(Q12) = s(Q19) = 1 / sqrt(s(Q22)) */
    s = Inv_sqrt(s);           /* Q19 */
    i = _round(L_shl(s,9));     /* Q12 */

    /* g0(Q12) = i(Q12) * (1-AGC_FAC)(Q15) */
    g0 = mult(i, AGC_FAC1);       /* Q12 */
  }

  /* compute gain(n) = AGC_FAC gain(n-1) + (1-AGC_FAC)gain_in/gain_out */
  /* sig_out(n) = gain(n) sig_out(n)                                   */

  gain = past_gain;
  for(i=0; i<l_trm; i++) {
    gain = mult(gain, AGC_FAC);
    gain = add(gain, g0);
    sig_out[i] = extract_h(L_shl(L_mult(sig_out[i], gain), 3));
  }
  past_gain = gain;

  return;
}
static Word16 Lag_max(  /* o   : lag found                               */
    vadState *vadSt,    /* i/o : VAD state struct                        */
    Word32 corr[],      /* i   : correlation vector.                     */
    Word16 scal_sig[],  /* i   : scaled signal.                          */
    Word16 scal_fac,    /* i   : scaled signal factor.                   */
    Word16 scal_flag,   /* i   : if 1 use EFR compatible scaling         */
    Word16 L_frame,     /* i   : length of frame to compute pitch        */
    Word16 lag_max,     /* i   : maximum lag                             */
    Word16 lag_min,     /* i   : minimum lag                             */
    Word16 *cor_max,    /* o   : normalized correlation of selected lag  */
    Flag dtx,           /* i   : dtx flag; use dtx=1, do not use dtx=0   */
    Flag *pOverflow     /* i/o : overflow Flag                           */
)
#endif
{
    register Word16 i;
    Word16 *p;
    Word32 max;
    Word32 t0;
    Word16 max_h;
    Word16 max_l;
    Word16 ener_h;
    Word16 ener_l;
    Word16 p_max = 0; /* initialization only needed to keep gcc silent */
    Word32 L_temp;
    Word32 L_temp_2;
    Word32 L_temp_3;
    Word32  *p_corr = &corr[-lag_max];

    max = MIN_32;
    p_max = lag_max;

    for (i = lag_max; i >= lag_min; i--)
    {
        /* The negative array index is equivalent to a negative */
        /* address offset, i.e., corr[-i] == *(corr - i)        */
        if (*(p_corr++) >= max)
        {
            p_corr--;
            max = *(p_corr++);
            p_max = i;
        }
    }

    /* compute energy */

    t0 = 0;

    /* The negative array index is equivalent to a negative          */
    /* address offset, i.e., scal_sig[-p_max] == *(scal_sig - p_max) */
    p = &scal_sig[-p_max];
    for (i = (L_frame >> 2); i != 0; i--)
    {
        t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0);
        p++;
        t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0);
        p++;
        t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0);
        p++;
        t0 = amrnb_fxp_mac_16_by_16bb((Word32) * (p), (Word32) * (p), t0);
        p++;
    }

    t0 <<= 1;
    /* 1/sqrt(energy) */

    if (dtx)
    {  /* no test() call since this if is only in simulation env */
        /* check tone */
#ifdef VAD2
        *rmax = max;
        *r0 = t0;
#else
        /* check tone */
        vad_tone_detection(vadSt, max, t0, pOverflow);
#endif
    }

    t0 = Inv_sqrt(t0, pOverflow);

    if (scal_flag)
    {
        if (t0 > (Word32) 0x3fffffffL)
        {
            t0 = MAX_32;
        }
        else
        {
            t0 = t0 << 1;
        }
    }

    /* max = max/sqrt(energy)  */
    /* The following code is an inlined version of */
    /* L_Extract (max, &max_h, &max_l), i.e.       */
    /*                                             */
    /* *max_h = extract_h (max);                   */
    max_h = (Word16)(max >> 16);

    /* L_temp_2 = L_shr(max,1), which is used in      */
    /* the calculation of *max_l (see next operation) */
    L_temp_2 = max >> 1;

    /* *max_l = extract_l (L_msu (L_shr (max, 1), *max_h, 16384)); */
    L_temp_3 = (Word32)(max_h << 15);

    L_temp = L_temp_2 - L_temp_3;

    max_l = (Word16)L_temp;

    /* The following code is an inlined version of */
    /* L_Extract (t0, &ener_h, &ener_l), i.e.      */
    /*                                             */
    /* *ener_h = extract_h (t0);                   */
    ener_h = (Word16)(t0 >> 16);

    /* L_temp_2 = L_shr(t0,1), which is used in        */
    /* the calculation of *ener_l (see next operation) */

    L_temp_2 = t0 >> 1;

    L_temp_3 = (Word32)(ener_h << 15);

    L_temp = L_temp_2 - L_temp_3;

    ener_l = (Word16)L_temp;

    t0 = Mpy_32(max_h, max_l, ener_h, ener_l, pOverflow);

    if (scal_flag)
    {
        t0 = L_shr(t0, scal_fac, pOverflow);

        if (t0 > (Word32) 0X0000FFFFL)
        {
            *cor_max = MAX_16;
        }
        else if (t0 < (Word32) 0xFFFF0000L)
        {
            *cor_max = MIN_16;
        }
        else
        {
            *cor_max = (Word16)(t0 >> 1);
        }
    }
    else
    {
Example #12
0
static Word16 Lag_max ( /* o   : lag found                               */
    vadState *vadSt,    /* i/o : VAD state struct                        */
    Word32 corr[],      /* i   : correlation vector.                     */
    Word16 scal_sig[],  /* i   : scaled signal.                          */    
    Word16 scal_fac,    /* i   : scaled signal factor.                   */
    Word16 scal_flag,   /* i   : if 1 use EFR compatible scaling         */
    Word16 L_frame,     /* i   : length of frame to compute pitch        */
    Word16 lag_max,     /* i   : maximum lag                             */
    Word16 lag_min,     /* i   : minimum lag                             */
    Word16 *cor_max,    /* o   : normalized correlation of selected lag  */
    Flag dtx            /* i   : dtx flag; use dtx=1, do not use dtx=0   */
    )
#endif
{
    Word16 i, j;
    Word16 *p;
    Word32 max, t0;
    Word16 max_h, max_l, ener_h, ener_l;
    Word16 p_max = 0; /* initialization only needed to keep gcc silent */
    
    max = MIN_32;               move32 (); 
    p_max = lag_max;            move16 ();
   
    for (i = lag_max, j = (PIT_MAX-lag_max-1); i >= lag_min; i--, j--)  
    {
       test ();  
       if (L_sub (corr[-i], max) >= 0) 
       { 
          max = corr[-i];       move32 ();  
          p_max = i;            move16 ();  
       } 
    }
    
    /* compute energy */

    t0 = 0;                     move32 ();     
    p = &scal_sig[-p_max];      move16 (); 
    for (i = 0; i < L_frame; i++, p++)
    {
        t0 = L_mac (t0, *p, *p);
    }
    /* 1/sqrt(energy) */

    if (dtx)
    {  /* no test() call since this if is only in simulation env */
#ifdef VAD2
       *rmax = max;		move32();
       *r0 = t0;		move32();
#else
       /* check tone */
       vad_tone_detection (vadSt, max, t0);
#endif
    }
    
    t0 = Inv_sqrt (t0); move32 (); /* function result */

    test();
    if (scal_flag)
    {
       t0 = L_shl (t0, 1);
    }
    
    /* max = max/sqrt(energy)  */

    L_Extract (max, &max_h, &max_l);
    L_Extract (t0, &ener_h, &ener_l);

    t0 = Mpy_32 (max_h, max_l, ener_h, ener_l);
    
    test();
    if (scal_flag)
    {
      t0 = L_shr (t0, scal_fac);
      *cor_max = extract_h (L_shl (t0, 15)); /* divide by 2 */
    }
    else
    {
      *cor_max = extract_l(t0);
    }

    return (p_max);
}
Example #13
0
/*
**************************************************************************
*
*  Function    : agc
*  Purpose     : Scales the postfilter output on a subframe basis
*
**************************************************************************
*/
int agc (
    agcState *st,      /* i/o : agc state                        */
    Word16 *sig_in,    /* i   : postfilter input signal  (l_trm) */
    Word16 *sig_out,   /* i/o : postfilter output signal (l_trm) */
    Word16 agc_fac,    /* i   : AGC factor                       */
    Word16 l_trm       /* i   : subframe size                    */
)
{
    Word16 i, exp;
    Word16 gain_in, gain_out, g0, gain;
    Word32 s;
            
    /* calculate gain_out with exponent */
    s = energy_new(sig_out, l_trm);  /* function result */
        
     
    if (s == 0)
    {
        st->past_gain = 0;           
        return 0;
    }
    exp = sub (norm_l (s), 1);
    gain_out = round (L_shl (s, exp));

    /* calculate gain_in with exponent */
    s = energy_new(sig_in, l_trm);    /* function result */
    
     
    if (s == 0)
    {
        g0 = 0;                  
    }
    else
    {
        i = norm_l (s);
        gain_in = round (L_shl (s, i));
        exp = sub (exp, i);

        /*---------------------------------------------------*
         *  g0 = (1-agc_fac) * sqrt(gain_in/gain_out);       *
         *---------------------------------------------------*/

        s = L_deposit_l (div_s (gain_out, gain_in));
        s = L_shl (s, 7);       /* s = gain_out / gain_in */
        s = L_shr (s, exp);     /* add exponent */

        s = Inv_sqrt (s);  /* function result */
        i = round (L_shl (s, 9));

        /* g0 = i * (1-agc_fac) */
        g0 = mult (i, sub (32767, agc_fac));
    }

    /* compute gain[n] = agc_fac * gain[n-1]
                        + (1-agc_fac) * sqrt(gain_in/gain_out) */
    /* sig_out[n] = gain[n] * sig_out[n]                        */

    gain = st->past_gain;            

    for (i = 0; i < l_trm; i++)
    {
        gain = mult (gain, agc_fac);
        gain = add (gain, g0);
        sig_out[i] = extract_h (L_shl (L_mult (sig_out[i], gain), 3));
                                 
    }

    st->past_gain = gain;            

    return 0;
}
Example #14
0
void set_sign12k2(
    Word16 dn[],        /* i/o : correlation between target and h[]         */
    Word16 cn[],        /* i   : residual after long term prediction        */
    Word16 sign[],      /* o   : sign of d[n]                               */
    Word16 pos_max[],   /* o   : position of maximum correlation            */
    Word16 nb_track,    /* i   : number of tracks tracks                    */
    Word16 ipos[],      /* o   : starting position for each pulse           */
    Word16 step,        /* i   : the step size in the tracks                */
    Flag   *pOverflow   /* i/o: overflow flag                               */
)
{
    Word16 i, j;
    Word16 val;
    Word16 cor;
    Word16 k_cn;
    Word16 k_dn;
    Word16 max;
    Word16 max_of_all;
    Word16 pos = 0; /* initialization only needed to keep gcc silent */
    Word16 en[L_CODE];                  /* correlation vector */
    Word32 s;
    Word32 t;
    Word32 L_temp;
    Word16 *p_cn;
    Word16 *p_dn;
    Word16 *p_sign;
    Word16 *p_en;

    /* calculate energy for normalization of cn[] and dn[] */

    s = 256;
    t = 256;
    p_cn = cn;
    p_dn = dn;      /* crosscorrelation values do not have strong peaks, so
                       scaling applied in cor_h_x (sf=2) guaranteed that the
                       mac of the energy for this vector will not overflow */

    for (i = L_CODE; i != 0; i--)
    {
        val = *(p_cn++);
        s = L_mac(s, val, val, pOverflow);
        val = *(p_dn++);
        t += ((Word32) val * val) << 1;
    }
    s = Inv_sqrt(s, pOverflow);
    k_cn = (Word16)((L_shl(s, 5, pOverflow)) >> 16);

    t = Inv_sqrt(t, pOverflow);
    k_dn = (Word16)(t >> 11);

    p_cn   = &cn[L_CODE-1];
    p_sign = &sign[L_CODE-1];
    p_en   = &en[L_CODE-1];

    for (i = L_CODE - 1; i >= 0; i--)
    {
        L_temp = ((Word32)k_cn * *(p_cn--)) << 1;
        val = dn[i];
        s = L_mac(L_temp, k_dn, val, pOverflow);
        L_temp = L_shl(s, 10, pOverflow);
        cor = pv_round(L_temp, pOverflow);

        if (cor >= 0)
        {
            *(p_sign--) = 32767;                      /* sign = +1 */
        }
        else
        {
            *(p_sign--) = -32767;                     /* sign = -1 */
            cor = - (cor);

            /* modify dn[] according to the fixed sign */
            dn[i] = - val;
        }

        *(p_en--) = cor;
    }

    max_of_all = -1;
    for (i = 0; i < nb_track; i++)
    {
        max = -1;

        for (j = i; j < L_CODE; j += step)
        {
            cor = en[j];
            if (cor > max)
            {
                max = cor;
                pos = j;
            }
        }
        /* store maximum correlation position */
        pos_max[i] = pos;
        if (max > max_of_all)
        {
            max_of_all = max;
            /* starting position for i0 */
            ipos[0] = i;
        }
    }

    /*----------------------------------------------------------------*
     *     Set starting position of each pulse.                       *
     *----------------------------------------------------------------*/

    pos = ipos[0];
    ipos[nb_track] = pos;

    for (i = 1; i < nb_track; i++)
    {
        pos++;

        if (pos >= nb_track)
        {
            pos = 0;
        }
        ipos[ i] = pos;
        ipos[ i + nb_track] = pos;
    }

    return;
}