Ejemplo n.º 1
0
Word16 block_norm (Word16 * in, Word16 * out, Word16 length, Word16 headroom)
{

	Word16 i, max, scnt, adata;

        max = abs_s(in[0]);
	for (i = 1; i < length; i++)
	{
                adata = abs_s(in[i]);                           test();
		if (sub(adata, max) > 0)
		{
			max = adata;				move16();
		}
	}
	test();
	if (max != 0)
	{
		scnt = sub(norm_s(max), headroom);
		for (i = 0; i < length; i++)
		{
			out[i] = shl(in[i], scnt);	       	move16();
		}
	}
	else
	{
		scnt = sub(16, headroom);
		for (i = 0; i < length; i++)
		{
			out[i] = 0;                             move16();
		}
	}
	return (scnt);
}
Ejemplo n.º 2
0
long interpolation_cos129( short freq )
{
    short  sin_data,cos_data,count,temp ;
    long  Ltemp,Lresult;


    /* cos(x)=cos(a)+(x-a)sin(a)-pow((a-x),2)*cos(a) */

    count=shr(abs_s(freq ),7 );

    temp=sub( extract_l(L_mult( count,64)) , freq );
    /* (a-x)sin a  */
    /* Scale factor for (a-x): 3217=pi2/64 */

    sin_data=sin129_table [ count];
    cos_data=cos129_table [count];

    Ltemp=L_mpy_ls(L_mult(3217,temp),sin_data);

    /* (a-x) sin(a) - [(a-x)*(a-x)*cos(a)] /2 */
    /* Scale factor for (a-x)*(a-x):  20213=pi2*pi2/64 */

    Ltemp=L_sub(Ltemp,
                L_mpy_ls(L_mult(mult_r(10106,temp),temp),cos_data));

    /* Scaled up by 64/2 times */
    Ltemp=L_shl( Ltemp ,6 );
    Lresult=  L_add(L_deposit_h(cos_data), (Ltemp)) ;

    return(Lresult);
}
Ejemplo n.º 3
0
void Cor_h_X(
    Word16 h[],        /* (i) Q12 :Impulse response of filters      */
    Word16 X[],        /* (i)     :Target vector                    */
    Word16 D[]         /* (o)     :Correlations between h[] and D[] */
    /*          Normalized to 13 bits            */
)
{
    Word16 i, j;
    Word32 s, max, L_temp;
    Word32 y32[L_SUBFR];

    /* first keep the result on 32 bits and find absolute maximum */

    max = 0;

    for (i = 0; i < L_SUBFR; i++)
    {
        s = 0;
        for (j = i; j <  L_SUBFR; j++)
            s = L_mac(s, X[j], h[j-i]);

        y32[i] = s;

        s = L_abs(s);
        L_temp =L_sub(s,max);
        if(L_temp>0L) {
            max = s;
        }
    }

    /* Find the number of right shifts to do on y32[]  */
    /* so that maximum is on 13 bits                   */

    j = norm_l(max);
    if( sub(j,16) > 0) {
        j = 16;
    }

    j = sub(18, j);

    if(j>=0)
    {
        for(i=0; i<L_SUBFR; i++) {
            D[i] = extract_l( L_shr(y32[i], j) );
        }
    }
    else
    {
        Word16 pj = abs_s(j);
        for(i=0; i<L_SUBFR; i++) {
            D[i] = extract_l( L_shr(y32[i], pj) );
        }
    }

    return;

}
Ejemplo n.º 4
0
/*----------------------------------------------------------------------------
 * calc_rc0_h - computes 1st parcor from composed filter impulse response
 *----------------------------------------------------------------------------
 */
static void calc_rc0_he(
 Word16 *h,      /* input : impulse response of composed filter */
 Word16 *rc0,     /* output: 1st parcor */
  Word16  long_h_st  /*input : impulse response length */
)
{
    Word16 acf0, acf1;
    Word32 L_acc;
    Word16 temp, sh_acf;
    Word16 *ptrs;
    Word16 i;


    /* computation of the autocorrelation function acf */
    L_acc  = 0L;
    for(i=0; i<long_h_st; i++) L_acc = L_mac(L_acc, h[i], h[i]);
    sh_acf = norm_l(L_acc);
    L_acc  = L_shl(L_acc, sh_acf);
    acf0   = extract_h(L_acc);

    L_acc  = 0L;
    ptrs   = h;
    for(i=0; i<long_h_st-1; i++){
        temp = *ptrs++;
        L_acc = L_mac(L_acc, temp, *ptrs);
    }
    L_acc = L_shl(L_acc, sh_acf);
    acf1  = extract_h(L_acc);

    /* Compute 1st parcor */
    /**********************/
    if( sub(acf0, abs_s(acf1))<0) {
        *rc0 = 0;
        return;
    }
    *rc0 = div_s(abs_s(acf1), acf0);
    if(acf1 > 0) {
        *rc0 = negate(*rc0);
    }

    return;
}
Ejemplo n.º 5
0
/*----------------------------------------------------------------------------
 * filt_mu - tilt filtering with : (1 + mu z-1) * (1/1-|mu|)
 *   computes y[n] = (1/1-|mu|) (x[n]+mu*x[n-1])
 *----------------------------------------------------------------------------
 */
static void filt_mu(
    Word16 *sig_in,     /* input : input signal (beginning at sample -1) */
    Word16 *sig_out,    /* output: output signal */
    Word16 parcor0      /* input : parcor0 (mu = parcor0 * gamma3) */
)
{
    int n;
    Word16 mu, mu2, ga, temp;
    Word32 L_acc, L_temp, L_fact;
    Word16 fact, sh_fact1;
    Word16 *ptrs;

    if(parcor0 > 0) {
        mu      = mult_r(parcor0, GAMMA3_PLUS);
        /* GAMMA3_PLUS < 0.5 */
        sh_fact1 = 15;                   /* sh_fact + 1 */
        fact     = (Word16)0x4000;       /* 2**sh_fact */
        L_fact   = (Word32)0x00004000L;
    }
    else {
        mu       = mult_r(parcor0, GAMMA3_MINUS);
        /* GAMMA3_MINUS < 0.9375 */
        sh_fact1 = 12;                   /* sh_fact + 1 */
        fact     = (Word16)0x0800;       /* 2**sh_fact */
        L_fact   = (Word32)0x00000800L;
    }

    temp = sub(1, abs_s(mu));
    mu2  = add(32767, temp);    /* 2**15 (1 - |mu|) */
    ga   = div_s(fact, mu2);    /* 2**sh_fact / (1 - |mu|) */

    ptrs = sig_in;     /* points on sig_in(-1) */
    mu   = shr(mu, 1);          /* to avoid overflows   */

    for(n=0; n<L_SUBFR; n++) {
        temp   = *ptrs++;
        L_temp = L_deposit_l(*ptrs);
        L_acc  = L_shl(L_temp, 15);         /* sig_in(n) * 2**15 */
        L_temp = L_mac(L_acc, mu, temp);
        L_temp = L_add(L_temp, 0x00004000L);
        temp   = extract_l(L_shr(L_temp,15));
        /* ga x temp x 2 with rounding */
        L_temp = L_add(L_mult(temp, ga),L_fact);
        L_temp = L_shr(L_temp, sh_fact1); /* mult. temp x ga */
        sig_out[n] = sature(L_temp);
    }
    return;
}
Ejemplo n.º 6
0
/*----------------------------------------------------------------------------
 *   calc_st_filt -  computes impulse response of A(gamma2) / A(gamma1)
 *   controls gain : computation of energy impulse response as
 *                    SUMn  (abs (h[n])) and computes parcor0
 *----------------------------------------------------------------------------
 */
static void calc_st_filte(
 Word16 *apond2,     /* input : coefficients of numerator */
 Word16 *apond1,     /* input : coefficients of denominator */
 Word16 *parcor0,    /* output: 1st parcor calcul. on composed filter */
 Word16 *sig_ltp_ptr,    /* in/out: input of 1/A(gamma1) : scaled by 1/g0 */
 Word16  long_h_st,     /* input : impulse response length                   */
 Word16 m_pst               /* input : LPC order    */
)
{
    Word16 h[LONG_H_ST_E];
    Word32 L_temp, L_g0;
    Word16 g0, temp;
    Word16 i;

    /* compute i.r. of composed filter apond2 / apond1 */
    Syn_filte(m_pst, apond1, apond2, h, long_h_st, mem_zero, 0);

    /* compute 1st parcor */
    calc_rc0_he(h, parcor0, long_h_st);

    /* compute g0 */
    L_g0 = 0L;
    for(i=0; i<long_h_st; i++) {
        L_temp = L_deposit_l(abs_s(h[i]));
        L_g0   = L_add(L_g0, L_temp);
    }
    g0 = extract_h(L_shl(L_g0, 14));

    /* Scale signal input of 1/A(gamma1) */
    if(sub(g0, 1024)>0) {
        temp = div_s(1024, g0);     /* temp = 2**15 / gain0 */
        for(i=0; i<L_SUBFR; i++) {
            sig_ltp_ptr[i] = mult_r(sig_ltp_ptr[i], temp);
        }
    }

    return;
}
Ejemplo n.º 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;
}
Ejemplo n.º 8
0
void modifyorig(short *residualm,
                short *accshift,
                short beta,
                short *dpm,
                short shiftrange,
                short resolution,
                short *TARGET,
                short *residual,
                short dp,
                short sfend)
{
    static short FirstTime = 1;
    short best;
    short tmp;
    long ex0y[(RSHIFT * 2 + 2) * RRESOLUTION + 1];	/* Fraction sampled correlation function */
    long ex0y2[RSHIFT * 2 + 2];	/* Integer sampled correlation function */
    short Residual[2 * SubFrameSize + 2 * RSHIFT + 1];
    static short a1[RRESOLUTION];
    static short a2[RRESOLUTION];
    static short a3[RRESOLUTION];
    register short i, j, k, n;
    short sfstart, length, shiftrangel, shiftranger;
    long e01, e02;
    short shft_fctr1, shft_fctr2, shft_fctr3;
    long ltmp;
    long laccshift;
    long y;

    /****** INITIALIZATION *****/
    if (FirstTime)
    {
        FirstTime = 0;

        /* Calculate interpolation coefficients */
        a1[0] = 12288;
        a1[1] = 8448;
        a1[2] = 5120;
        a1[3] = 2304;
        a1[4] = 0;
        a1[5] = -1792;
        a1[6] = -3072;
        a1[7] = -3840;

        a2[0] = 24576;
        a2[1] = 28160;
        a2[2] = 30720;
        a2[3] = 32256;
        a2[4] = 32767;
        a2[5] = 32256;
        a2[6] = 30720;
        a2[7] = 28160;

        a3[0] = -4096;
        a3[1] = -3840;
        a3[2] = -3072;
        a3[3] = -1792;
        a3[4] = 0;
        a3[5] = 2304;
        a3[6] = 5120;
        a3[7] = 8448;
    }

    /********************
    * CORRELATION MATCH *
    ********************/
    length = sub(sfend, dp);
    sfstart = dp;

    /*laccshift = L_shl(L_deposit_h(*accshift), 8); */
    laccshift = L_deposit_h(*accshift);		/* accshift scaled by 8 */
    /* Perform before if
     * * statement.
     */
    if (shiftrange != 0)
    {
        /* Limit the search range to control accshift */
        shiftrangel = shiftranger = shiftrange;
        if (*accshift < 0)
            shiftrangel = add(shiftrangel, 1);
        if (*accshift > 0)
            shiftranger = add(shiftranger, 1);

        tmp = abs_s(*accshift);
        /* For non-periodic signals */
        if ((beta < 6554 && tmp > 15 * 256) || (beta < 9830 && tmp > 30 * 256))
        {
            if (*accshift < 0)
                shiftranger = 1;
            else
                shiftrangel = 1;
        }

        if (add(shiftrangel, shr(*accshift, 8)) > 72)
        {
            shiftrangel = sub(72, shr(*accshift, 8));
            fprintf(stderr, "mdfyorig:*** Buffer limit. shiftrangel is:%d\n", shiftrangel);
        }
        if (sub(shiftranger, shr(*accshift, 8)) > 72)
        {
            shiftranger = add(72, shr(*accshift, 8));
            fprintf(stderr, "mdfyorig:*** Buffer limit. shiftranger is:%d\n", shiftranger);
        }

        /* Create a buffer of modify residual for match at low cut-off frequency */
        tmp = add(length, shiftrangel);
        tmp = add(tmp, shiftranger);

        ltmp = L_deposit_h(add(*accshift, shl(shiftrangel, 8)));
        for (i = 0; i <= tmp; i++)
        {
            /* POINTER ADDITION NOT CONVERTED -- NEED UNSIGNED ADDITION */
            bl_intrp(Residual + i, residual + dp + i, ltmp, 16384, 3);
        }

        tmp = add(shiftrangel, shiftranger);

        /* Search for all integer delays of residual */
        for (n = 0; n <= tmp; n++)
        {
            ex0y2[n] = 0;
            for (i = 0; i < length; i++)
            {
                ex0y2[n] = L_mac(ex0y2[n], Residual[n + i], TARGET[sfstart + i]);
            }
            ex0y2[n] = L_shr(ex0y2[n], 1);

        }

        /* Do quadratic interpolation of ex0y */
        for (n = 1, k = 0; n < shiftrangel + shiftranger; n++)
        {
            for (j = 0; j < resolution; j++)
            {
                ex0y[k] = L_mpy_ls(ex0y2[n - 1], a1[j]);
                ltmp = L_mpy_ls(ex0y2[n], a2[j]);
                ex0y[k] = L_add(ex0y[k], ltmp);
                ltmp = L_mpy_ls(ex0y2[n + 1], a3[j]);
                ex0y[k] = L_add(ex0y[k], ltmp);
                k++;
            }
        }

        /* Find maximum with positive correlation */
        y = 0;
        best = sub(shl(shiftrangel, 3), 4);
        for (n = 0; n < k; n++)
        {
            if (ex0y[n] > y)
            {
                y = ex0y[n];
                best = n;
            }
        }
        /* best value not very accurate since ex0y[] calculation not percise. To correct
         * Residual[] should have more percision. This error does not seem to affect the
         * final output using the test data.
         */
        /* Calculate energy in selected shift index */
        e01 = e02 = 0;
        for (i = shiftrangel; i < length + shiftrangel; i++)
            e01 = L_mac(e01, Residual[i], Residual[i]);

        for (i = 0; i < length; i++)
            e02 = L_mac(e02, TARGET[i + sfstart], TARGET[i + sfstart]);

        if (e01 == 0 || e02 == 0)
            y = 0;
        else
        {
            shft_fctr1 = norm_l(y);
            y = L_shl(y, shft_fctr1);
            y = L_mpy_ll(y, y);
            /* TO RECOVER Y VALUE:
             * y = L_shl(y, 31-2*shft_fctr1) */

            shft_fctr2 = norm_l(e01);
            e01 = L_shl(e01, shft_fctr2);

            shft_fctr3 = norm_l(e02);
            e02 = L_shl(e02, shft_fctr3);
            ltmp = L_mpy_ll(e01, e02);
            ltmp = L_mpy_ls(ltmp, 16056);

            ltmp = L_shl(ltmp, shl(shft_fctr1, 1) - add(add(2, shft_fctr2), shft_fctr3));

            if (y > ltmp)
            {
                /*tmp = shl(shr(*accshift,8) + shiftrangel, 3) - (best + 4); */
                tmp = *accshift + shl(shiftrangel, 8) - shl((best + 4), 5);
                *accshift = tmp;
                laccshift = L_deposit_h(tmp);
                /**accshift = shift_r(tmp, -3);*/
                /*
                 * if (laccshift == -75497472)
                 * laccshift = -88080384;
                 */
            }
        }
    }

    for (k = 0; k < length; k++)
    {
        bl_intrp(residualm + dp + k, residual + dp + k, laccshift, BLFREQ, BLPRECISION);

    }

    *dpm = add(dp, length);

}
Ejemplo n.º 9
0
void track_pit( Word16 *T0,         /* I/O  Integer pitch delay */
                Word16 *T0_frac,     /* I/O  Non integer correction */
                Word16 *prev_pitch, /* I/O  previous pitch delay */
                Word16 *stat_pitch, /* I/O  pitch stationnarity indicator */
                Word16 *pitch_sta,  /* I/O  stationnary integer pitch delay */
                Word16 *frac_sta    /* I/O  stationnary fractional pitch */
)

{

    Word16 dist, dist_min, pitch_mult, temp;
    Word16     j, flag_mult;

    dist = sub(*T0, *prev_pitch);
    if(dist < 0) {
        flag_mult = 0;
        dist = negate(dist);
    }
    else {
        flag_mult = 1;
    }
    /* ------------------------ */
    /* Test pitch stationnarity */
    /* ------------------------ */

    if (dist < 5) {
      *stat_pitch += 1;
      if (*stat_pitch > 7) *stat_pitch = 7 ;
      *pitch_sta = *T0;
      *frac_sta = *T0_frac;
    }
    else {

      /* ------------------------------- */
      /* Find multiples or sub-multiples */
      /* ------------------------------- */
        dist_min =  dist;
        if( flag_mult == 0) {
            pitch_mult = add(*T0, *T0);
            for (j=2; j<5; j++) {
                dist = abs_s(sub(pitch_mult, *prev_pitch));
                temp = sub(dist, dist_min);
                if (temp <= 0) {
                    dist_min = dist;
                }
                pitch_mult = add(*T0, pitch_mult);
            }
        }
        else {
            pitch_mult = add(*prev_pitch, *prev_pitch);
            for (j=2; j<5; j++) {
                dist = abs_s(sub(pitch_mult, *T0));
                temp = sub(dist, dist_min);
                if (temp <= 0) {
                    dist_min = dist;
                }
                pitch_mult = add(*prev_pitch, pitch_mult);
            }
        }
        if (dist_min < 5) {   /* Multiple or sub-multiple detected */
            if (*stat_pitch > 0) {
                *T0 = *pitch_sta;
                *T0_frac = *frac_sta;
            }
            *stat_pitch -= 1;
            if (*stat_pitch < 0) *stat_pitch = 0 ;
        }
        else {
            *stat_pitch = 0;    /* No (sub-)multiple detected  => Pitch transition */
            *pitch_sta = *T0;
            *frac_sta = *T0_frac;
        }
    }

    *prev_pitch = *T0;

    return;
}
Ejemplo n.º 10
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;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
void pit_pst_filt(
  Word16 *signal,      /* (i)     : input signal                        */
  Word16 *scal_sig,    /* (i)     : input signal (scaled, divided by 4) */
  Word16 t0_min,       /* (i)     : minimum value in the searched range */
  Word16 t0_max,       /* (i)     : maximum value in the searched range */
  Word16 L_subfr,      /* (i)     : size of filtering                   */
  Word16 *signal_pst   /* (o)     : harmonically postfiltered signal    */
)
{
  Word16 i, j, t0;
  Word16 g0, gain, cmax, en, en0;
  Word16 *p, *p1, *deb_sig;
  Word32 corr, cor_max, ener, ener0, temp;
  Word32 L_temp;

/*---------------------------------------------------------------------------*
 * Compute the correlations for all delays                                   *
 * and select the delay which maximizes the correlation                      *
 *---------------------------------------------------------------------------*/

  deb_sig = &scal_sig[-t0_min];
  cor_max = MIN_32;
  t0 = t0_min;             /* Only to remove warning from some compilers */
  for (i=t0_min; i<=t0_max; i++)
  {
    corr = 0;
    p    = scal_sig;
    p1   = deb_sig;
    for (j=0; j<L_subfr; j++)
       corr = L_mac(corr, *p++, *p1++);

    L_temp = L_sub(corr, cor_max);
    if (L_temp > (Word32)0)
    {
      cor_max = corr;
      t0 = i;
    }
    deb_sig--;
  }

  /* Compute the energy of the signal delayed by t0 */

  ener = 1;
  p = scal_sig - t0;
  for ( i=0; i<L_subfr ;i++, p++)
    ener = L_mac(ener, *p, *p);

  /* Compute the signal energy in the present subframe */

  ener0 = 1;
  p = scal_sig;
  for ( i=0; i<L_subfr; i++, p++)
    ener0 = L_mac(ener0, *p, *p);

  if (cor_max < 0)
  {
    cor_max = 0;
  }

  /* scale "cor_max", "ener" and "ener0" on 16 bits */

  temp = cor_max;
  if (ener > temp)
  {
    temp = ener;
  }
  if (ener0 > temp)
  {
    temp = ener0;
  }
  j = norm_l(temp);
  if(j>0)
  {
  cmax = round(L_shl(cor_max, j));
  en = round(L_shl(ener, j));
  en0 = round(L_shl(ener0, j));
  }
  else
  {
  	Word16 pj = abs_s(j);
  	cmax = round(L_shr(cor_max, pj));	
  	en = round(L_shr(ener, pj));
  	en0 = round(L_shr(ener0, pj));
  }
  /* prediction gain (dB)= -10 log(1-cor_max*cor_max/(ener*ener0)) */

  /* temp = (cor_max * cor_max) - (0.5 * ener * ener0)  */
  temp = L_mult(cmax, cmax);
  temp = L_sub(temp, L_shr(L_mult(en, en0), 1));

  if (temp < (Word32)0)           /* if prediction gain < 3 dB   */
  {                               /* switch off pitch postfilter */
    for (i = 0; i < L_subfr; i++)
      signal_pst[i] = signal[i];
    return;
  }

  if (sub(cmax, en) > 0)      /* if pitch gain > 1 */
  {
    g0 = INV_GAMMAP;
    gain = GAMMAP_2;
  }
  else {
    cmax = shr(mult(cmax, GAMMAP), 1);  /* cmax(Q14) = cmax(Q15) * GAMMAP */
    en = shr(en, 1);          /* Q14 */
    i = add(cmax, en);
    if(i > 0)
    {
      gain = div_s(cmax, i);    /* gain(Q15) = cor_max/(cor_max+ener)  */
      g0 = sub(32767, gain);    /* g0(Q15) = 1 - gain */
    }
    else
    {
      g0 =  32767;
      gain = 0;
    }
  }


  for (i = 0; i < L_subfr; i++)
  {
    /* signal_pst[i] = g0*signal[i] + gain*signal[i-t0]; */

    signal_pst[i] = add(mult(g0, signal[i]), mult(gain, signal[i-t0]));

  }

  return;
}
Ejemplo n.º 13
0
void Az_lsp(
  Word16 a[],        /* (i) Q12 : predictor coefficients              */
  Word16 lsp[],      /* (o) Q15 : line spectral pairs                 */
  Word16 old_lsp[]   /* (i)     : old lsp[] (in case not found 10 roots) */
)
{
 Word16 i, j, nf, ip;
 Word16 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
 Word16 x, y, sign, exp;
 Word16 *coef;
 Word16 f1[M/2+1], f2[M/2+1];
 Word32 t0, L_temp;
 Flag   ovf_coef;
 Word16 (*pChebps)(Word16 x, Word16 f[], Word16 n);

/*-------------------------------------------------------------*
 *  find the sum and diff. pol. F1(z) and F2(z)                *
 *    F1(z) <--- F1(z)/(1+z**-1) & F2(z) <--- F2(z)/(1-z**-1)  *
 *                                                             *
 * f1[0] = 1.0;                                                *
 * f2[0] = 1.0;                                                *
 *                                                             *
 * for (i = 0; i< NC; i++)                                     *
 * {                                                           *
 *   f1[i+1] = a[i+1] + a[M-i] - f1[i] ;                       *
 *   f2[i+1] = a[i+1] - a[M-i] + f2[i] ;                       *
 * }                                                           *
 *-------------------------------------------------------------*/

 ovf_coef = 0;
 pChebps = Chebps_11;

 f1[0] = 2048;          /* f1[0] = 1.0 is in Q11 */
 f2[0] = 2048;          /* f2[0] = 1.0 is in Q11 */

 for (i = 0; i< NC; i++)
 {
   Overflow = 0;
   t0 = L_mult(a[i+1], 16384);          /* x = (a[i+1] + a[M-i]) >> 1        */
   t0 = L_mac(t0, a[M-i], 16384);       /*    -> From Q12 to Q11             */
   x  = extract_h(t0);
   if ( Overflow ) {
     ovf_coef = 1;      }

   Overflow = 0;
   f1[i+1] = sub(x, f1[i]);    /* f1[i+1] = a[i+1] + a[M-i] - f1[i] */
   if ( Overflow ) {
     ovf_coef = 1;      }

   Overflow = 0;
   t0 = L_mult(a[i+1], 16384);          /* x = (a[i+1] - a[M-i]) >> 1        */
   t0 = L_msu(t0, a[M-i], 16384);       /*    -> From Q12 to Q11             */
   x  = extract_h(t0);
   if ( Overflow ) {
     ovf_coef = 1;      }

   Overflow = 0;
   f2[i+1] = add(x, f2[i]);    /* f2[i+1] = a[i+1] - a[M-i] + f2[i] */
   if ( Overflow ) {
     ovf_coef = 1;      }
 }

 if ( ovf_coef ) {
   /*printf("===== OVF ovf_coef =====\n");*/

   pChebps = Chebps_10;

   f1[0] = 1024;          /* f1[0] = 1.0 is in Q10 */
   f2[0] = 1024;          /* f2[0] = 1.0 is in Q10 */

   for (i = 0; i< NC; i++)
   {
     t0 = L_mult(a[i+1], 8192);          /* x = (a[i+1] + a[M-i]) >> 1        */
     t0 = L_mac(t0, a[M-i], 8192);       /*    -> From Q11 to Q10             */
     x  = extract_h(t0);
     f1[i+1] = sub(x, f1[i]);    /* f1[i+1] = a[i+1] + a[M-i] - f1[i] */

     t0 = L_mult(a[i+1], 8192);          /* x = (a[i+1] - a[M-i]) >> 1        */
     t0 = L_msu(t0, a[M-i], 8192);       /*    -> From Q11 to Q10             */
     x  = extract_h(t0);
     f2[i+1] = add(x, f2[i]);    /* f2[i+1] = a[i+1] - a[M-i] + f2[i] */
   }
 }

/*-------------------------------------------------------------*
 * find the LSPs using the Chebichev pol. evaluation           *
 *-------------------------------------------------------------*/

 nf=0;          /* number of found frequencies */
 ip=0;          /* indicator for f1 or f2      */

 coef = f1;

 xlow = grid[0];
 ylow = (*pChebps)(xlow, coef, NC);

 j = 0;
 while ( (nf < M) && (j < GRID_POINTS) )
 {
   j =add(j,1);
   xhigh = xlow;
   yhigh = ylow;
   xlow  = grid[j];
   ylow  = (*pChebps)(xlow,coef,NC);

   L_temp = L_mult(ylow ,yhigh);
   if ( L_temp <= (Word32)0)
   {

     /* divide 4 times the interval */

     for (i = 0; i < 4; i++)
     {
       xmid = add( shr(xlow, 1) , shr(xhigh, 1)); /* xmid = (xlow + xhigh)/2 */

       ymid = (*pChebps)(xmid,coef,NC);

       L_temp = L_mult(ylow,ymid);
       if ( L_temp <= (Word32)0)
       {
         yhigh = ymid;
         xhigh = xmid;
       }
       else
       {
         ylow = ymid;
         xlow = xmid;
       }
     }

    /*-------------------------------------------------------------*
     * Linear interpolation                                        *
     *    xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow);            *
     *-------------------------------------------------------------*/

     x   = sub(xhigh, xlow);
     y   = sub(yhigh, ylow);

     if(y == 0)
     {
       xint = xlow;
     }
     else
     {
       sign= y;
       y   = abs_s(y);
       exp = norm_s(y);
       y   = shl(y, exp);
       y   = div_s( (Word16)16383, y);
       t0  = L_mult(x, y);
       t0  = L_shr(t0, sub(20, exp) );
       y   = extract_l(t0);            /* y= (xhigh-xlow)/(yhigh-ylow) in Q11 */

       if(sign < 0) y = negate(y);

       t0   = L_mult(ylow, y);                  /* result in Q26 */
       t0   = L_shr(t0, 11);                    /* result in Q15 */
       xint = sub(xlow, extract_l(t0));         /* xint = xlow - ylow*y */
     }

     lsp[nf] = xint;
     xlow    = xint;
     nf =add(nf,1);

     if(ip == 0)
     {
       ip = 1;
       coef = f2;
     }
     else
     {
       ip = 0;
       coef = f1;
     }
     ylow = (*pChebps)(xlow,coef,NC);

   }
 }

 /* Check if M roots found */

 if( sub(nf, M) < 0)
 {
    for(i=0; i<M; i++)
    {
      lsp[i] = old_lsp[i];
    }

 /* printf("\n !!Not 10 roots found in Az_lsp()!!!\n"); */
 }

 return;
}
Ejemplo n.º 14
0
/*******************************************************************************
*
* functionname: scfCount
* returns     : ---
* description : count bits used by scalefactors.
*
********************************************************************************/
static void scfCount(const Word16 *scalefacGain,
                     const UWord16 *maxValueInSfb,
                     SECTION_DATA * sectionData)

{
  SECTION_INFO *psectionInfo;
  SECTION_INFO *psectionInfom;

  /* counter */
  Word32 i = 0; /* section counter */
  Word32 j = 0; /* sfb counter */
  Word32 k = 0; /* current section auxiliary counter */
  Word32 m = 0; /* other section auxiliary counter */
  Word32 n = 0; /* other sfb auxiliary counter */

  /* further variables */
  Word32 lastValScf     = 0;
  Word32 deltaScf       = 0;
  Flag found            = 0;
  Word32 scfSkipCounter = 0;


  sectionData->scalefacBits = 0;


  if (scalefacGain == NULL) {
    return;
  }

  lastValScf = 0;
  sectionData->firstScf = 0;

  psectionInfo = sectionData->sectionInfo;
  for (i=0; i<sectionData->noOfSections; i++) {

    if (psectionInfo->codeBook != CODE_BOOK_ZERO_NO) {
      sectionData->firstScf = psectionInfo->sfbStart;
      lastValScf = scalefacGain[sectionData->firstScf];
      break;
    }
	psectionInfo += 1;
  }

  psectionInfo = sectionData->sectionInfo;
  for (i=0; i<sectionData->noOfSections; i++, psectionInfo += 1) {

    if (psectionInfo->codeBook != CODE_BOOK_ZERO_NO
        && psectionInfo->codeBook != CODE_BOOK_PNS_NO) {
      for (j = psectionInfo->sfbStart;
           j < (psectionInfo->sfbStart + psectionInfo->sfbCnt); j++) {
        /* check if we can repeat the last value to save bits */

        if (maxValueInSfb[j] == 0) {
          found = 0;

          if (scfSkipCounter == 0) {
            /* end of section */

            if (j - ((psectionInfo->sfbStart + psectionInfo->sfbCnt) - 1) == 0) {
              found = 0;
            }
            else {
              for (k = j + 1; k < psectionInfo->sfbStart + psectionInfo->sfbCnt; k++) {

                if (maxValueInSfb[k] != 0) {
                  int tmp = L_abs(scalefacGain[k] - lastValScf);
				  found = 1;

                  if ( tmp < CODE_BOOK_SCF_LAV) {
                    /* save bits */
                    deltaScf = 0;
                  }
                  else {
                    /* do not save bits */
                    deltaScf = lastValScf - scalefacGain[j];
                    lastValScf = scalefacGain[j];
                    scfSkipCounter = 0;
                  }
                  break;
                }
                /* count scalefactor skip */
                scfSkipCounter = scfSkipCounter + 1;
              }
            }

			psectionInfom = psectionInfo + 1;
            /* search for the next maxValueInSfb[] != 0 in all other sections */
            for (m = i + 1; (m < sectionData->noOfSections) && (found == 0); m++) {

              if ((psectionInfom->codeBook != CODE_BOOK_ZERO_NO) &&
                  (psectionInfom->codeBook != CODE_BOOK_PNS_NO)) {
                for (n = psectionInfom->sfbStart;
                     n < (psectionInfom->sfbStart + psectionInfom->sfbCnt); n++) {

                  if (maxValueInSfb[n] != 0) {
                    found = 1;

                    if ( (abs_s(scalefacGain[n] - lastValScf) < CODE_BOOK_SCF_LAV)) {
                      deltaScf = 0;
                    }
                    else {
                      deltaScf = (lastValScf - scalefacGain[j]);
                      lastValScf = scalefacGain[j];
                      scfSkipCounter = 0;
                    }
                    break;
                  }
                  /* count scalefactor skip */
                  scfSkipCounter = scfSkipCounter + 1;
                }
              }

			  psectionInfom += 1;
            }

            if (found == 0) {
              deltaScf = 0;
              scfSkipCounter = 0;
            }
          }
          else {
            deltaScf = 0;
            scfSkipCounter = scfSkipCounter - 1;
          }
        }
        else {
          deltaScf = lastValScf - scalefacGain[j];
          lastValScf = scalefacGain[j];
        }
        sectionData->scalefacBits += bitCountScalefactorDelta(deltaScf);
      }
    }
  }
}
Ejemplo n.º 15
0
Word16 coarsepitch(
                   Word16  *xw,           /* (i) (normalized) weighted signal */
                   struct BV16_Encoder_State *cstate) /* (i/o) Coder State */
{
   
   Word16   s;    /* Q2 */
   Word16   a, b; 
   Word16   im;
   Word16   maxdev, flag, mpflag;
   Word32   eni, deltae;
   Word32   cc;
   Word16   ah,al, bh, bl;
   Word32   a0, a1, a2, a3;
   Word32   *lp0; 
   Word16   exp, new_exp;  
   Word16   *fp0, *fp1, *fp2, *fp3, *sp; 
   Word16   *fp1_h, *fp1_l, *fp2_h, *fp2_l;
   Word16   cor2max, cor2max_exp;
   Word16   cor2m, cor2m_exp;
   Word16   s0, t0, t1, exp0, exp1, e2, e3;
   Word16   threshold;
   Word16   mplth;      /* Q2 */
   Word16   i, j, k, n, npeaks, imax, idx[MAXPPD-MINPPD+1];
   Word16   cpp;
   Word16 plag[HMAXPPD], cor2[MAXPPD1], cor2_exp[MAXPPD1];
   Word16 cor2i[HMAXPPD], cor2i_exp[HMAXPPD], xwd[LXD];
   Word16 tmp_h[DFO+FRSZ], tmp_l[DFO+FRSZ]; /* DPF Q7 */
   Word32 cor[MAXPPD1], energy[MAXPPD1], lxwd[FRSZD];
   Word16 energy_man[MAXPPD1], energy_exp[MAXPPD1];
   Word16 energyi_man[HMAXPPD], energyi_exp[HMAXPPD];
   Word16 energym_man, energym_exp;
   Word16 energymax_man, energymax_exp;
      
   /* Lowpass filter xw() to 800 hz; shift & output into xwd() */
   
   /* AP and AZ filtering and decimation */
   
   fp1_h = tmp_h + DFO;
   fp1_l = tmp_l + DFO;
   
   sp = xw;
   a1 = 1;
   
   
   for (i=0;i<DFO;i++) tmp_h[i] = cstate->dfm_h[2*i+1];
   for (i=0;i<DFO;i++) tmp_l[i] = cstate->dfm_h[2*i];
   
   lp0 = lxwd;
   
   for (i=0;i<FRSZD;i++) {
      for (k=0;k<DECF;k++) {
         a0 = L_shr(L_deposit_h(*sp++),10);
         fp2_h = fp1_h-1;
         fp2_l = fp1_l-1;
         for (j=0;j<DFO;j++)  
            a0=L_sub(a0,Mpy_32(*fp2_h--,*fp2_l--,adf_h[j+1],adf_l[j+1]));
         a0 = L_shl(a0, 2);             /* adf Q13 */
         L_Extract(a0, fp1_h++, fp1_l++);
      }
      fp2_h = fp1_h-1;
      fp2_l = fp1_l-1;
      a0 = Mpy_32_16(*fp2_h--, *fp2_l--, bdf[0]);
      for (j=0;j<DFO;j++)
         a0=L_add(a0,Mpy_32_16(*fp2_h--,*fp2_l--,bdf[j+1]));
      
      *lp0++ = a0;
      a0 = L_abs(a0);
      
      if (a1 < a0) 
         a1 = a0;
   }
   
   /* copy temp buffer to memory */
   fp1_h -= DFO;
   fp1_l -= DFO;
   for (i=0;i<DFO;i++) {
      cstate->dfm_h[2*i+1] = fp1_h[i];
      cstate->dfm_h[2*i] = fp1_l[i];
   }
   
   lp0 = lxwd;
   new_exp = sub(norm_l(a1), 3);       /* headroom to avoid overflow */
   exp = sub(cstate->xwd_exp,new_exp); /* increase in bit-resolution */
   
   if (exp < 0) { /* Descending signal level */
      new_exp = cstate->xwd_exp;
      exp = 0;
   }
   
   for (i=0;i<XDOFF;i++) 
      xwd[i] = shr(cstate->xwd[i], exp);
   
   /* fill-in new exponent */
   fp0 = xwd + XDOFF;
   for (i=0;i<FRSZD;i++) 
      fp0[i] = intround(L_shl(lp0[i],new_exp));
   
   /* update signal memory for next frame */
   exp0 = 1;
   for (i=0;i<XDOFF;i++) {
      exp1 = abs_s(xwd[FRSZD+i]);
      
      if (exp1 > exp0) 
         exp0 = exp1;
   }
   exp0 = sub(norm_s(exp0),3); /* extra exponent for next frame */
   
   exp = sub(exp0, exp);
   
   if (exp >=0)
   {
      for (i=0;i<XDOFF-FRSZD;i++)  
         cstate->xwd[i] = shl(cstate->xwd[i+FRSZD], exp);
   }
   else
   {
      exp = -exp;
      if (exp >=15)
         exp = 15;
      for (i=0;i<XDOFF-FRSZD;i++)  
         cstate->xwd[i] = shr(cstate->xwd[i+FRSZD], exp);
   }
   for (;i<XDOFF;i++) 
      cstate->xwd[i] = shl(xwd[FRSZD+i],exp0);
   
   
   cstate->xwd_exp = add(new_exp, exp0);
   
   /* Compute correlation & energy of prediction basis vector */
   
   /* reset local buffers */
   for (i=0;i<MAXPPD1;i++) 
      cor[i] = energy[i] = 0;
   
   fp0 = xwd+MAXPPD1;
   fp1 = xwd+MAXPPD1-M1;
   a0 = a1 = 0; 
   for (i=0;i<(LXD-MAXPPD1);i++) {
      a0 = L_mac0(a0, *fp1, *fp1);
      a1 = L_mac0(a1, *fp0++, *fp1++);
   }
   cor[M1-1] = a1;
   energy[M1-1] = a0;
   energy_exp[M1-1] = norm_l(energy[M1-1]);
   energy_man[M1-1] = extract_h(L_shl(energy[M1-1], energy_exp[M1-1]));
   s0 = cor2_exp[M1-1] = norm_l(a1);
   t0 = extract_h(L_shl(a1, s0));
   cor2[M1-1] = extract_h(L_mult(t0, t0));
   
   if (a1 < 0) 
      cor2[M1-1] = negate(cor2[M1-1]);
   
   fp2 = xwd+LXD-M1-1;
   fp3 = xwd+MAXPPD1-M1-1;
   for (i=M1;i<M2;i++) {
      fp0 = xwd+MAXPPD1;
      fp1 = xwd+MAXPPD1-i-1;
      a1 = 0;
      for (j=0;j<(LXD-MAXPPD1);j++) 
         a1 = L_mac0(a1,*fp0++,*fp1++); 
      cor[i] = a1;
      a0 = L_msu0(a0, *fp2, *fp2);
      a0 = L_mac0(a0, *fp3, *fp3);
      fp2--; fp3--;
      energy[i] = a0;
      energy_exp[i] = norm_l(energy[i]);
      energy_man[i] = extract_h(L_shl(energy[i], energy_exp[i]));
      s0 = cor2_exp[i] = norm_l(a1);
      t0 = extract_h(L_shl(a1, s0));
      cor2[i] = extract_h(L_mult(t0, t0));
      
      if (a1 < 0) 
         cor2[i] = negate(cor2[i]);
   }
   
   /* Find positive correlation peaks */
   /* Find maximum of cor*cor/energy among positive correlation peaks */ 
   
   npeaks = 0;
   n = MINPPD-1;
   while ((npeaks < MAX_NPEAKS) && (n<MAXPPD)) {
      
      if (cor[n]>0) { 
         a0   = L_mult(energy_man[n-1],cor2[n]);
         a1   = L_mult(energy_man[n], cor2[n-1]);
         exp0 = shl(sub(cor2_exp[n], cor2_exp[n-1]),1);
         exp0 = add(exp0, energy_exp[n-1]);
         exp0 = sub(exp0, energy_exp[n]);
         
         if (exp0>=0) 
            a0 = L_shr(a0, exp0);
         else 
            a1 = L_shl(a1, exp0);
         
         if (a0 > a1) { 
            
            a0   = L_mult(energy_man[n+1],cor2[n]);
            a1   = L_mult(energy_man[n], cor2[n+1]);
            exp0 = shl(sub(cor2_exp[n], cor2_exp[n+1]),1);
            exp0 = add(exp0, energy_exp[n+1]);
            exp0 = sub(exp0, energy_exp[n]);
            
            if (exp0>=0) 
               a0 = L_shr(a0, exp0);
            else 
               a1 = L_shl(a1, exp0);
            
            if (a0 > a1) {
               idx[npeaks] = n;
               npeaks++; 
            }
         }
    }
    
    n++;
    
  }
  
  /* Return early if there is no peak or only one peak */
  
  if (npeaks == 0){   /* if there are no positive peak, */
     return MINPPD*DECF; /* return minimum pitch period in decimated domain */
  }
  
  if (npeaks == 1){   /* if there is exactly one peak, */
     return (idx[0]+1)*DECF; /* return the time lag for this single peak */
  }
  
  /* If program proceeds to here, there are 2 or more peaks */
  cor2max=(Word16) 0x8000;
  cor2max_exp= (Word16) 0;
  energymax_man=1;
  energymax_exp=0;
  
  imax=0;
  for (i=0; i < npeaks; i++) {
     
  /* Use quadratic interpolation to find the interpolated cor[] and
     energy[] corresponding to interpolated peak of cor2[]/energy[] */
     /* first calculate coefficients of y(x)=ax^2+bx+c; */
     n=idx[i];
     a0=L_sub(L_shr(L_add(cor[n+1],cor[n-1]),1),cor[n]);
     L_Extract(a0, &ah, &al);
     a0=L_shr(L_sub(cor[n+1],cor[n-1]),1);
     L_Extract(a0, &bh, &bl);
     cc=cor[n];
     
     /* Initialize variables before searching for interpolated peak */
     im=0;
     cor2m_exp = cor2_exp[n];
     cor2m = cor2[n];
     energym_exp = energy_exp[n];
     energym_man = energy_man[n];
     eni=energy[n];
     
     /* Determine which side the interpolated peak falls in, then
     do the search in the appropriate range */
     
     a0   = L_mult(energy_man[n-1],cor2[n+1]);
     a1   = L_mult(energy_man[n+1], cor2[n-1]);
     exp0 = shl(sub(cor2_exp[n+1], cor2_exp[n-1]),1);
     exp0 = add(exp0, energy_exp[n-1]);
     exp0 = sub(exp0, energy_exp[n+1]);
     
     if (exp0>=0) 
        a0 = L_shr(a0, exp0);
     else 
        a1 = L_shl(a1, exp0);
     
     if (a0 > a1) {  /* if right side */
        
        deltae = L_shr(L_sub(energy[n+1], eni), 2);
        
        for (k = 0; k < HDECF; k++) {
           a0=L_add(L_add(Mpy_32_16(ah,al,x2[k]),Mpy_32_16(bh,bl,x[k])),cc);
           eni = L_add(eni, deltae);
           a1 = eni;
           exp0 = norm_l(a0);
           s0 = extract_h(L_shl(a0, exp0));
           s0 = extract_h(L_mult(s0, s0));
           e2 = energym_exp;
           t0 = energym_man;
           a2 = L_mult(t0, s0);
           e3 = norm_l(a1);
           t1 = extract_h(L_shl(a1, e3));
           a3 = L_mult(t1, cor2m);
           exp1 = shl(sub(exp0, cor2m_exp),1);
           exp1 = add(exp1, e2);
           exp1 = sub(exp1, e3);
           
           if (exp1>=0) 
              a2 = L_shr(a2, exp1);
           else 
              a3 = L_shl(a3, exp1);
           
           if (a2 > a3) {
              im = k+1;
              cor2m = s0;
              cor2m_exp = exp0;
              energym_exp = e3;
              energym_man = t1;
           }
        }        
     } else {    /* if interpolated peak is on the left side */
        
        deltae = L_shr(L_sub(energy[n-1], eni), 2);
        for (k = 0; k < HDECF; k++) {
           a0=L_add(L_sub(Mpy_32_16(ah,al,x2[k]),Mpy_32_16(bh,bl,x[k])),cc);
           eni = L_add(eni, deltae);
           a1=eni;
           
           exp0 = norm_l(a0);
           s0 = extract_h(L_shl(a0, exp0));
           s0 = extract_h(L_mult(s0, s0));
           e2 = energym_exp;
           t0 = energym_man;
           a2 = L_mult(t0, s0);
           e3 = norm_l(a1);
           t1 = extract_h(L_shl(a1, e3));
           a3 = L_mult(t1, cor2m);
           exp1 = shl(sub(exp0, cor2m_exp),1);
           exp1 = add(exp1, e2);
           exp1 = sub(exp1, e3);
           
           if (exp1>=0) 
              a2 = L_shr(a2, exp1);
           else 
              a3 = L_shl(a3, exp1);
           
           if (a2 > a3) {
              im = -k-1;
              cor2m = s0;
              cor2m_exp = exp0;
              energym_exp = e3;
              energym_man = t1;
           }
        }        
     }
     
     /* Search done; assign cor2[] and energy[] corresponding to 
     interpolated peak */ 
     plag[i]=add(shl(add(idx[i],1),2),im); /* lag of interp. peak */
     cor2i[i]=cor2m;
     cor2i_exp[i]=cor2m_exp;
     /* interpolated energy[] of i-th interpolated peak */
     energyi_exp[i] = energym_exp;
     energyi_man[i] = energym_man;
     
     /* Search for global maximum of interpolated cor2[]/energy[] peak */
     a0 = L_mult(cor2m,energymax_man);
     a1 = L_mult(cor2max, energyi_man[i]);
     exp0 = shl(sub(cor2m_exp, cor2max_exp),1);
     exp0 = add(exp0, energymax_exp);
     exp0 = sub(exp0, energyi_exp[i]);
     
     if (exp0 >=0) 
        a0 = L_shr(a0, exp0);
     else 
        a1 = L_shl(a1, exp0);
     
     if (a0 > a1) {
        imax=i;
        cor2max=cor2m;
        cor2max_exp=cor2m_exp;
        energymax_exp = energyi_exp[i];
        energymax_man = energyi_man[i];
     }
  }
  cpp=plag[imax]; /* first candidate for coarse pitch period */
  mplth=plag[npeaks-1]; /* set mplth to the lag of last peak */
  
  /* Find the largest peak (if there is any) around the last pitch */
  maxdev= shr(cstate->cpplast,2); /* maximum deviation from last pitch */
  im = -1;
  cor2m=(Word16) 0x8000;
  cor2m_exp= (Word16) 0;
  energym_man = 1;
  energym_exp = 0;
  
  for (i=0;i<npeaks;i++) {  /* loop thru the peaks before the largest peak */
     
     if (abs_s(sub(plag[i],cstate->cpplast)) <= maxdev) {
        a0 = L_mult(cor2i[i],energym_man);
        a1 = L_mult(cor2m, energyi_man[i]);
        exp0 = shl(sub(cor2i_exp[i], cor2m_exp),1);
        exp0 = add(exp0, energym_exp);
        exp0 = sub(exp0, energyi_exp[i]);
        
        if (exp0 >=0) 
           a0 = L_shr(a0, exp0);
        else 
           a1 = L_shl(a1, exp0);
        
        if (a0 > a1) {
           im=i;
           cor2m=cor2i[i];
           cor2m_exp=cor2i_exp[i];
           energym_man = energyi_man[i];
           energym_exp = energyi_exp[i];
        }   
     }
  } /* if there is no peaks around last pitch, then im is still -1 */
  
  
  /* Now see if we should pick any alternatice peak */
  /* first, search first half of pitch range, see if any qualified peak
  has large enough peaks at every multiple of its lag */
  i=0;
  
  while (2*plag[i] < mplth) {
     
     /* Determine the appropriate threshold for this peak */
     
     if (i != im) {  /* if not around last pitch, */
        threshold = TH1;    /* use a higher threshold */
     } else {        /* if around last pitch */
        threshold = TH2;    /* use a lower threshold */
     }
     
     /* If threshold exceeded, test peaks at multiples of this lag */
     a0 = L_mult(cor2i[i],energymax_man);
     t1 = extract_h(L_mult(energyi_man[i], threshold));
     a1 = L_mult(cor2max, t1);
     exp0 = shl(sub(cor2i_exp[i], cor2max_exp),1);
     exp0 = add(exp0, energymax_exp);
     exp0 = sub(exp0, energyi_exp[i]);
     
     if (exp0 >=0) 
        a0 = L_shr(a0, exp0);
     else 
        a1 = L_shl(a1, exp0);
     
     if (a0 > a1) {
        flag=1;  
        j=i+1;
        k=0;
        s=shl(plag[i],1); /* initialize t to twice the current lag */
        
        while (s<=mplth) { /* loop thru all multiple lag <= mplth */
           
           mpflag=0;   /* initialize multiple pitch flag to 0 */
           t0 = mult_r(s,MPDTH); 
           a=sub(s, t0);   /* multiple pitch range lower bound */
           b=add(s, t0);   /* multiple pitch range upper bound */
           while (j < npeaks) { /* loop thru peaks with larger lags */
              
              if (plag[j] > b) { /* if range exceeded, */
                 break;          /* break the innermost while loop */
              }       /* if didn't break, then plag[j] <= b */
              
              if (plag[j] > a) { /* if current peak lag within range, */
                 /* then check if peak value large enough */
                 a0 = L_mult(cor2i[j],energymax_man);
                 if (k<4) 
                    t1 = MPTH[k];
                 else 
                    t1 = MPTH4;
                 t1 = extract_h(L_mult(t1, energyi_man[j]));
                 a1 = L_mult(cor2max, t1);
                 exp0 = shl(sub(cor2i_exp[j], cor2max_exp),1);
                 exp0 = add(exp0, energymax_exp);
                 exp0 = sub(exp0, energyi_exp[j]);
                 
                 if (exp0 >=0) 
                    a0 = L_shr(a0, exp0);
                 else 
                    a1 = L_shl(a1, exp0);
                 
                 if (a0 > a1) {
                    mpflag=1; /* if peak large enough, set mpflag, */
                    break; /* and break the innermost while loop */
                 } 
              }
              j++;
           }
           /* if no qualified peak found at this multiple lag */
           
           if (mpflag == 0) { 
              flag=0;     /* disqualify the lag plag[i] */
              break;      /* and break the while (s<=mplth) loop */
           }
           k++;
           s = add(s, plag[i]); /* update s to the next multiple pitch lag */
           
        }
        /* if there is a qualified peak at every multiple of plag[i], */
        
        if (flag == 1) { 
           cpp = plag[i];   /* then accept this as final pitch */

           return cpp;         /* and return to calling function */
        }
    }       
    i++;
    
    if (i == npeaks)
       break;      /* to avoid out of array bound error */
  }
  
  /* If program proceeds to here, none of the peaks with lags < 0.5*mplth
  qualifies as the final pitch. in this case, check if
  there is any peak large enough around last pitch.  if so, use its
  lag as the final pitch. */
  
  if (im != -1) {   /* if there is at least one peak around last pitch */
     
     if (im == imax) { /* if this peak is also the global maximum, */
        return cpp;   /* return first pitch candidate at global max */
     }
     
     if (im < imax) { /* if lag of this peak < lag of global max, */
        a0 = L_mult(cor2m,energymax_man);
        t1 = extract_h(L_mult(energym_man, LPTH2));
        a1 = L_mult(cor2max, t1);
        exp0 = shl(sub(cor2m_exp, cor2max_exp),1);
        exp0 = add(exp0, energymax_exp);
        exp0 = sub(exp0, energym_exp);
        
        if (exp0 >=0) 
           a0 = L_shr(a0, exp0);
        else 
           a1 = L_shl(a1, exp0);
        
        if (a0 > a1) {
           
           if (plag[im] > HMAXPPD*DECF) {
              cpp=plag[im];
              
              return cpp;
           }
           for (k=2; k<=5;k++) { /* check if current candidate pitch */
              s=mult(plag[imax],invk[k-2]); /* is a sub-multiple of */
              t0 = mult_r(s,SMDTH);
              a=sub(s, t0);      /* the time lag of */
              b=add(s, t0);       /* the global maximum peak */
              
              if (plag[im]>a && plag[im]<b) {     /* if so, */
                 cpp=plag[im];       /* accept this peak, */
                 
                 return cpp;         /* and return as pitch */
              }
           }
        }
     } else {           /* if lag of this peak > lag of global max, */
        a0 = L_mult(cor2m,energymax_man);
        t1 = extract_h(L_mult(energym_man, LPTH1));
        a1 = L_mult(cor2max, t1);
        exp0 = shl(sub(cor2m_exp, cor2max_exp),1);
        exp0 = add(exp0, energymax_exp);
        exp0 = sub(exp0, energym_exp);
        
        if (exp0 >=0) 
           a0 = L_shr(a0, exp0);
        else 
           a1 = L_shl(a1, exp0);
        
        if (a0 > a1) {
           cpp = plag[im];  /* if this peak is large enough, */
           
           return cpp;         /* accept its lag */ 
        }
     }
  }
  
  /* If program proceeds to here, we have no choice but to accept the
  lag of the global maximum */
  return cpp;
  
}
Ejemplo n.º 16
0
/*---------------------------------------------------------------------------*
 * Function  Dec_gain                                                        *
 * ~~~~~~~~~~~~~~~~~~                                                        *
 * Decode the pitch and codebook gains                                       *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * input arguments:                                                          *
 *                                                                           *
 *   index      :Quantization index                                          *
 *   code[]     :Innovative code vector                                      *
 *   L_subfr    :Subframe size                                               *
 *   bfi        :Bad frame indicator                                         *
 *                                                                           *
 * output arguments:                                                         *
 *                                                                           *
 *   gain_pit   :Quantized pitch gain                                        *
 *   gain_cod   :Quantized codebook gain                                     *
 *                                                                           *
 *---------------------------------------------------------------------------*/
void Dec_gain(
   Word16 index,        /* (i)     :Index of quantization.         */
   Word16 code[],       /* (i) Q13 :Innovative vector.             */
   Word16 L_subfr,      /* (i)     :Subframe length.               */
   Word16 bfi,          /* (i)     :Bad frame indicator            */
   Word16 *gain_pit,    /* (o) Q14 :Pitch gain.                    */
   Word16 *gain_cod     /* (o) Q1  :Code gain.                     */
)
{
   Word16  index1, index2, tmp;
   Word16  gcode0, exp_gcode0;
   Word32  L_gbk12, L_acc, L_accb;
   
   dec_gain_type* pdec_gain = pg729dec->pdec_gain;
   
   void    Gain_predict( Word16 past_qua_en[], Word16 code[], Word16 L_subfr,
                        Word16 *gcode0, Word16 *exp_gcode0 );
   void    Gain_update( Word16 past_qua_en[], Word32 L_gbk12 );
   void    Gain_update_erasure( Word16 past_qua_en[] );

        /* Gain predictor, Past quantized energies = -14.0 in Q10 */
#if 0
   static Word16 past_qua_en[4] = { -14336, -14336, -14336, -14336 };
#endif

   /*-------------- Case of erasure. ---------------*/

   if(bfi != 0){
      *gain_pit = mult( *gain_pit, 29491 );      /* *0.9 in Q15 */
      if (sub( *gain_pit, 29491) > 0) *gain_pit = 29491;
      *gain_cod = mult( *gain_cod, 32111 );      /* *0.98 in Q15 */

     /*----------------------------------------------*
      * update table of past quantized energies      *
      *                              (frame erasure) *
      *----------------------------------------------*/
      Gain_update_erasure(pdec_gain->past_qua_en);

      return;
   }

   /*-------------- Decode pitch gain ---------------*/

   index1 = imap1[ shr(index,NCODE2_B) ] ;
   index2 = imap2[ index & (NCODE2-1) ] ;
   *gain_pit = add( gbk1[index1][0], gbk2[index2][0] );

   /*-------------- Decode codebook gain ---------------*/

  /*---------------------------------------------------*
   *-  energy due to innovation                       -*
   *-  predicted energy                               -*
   *-  predicted codebook gain => gcode0[exp_gcode0]  -*
   *---------------------------------------------------*/

   Gain_predict( pdec_gain->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0 );

  /*-----------------------------------------------------------------*
   * *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0;      *
   *-----------------------------------------------------------------*/

   L_acc = L_deposit_l( gbk1[index1][1] );
   L_accb = L_deposit_l( gbk2[index2][1] );
   L_gbk12 = L_add( L_acc, L_accb );                       /* Q13 */
   tmp = extract_l( L_shr( L_gbk12,1 ) );                  /* Q12 */
   L_acc = L_mult(tmp, gcode0);             /* Q[exp_gcode0+12+1] */

   {
   	Word16 shift = add( negate(exp_gcode0),(-12-1+1+16) );
   	if(shift>0)
   		L_acc = L_shl(L_acc, shift);
   	else
   		L_acc = L_shr(L_acc, abs_s(shift));
   }
   *gain_cod = extract_h( L_acc );                          /* Q1 */

  /*----------------------------------------------*
   * update table of past quantized energies      *
   *----------------------------------------------*/
   Gain_update( pdec_gain->past_qua_en, L_gbk12 );

   return;

}
Ejemplo n.º 17
0
Word16 Cb_gain_average(
    Cb_gain_averageState *st, /* i/o : State variables for CB gain averaging */
    enum Mode mode,           /* i   : AMR mode                              */
    Word16 gain_code,         /* i   : CB gain                            Q1 */
    Word16 lsp[],             /* i   : The LSP for the current frame     Q15 */
    Word16 lspAver[],         /* i   : The average of LSP for 8 frames   Q15 */
    Word16 bfi,               /* i   : bad frame indication flag             */
    Word16 prev_bf,           /* i   : previous bad frame indication flag    */
    Word16 pdfi,              /* i   : potential degraded bad frame ind flag */
    Word16 prev_pdf,          /* i   : prev pot. degraded bad frame ind flag */
    Word16 inBackgroundNoise, /* i   : background noise decision             */
    Word16 voicedHangover,    /* i   : # of frames after last voiced frame   */
    Flag   *pOverflow
)
{
    Word16 i;
    Word16 cbGainMix;
    Word16 diff;
    Word16 tmp_diff;
    Word16 bgMix;
    Word16 cbGainMean;
    Word32 L_sum;
    Word16 tmp[M];
    Word16 tmp1;
    Word16 tmp2;
    Word16 shift1;
    Word16 shift2;
    Word16 shift;

    /*---------------------------------------------------------*
     * Compute mixed cb gain, used to make cb gain more        *
     * smooth in background noise for modes 5.15, 5.9 and 6.7  *
     * states that needs to be updated by all                  *
     *---------------------------------------------------------*/

    /* set correct cbGainMix for MR74, MR795, MR122 */
    cbGainMix = gain_code;

    /*-------------------------------------------------------*
     *   Store list of CB gain needed in the CB gain         *
     *   averaging                                           *
     *-------------------------------------------------------*/
    for (i = 0; i < (L_CBGAINHIST - 1); i++)
    {
        st->cbGainHistory[i] = st->cbGainHistory[i+1];
    }
    st->cbGainHistory[L_CBGAINHIST-1] = gain_code;

    diff = 0;

    /* compute lsp difference */
    for (i = 0; i < M; i++)
    {
        tmp1 = abs_s(sub(*(lspAver + i), *(lsp + i), pOverflow));
        /* Q15      */
        shift1 = sub(norm_s(tmp1), 1, pOverflow);       /* Qn       */
        tmp1 = shl(tmp1, shift1, pOverflow);            /* Q15+Qn   */
        shift2 = norm_s(*(lspAver + i));                /* Qm       */
        tmp2 = shl(*(lspAver + i), shift2, pOverflow);  /* Q15+Qm   */
        tmp[i] = div_s(tmp1, tmp2);        /* Q15+(Q15+Qn)-(Q15+Qm) */

        shift = 2 + shift1 - shift2;

        if (shift >= 0)
        {
            *(tmp + i) = shr(*(tmp + i), shift, pOverflow);
            /* Q15+Qn-Qm-Qx=Q13 */
        }
        else
        {
            *(tmp + i) = shl(*(tmp + i), negate(shift), pOverflow);
            /* Q15+Qn-Qm-Qx=Q13 */
        }

        diff = add(diff, *(tmp + i), pOverflow);           /* Q13 */
    }

    /* Compute hangover */

    if (diff > 5325)                /* 0.65 in Q11 */
    {
        st->hangVar += 1;
    }
    else
    {
        st->hangVar = 0;
    }


    if (st->hangVar > 10)
    {
        /* Speech period, reset hangover variable */
        st->hangCount = 0;
    }

    /* Compute mix constant (bgMix) */
    bgMix = 8192;    /* 1 in Q13 */

    if ((mode <= MR67) || (mode == MR102))
        /* MR475, MR515, MR59, MR67, MR102 */
    {
        /* if errors and presumed noise make smoothing probability stronger */

        if (((((pdfi != 0) && (prev_pdf != 0)) || (bfi != 0) ||
                (prev_bf != 0))
                && (voicedHangover > 1)
                && (inBackgroundNoise != 0)
                && ((mode == MR475) || (mode == MR515) ||
                    (mode == MR59))))
        {
            /* bgMix = min(0.25, max(0.0, diff-0.55)) / 0.25; */
            tmp_diff = sub(diff, 4506, pOverflow);   /* 0.55 in Q13 */
        }
        else
        {
            /* bgMix = min(0.25, max(0.0, diff-0.40)) / 0.25; */
            tmp_diff = sub(diff, 3277, pOverflow); /* 0.4 in Q13 */
        }

        /* max(0.0, diff-0.55)  or  */
        /* max(0.0, diff-0.40) */
        if (tmp_diff > 0)
        {
            tmp1 = tmp_diff;
        }
        else
        {
            tmp1 = 0;
        }

        /* min(0.25, tmp1) */
        if (2048 < tmp1)
        {
            bgMix = 8192;
        }
        else
        {
            bgMix = shl(tmp1, 2, pOverflow);
        }

        if ((st->hangCount < 40) || (diff > 5325)) /* 0.65 in Q13 */
        {
            /* disable mix if too short time since */
            bgMix = 8192;
        }

        /* Smoothen the cb gain trajectory  */
        /* smoothing depends on mix constant bgMix */
        L_sum = L_mult(6554, st->cbGainHistory[2], pOverflow);
        /* 0.2 in Q15; L_sum in Q17 */

        for (i = 3; i < L_CBGAINHIST; i++)
        {
            L_sum = L_mac(L_sum, 6554, st->cbGainHistory[i], pOverflow);
        }
        cbGainMean = pv_round(L_sum, pOverflow);               /* Q1 */

        /* more smoothing in error and bg noise (NB no DFI used here) */

        if (((bfi != 0) || (prev_bf != 0)) && (inBackgroundNoise != 0)
                && ((mode == MR475) || (mode == MR515)
                    || (mode == MR59)))
        {
            /* 0.143 in Q15; L_sum in Q17    */
            L_sum = L_mult(4681, st->cbGainHistory[0], pOverflow);
            for (i = 1; i < L_CBGAINHIST; i++)
            {
                L_sum =
                    L_mac(L_sum, 4681, st->cbGainHistory[i], pOverflow);
            }
            cbGainMean = pv_round(L_sum, pOverflow);              /* Q1 */
        }

        /* cbGainMix = bgMix*cbGainMix + (1-bgMix)*cbGainMean; */
        /* L_sum in Q15 */
        L_sum = L_mult(bgMix, cbGainMix, pOverflow);
        L_sum = L_mac(L_sum, 8192, cbGainMean, pOverflow);
        L_sum = L_msu(L_sum, bgMix, cbGainMean, pOverflow);
        cbGainMix = pv_round(L_shl(L_sum, 2, pOverflow), pOverflow);  /* Q1 */
    }

    st->hangCount += 1;

    return (cbGainMix);
}
Ejemplo n.º 18
0
void perc_var (
  Word16 *gamma1, /* Bandwidth expansion parameter */
  Word16 *gamma2, /* Bandwidth expansion parameter */
  Word16 *LsfInt, /* Interpolated LSP vector : 1st subframe */
  Word16 *LsfNew, /* New LSP vector : 2nd subframe */
  Word16 *r_c     /* Reflection coefficients */
)
{

  Word32   L_temp;
  Word16   cur_rc;                    /* Q11 */
  Word16   Lar[4];                    /* Q11 */
  Word16  *LarNew;                    /* Q11 */
  Word16  *Lsf;                       /* Q15 */
  Word16   CritLar0, CritLar1;        /* Q11 */
  Word16   temp;
  Word16   d_min;                     /* Q10 */
  Word16   i, k;



  for (k=0; k<M; k++) {
    LsfInt[k] = shl(LsfInt[k], 1);
    LsfNew[k] = shl(LsfNew[k], 1);
  }


  LarNew = &Lar[2];
  /* ---------------------------------------- */
  /* Reflection coefficients ---> Lar         */
  /* Lar(i) = log10( (1+rc) / (1-rc) )        */
  /* Approximated by                          */
  /* x <= SEG1            y = x               */
  /* SEG1 < x <= SEG2     y = A1 x - B1_L     */
  /* SEG2 < x <= SEG3     y = A2 x - B2_L     */
  /* x > SEG3             y = A3 x - B3_L     */
  /* ---------------------------------------- */
  for (i=0; i<2; i++) {

    cur_rc = abs_s(r_c[i]);
    cur_rc = shr(cur_rc, 4);

    if (sub(cur_rc ,SEG1)<= 0) {
        LarNew[i] = cur_rc;
    }
    else {
      if (sub(cur_rc,SEG2)<= 0) {
        cur_rc = shr(cur_rc, 1);
        L_temp = L_mult(cur_rc, A1);
        L_temp = L_sub(L_temp, L_B1);
        L_temp = L_shr(L_temp, 11);
        LarNew[i] = extract_l(L_temp);
      }
      else {
        if (sub(cur_rc ,SEG3)<= 0) {
          cur_rc = shr(cur_rc, 1);
          L_temp = L_mult(cur_rc, A2);
          L_temp = L_sub(L_temp, L_B2);
          L_temp = L_shr(L_temp, 11);
          LarNew[i] = extract_l(L_temp);
        }
        else {
          cur_rc = shr(cur_rc, 1);
          L_temp = L_mult(cur_rc, A3);
          L_temp = L_sub(L_temp, L_B3);
          L_temp = L_shr(L_temp, 11);
          LarNew[i] = extract_l(L_temp);
        }
      }
    }
    if (r_c[i] < 0) {
        LarNew[i] = sub(0, LarNew[i]);

    }
  }

  /* Interpolation of Lar for the 1st subframe */

  temp = add(LarNew[0], LarOld[0]);
  Lar[0] = shr(temp, 1);
  LarOld[0] = LarNew[0];
  temp = add(LarNew[1], LarOld[1]);
  Lar[1] = shr(temp, 1);
  LarOld[1] = LarNew[1];

  for (k=0; k<2; k++) { /* LOOP : gamma2 for 1st to 2nd subframes */

      /* ---------------------------------------------------------- */
      /* First criterion based on the first two Lars                */
      /* smooth == 1  ==>  gamma2 can vary from 0.4 to 0.7          */
      /* smooth == 0  ==>  gamma2 is set to 0.6                     */
      /*                                                            */
      /* Double threshold + hysteresis :                            */
      /* if smooth = 1                                              */
      /*  if (CritLar0 < THRESH_L1) and (CritLar1 > THRESH_H1)      */
      /*                                                 smooth = 0 */
      /* if smooth = 0                                              */
      /*  if (CritLar0 > THRESH_L2) or (CritLar1 < THRESH_H2)       */
      /*                                                 smooth = 1 */
      /* ---------------------------------------------------------- */

      CritLar0 = Lar[2*k];
      CritLar1 = Lar[2*k+1];

      if (smooth != 0) {
        if ((sub(CritLar0,THRESH_L1)<0)&&( sub(CritLar1,THRESH_H1)>0)) {
            smooth = 0;
        }
      }
      else {
        if ( (sub(CritLar0 ,THRESH_L2)>0) || (sub(CritLar1,THRESH_H2) <0) ) {
            smooth = 1;
        }

      }

    if (smooth == 0) {
      /* ------------------------------------------------------ */
      /* Second criterion based on the minimum distance between */
      /*                two successives LSPs                    */
      /*                                                        */
      /*           gamma2[k] = -6.0 * pi * d_min + 1.0          */
      /*                                                        */
      /*       with Lsfs normalized range 0.0 <= val <= 1.0     */
      /* ------------------------------------------------------ */
      gamma1[k] = GAMMA1_0;
      if (k == 0) {
        Lsf = LsfInt;
      }
      else {
        Lsf = LsfNew;
      }
      d_min = sub(Lsf[1], Lsf[0]);
      for (i=1; i<M-1; i++) {
        temp = sub(Lsf[i+1],Lsf[i]);
        if (sub(temp,d_min)<0) {
            d_min = temp;
        }
      }
      temp = mult(ALPHA, d_min);
      temp = sub(BETA, temp);
      temp = shl(temp, 5);
      gamma2[k] = temp;

      if (sub(gamma2[k] , GAMMA2_0_H)>0) {
        gamma2[k] = GAMMA2_0_H;
      }
      if (sub(gamma2[k] ,GAMMA2_0_L)<0) {
        gamma2[k] = GAMMA2_0_L;
      }

    }
    else {
      gamma1[k] = GAMMA1_1;
      gamma2[k] = GAMMA2_1;
    }
  }
  return;
}
Ejemplo n.º 19
0
void ABS_S(void)
{
   if (check_cop1_unusable()) return;
   abs_s(reg_cop1_simple[cffs], reg_cop1_simple[cffd]);
   PC++;
}
Ejemplo n.º 20
0
Word16 vad2 (Word16 * farray_ptr, vadState2 * st)
{

	/*
	 * The channel table is defined below.  In this table, the
	 * lower and higher frequency coefficients for each of the 16
	 * channels are specified.  The table excludes the coefficients
	 * with numbers 0 (DC), 1, and 64 (Foldover frequency).
	 */

	const static Word16 ch_tbl[NUM_CHAN][2] =
	{

		{2, 3},
		{4, 5},
		{6, 7},
		{8, 9},
		{10, 11},
		{12, 13},
		{14, 16},
		{17, 19},
		{20, 22},
		{23, 26},
		{27, 30},
		{31, 35},
		{36, 41},
		{42, 48},
		{49, 55},
		{56, 63}

	};

	/* channel energy scaling table - allows efficient division by number
         * of DFT bins in the channel: 1/2, 1/3, 1/4, etc.
	 */

	const static Word16 ch_tbl_sh[NUM_CHAN] =
	{
		16384, 16384, 16384, 16384, 16384, 16384, 10923, 10923,
		10923, 8192, 8192, 6554, 5461, 4681, 4681, 4096
	};

	/*
	 * The voice metric table is defined below.  It is a non-
	 * linear table with a deadband near zero.  It maps the SNR
	 * index (quantized SNR value) to a number that is a measure
	 * of voice quality.
	 */

	const static Word16 vm_tbl[90] =
	{
		2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
		3, 3, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 7, 7, 7,
		8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 13, 14, 15,
		15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 23, 24,
		24, 25, 26, 27, 28, 28, 29, 30, 31, 32, 33, 34,
		35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45,
		46, 47, 48, 49, 50, 50, 50, 50, 50, 50, 50, 50,
		50, 50
	};

	/* hangover as a function of peak SNR (3 dB steps) */
	const static Word16 hangover_table[20] =
	{
		30, 30, 30, 30, 30, 30, 28, 26, 24, 22, 20, 18, 16, 14, 12, 10, 8, 8, 8, 8
	};

	/* burst sensitivity as a function of peak SNR (3 dB steps) */
	const static Word16 burstcount_table[20] =
	{
		8, 8, 8, 8, 8, 8, 8, 8, 7, 6, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4
	};

	/* voice metric sensitivity as a function of peak SNR (3 dB steps) */
	const static Word16 vm_threshold_table[20] =
	{
                34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 40, 51, 71, 100, 139, 191, 257, 337, 432
	};


	/* State tables that use 22,9 or 27,4 scaling for ch_enrg[] */

   const static Word16 noise_floor_chan[2] =	{NOISE_FLOOR_CHAN_0, NOISE_FLOOR_CHAN_1};
	const  static Word16 min_chan_enrg[2] =	{MIN_CHAN_ENRG_0, MIN_CHAN_ENRG_1};
	const static Word16 ine_noise[2] = 		{INE_NOISE_0, INE_NOISE_1};
	const static Word16 fbits[2] = 		{FRACTIONAL_BITS_0, FRACTIONAL_BITS_1};
	const static Word16 state_change_shift_r[2] = {STATE_1_TO_0_SHIFT_R, STATE_0_TO_1_SHIFT_R};

	/* Energy scale table given 30,1 input scaling (also account for -6 dB shift on input) */
	const static Word16 enrg_norm_shift[2] = 	{(FRACTIONAL_BITS_0-1+2), (FRACTIONAL_BITS_1-1+2)};


	/* Automatic variables */

	Word32 Lenrg;				/* scaled as 30,1 */
	Word32 Ltne;				/* scaled as 22,9 */
	Word32 Ltce;				/* scaled as 22,9 or 27,4 */

	Word16 tne_db;				/* scaled as 7,8 */
	Word16 tce_db;				/* scaled as 7,8 */

	Word16 input_buffer[FRM_LEN];		/* used for block normalising input data */
	Word16 data_buffer[FFT_LEN];		/* used for in-place FFT */

	Word16 ch_snr[NUM_CHAN];		/* scaled as 7,8 */
	Word16 ch_snrq;				/* scaled as 15,0 (in 0.375 dB steps) */
	Word16 vm_sum;				/* scaled as 15,0 */
	Word16 ch_enrg_dev;			/* scaled as 7,8 */

	Word32 Lpeak;				/* maximum channel energy */
	Word16 p2a_flag;			/* flag to indicate spectral peak-to-average ratio > 10 dB */

	Word16 ch_enrg_db[NUM_CHAN];		/* scaled as 7,8 */
	Word16 ch_noise_db;			/* scaled as 7,8 */

	Word16 alpha;				/* scaled as 0,15 */
	Word16 one_m_alpha;			/* scaled as 0,15 */
	Word16 update_flag;			/* set to indicate a background noise estimate update */

	Word16 i, j, j1, j2;			/* Scratch variables */
	Word16 hi1, lo1;

	Word32 Ltmp, Ltmp1, Ltmp2;
	Word16 tmp;

	Word16 normb_shift;		/* block norm shift count */

	Word16 ivad;			/* intermediate VAD decision (return value) */
	Word16 tsnrq;			/* total signal-to-noise ratio (quantized 3 dB steps) scaled as 15,0 */
	Word16 xt;			/* instantaneous frame SNR in dB, scaled as 7,8 */

	Word16 state_change;


	/* Increment frame counter */
	st->Lframe_cnt = L_add(st->Lframe_cnt, 1);

	/* Block normalize the input */
	normb_shift = block_norm(farray_ptr, input_buffer, FRM_LEN, FFT_HEADROOM);

	/* Pre-emphasize the input data and store in the data buffer with the appropriate offset */
	for (i = 0; i < DELAY; i++)
	{
		data_buffer[i] = 0;									move16();
	}

	st->pre_emp_mem = shr_r(st->pre_emp_mem, sub(st->last_normb_shift, normb_shift));
	st->last_normb_shift = normb_shift;								move16();

	data_buffer[DELAY] = add(input_buffer[0], mult(PRE_EMP_FAC, st->pre_emp_mem));			move16();

	for (i = DELAY + 1, j = 1; i < DELAY + FRM_LEN; i++, j++)
	{
		data_buffer[i] = add(input_buffer[j], mult(PRE_EMP_FAC, input_buffer[j-1]));		move16();
	}
	st->pre_emp_mem = input_buffer[FRM_LEN-1];							move16();

	for (i = DELAY + FRM_LEN; i < FFT_LEN; i++)
	{
		data_buffer[i] = 0;									move16();
	}


	/* Perform FFT on the data buffer */
	r_fft(data_buffer);


	/* Use normb_shift factor to determine the scaling of the energy estimates */
	state_change = 0;										move16();
													test();
	if (st->shift_state == 0)
	{												test();
		if (sub(normb_shift, -FFT_HEADROOM+2) <= 0)
		{
			state_change = 1;								move16();
			st->shift_state = 1;								move16();
		}
	}
	else
	{												test();
		if (sub(normb_shift, -FFT_HEADROOM+5) >= 0)
		{
			state_change = 1;								move16();
			st->shift_state = 0;								move16();
		}
	}

	/* Scale channel energy estimate */								test();
	if (state_change)
	{
		for (i = LO_CHAN; i <= HI_CHAN; i++)
		{
			st->Lch_enrg[i] = L_shr(st->Lch_enrg[i], state_change_shift_r[st->shift_state]);	move32();
		}
	}


	/* Estimate the energy in each channel */
													test();
	if (L_sub(st->Lframe_cnt, 1) == 0)
	{
		alpha = 32767;										move16();
		one_m_alpha = 0;									move16();
	}
	else
	{
		alpha = CEE_SM_FAC;									move16();
		one_m_alpha = ONE_MINUS_CEE_SM_FAC;							move16();
	}

	for (i = LO_CHAN; i <= HI_CHAN; i++)
	{
		Lenrg = 0;										move16();
		j1 = ch_tbl[i][0];									move16();
		j2 = ch_tbl[i][1];									move16();

		for (j = j1; j <= j2; j++)
		{
			Lenrg = L_mac(Lenrg, data_buffer[2 * j], data_buffer[2 * j]);
			Lenrg = L_mac(Lenrg, data_buffer[2 * j + 1], data_buffer[2 * j + 1]);
		}

		/* Denorm energy & scale 30,1 according to the state */
		Lenrg = L_shr_r(Lenrg, sub(shl(normb_shift, 1), enrg_norm_shift[st->shift_state]));

		/* integrate over time: e[i] = (1-alpha)*e[i] + alpha*enrg/num_bins_in_chan */
		tmp = mult(alpha, ch_tbl_sh[i]);
		L_Extract (Lenrg, &hi1, &lo1);
		Ltmp = Mpy_32_16(hi1, lo1, tmp);

		L_Extract (st->Lch_enrg[i], &hi1, &lo1);
		st->Lch_enrg[i] = L_add(Ltmp, Mpy_32_16(hi1, lo1, one_m_alpha));			move32();
													test();
		if (L_sub(st->Lch_enrg[i], min_chan_enrg[st->shift_state]) < 0)
		{
			st->Lch_enrg[i] = min_chan_enrg[st->shift_state];				move32();
		}

	}


	/* Compute the total channel energy estimate (Ltce) */
	Ltce = 0;											move16();
	for (i = LO_CHAN; i <= HI_CHAN; i++)
	{
		Ltce = L_add(Ltce, st->Lch_enrg[i]);
	}


	/* Calculate spectral peak-to-average ratio, set flag if p2a > 10 dB */
	Lpeak = 0;											move32();
	for (i = LO_CHAN+2; i <= HI_CHAN; i++)	/* Sine waves not valid for low frequencies */
	{												test();
		if (L_sub(st->Lch_enrg [i], Lpeak) > 0)
		{
			Lpeak = st->Lch_enrg [i];							move32();
		}
	}

	/* Set p2a_flag if peak (dB) > average channel energy (dB) + 10 dB */
	/*   Lpeak > Ltce/num_channels * 10^(10/10)                        */
	/*   Lpeak > (10/16)*Ltce                                          */

	L_Extract (Ltce, &hi1, &lo1);
	Ltmp = Mpy_32_16(hi1, lo1, 20480);
													test();
	if (L_sub(Lpeak, Ltmp) > 0)
	{
		p2a_flag = TRUE;									move16();
	}
	else
	{
		p2a_flag = FALSE;									move16();
	}


	/* Initialize channel noise estimate to either the channel energy or fixed level  */
	/*   Scale the energy appropriately to yield state 0 (22,9) scaling for noise */
													test();
	if (L_sub(st->Lframe_cnt, 4) <= 0)
	{												test();
		if (p2a_flag == TRUE)
		{
			for (i = LO_CHAN; i <= HI_CHAN; i++)
			{
				st->Lch_noise[i] = INE_NOISE_0;						move32();
			}
		}
		else
		{
			for (i = LO_CHAN; i <= HI_CHAN; i++)
			{										test();
				if (L_sub(st->Lch_enrg[i], ine_noise[st->shift_state]) < 0)
				{
					st->Lch_noise[i] = INE_NOISE_0;					move32();
				}
				else
				{									test();
					if (st->shift_state == 1)
					{
						st->Lch_noise[i] = L_shr(st->Lch_enrg[i], state_change_shift_r[0]);
													move32();
					}
					else
					{
						st->Lch_noise[i] = st->Lch_enrg[i];			move32();
					}
				}
			}
		}
	}


	/* Compute the channel energy (in dB), the channel SNRs, and the sum of voice metrics */
	vm_sum = 0;											move16();
	for (i = LO_CHAN; i <= HI_CHAN; i++)
	{
		ch_enrg_db[i] = fn10Log10(st->Lch_enrg[i], fbits[st->shift_state]);			move16();
		ch_noise_db = fn10Log10(st->Lch_noise[i], FRACTIONAL_BITS_0);

		ch_snr[i] = sub(ch_enrg_db[i], ch_noise_db);						move16();

		/* quantize channel SNR in 3/8 dB steps (scaled 7,8 => 15,0) */
		/*   ch_snr = round((snr/(3/8))>>8)                          */
		/*          = round(((0.6667*snr)<<2)>>8)                    */
		/*          = round((0.6667*snr)>>6)                         */

		ch_snrq = shr_r(mult(21845, ch_snr[i]), 6);

		/* Accumulate the sum of voice metrics	*/						test();
		if (sub(ch_snrq, 89) < 0)
		{											test();
			if (ch_snrq > 0)
			{
				j = ch_snrq;								move16();
			}
			else
			{
				j = 0;									move16();
			}
		}
		else
		{
			j = 89;										move16();
		}
		vm_sum = add(vm_sum, vm_tbl[j]);
	}


	/* Initialize NOMINAL peak voice energy and average noise energy, calculate instantaneous SNR */ 
												test(),test(),logic16();
	if (L_sub(st->Lframe_cnt, 4) <= 0 || st->fupdate_flag == TRUE)
	{
		/* tce_db = (96 - 22 - 10*log10(64) (due to FFT)) scaled as 7,8 */
		tce_db = 14320;										move16();
		st->negSNRvar = 0;									move16();
		st->negSNRbias = 0;									move16();

		/* Compute the total noise estimate (Ltne) */
		Ltne = 0;										move32();
		for (i = LO_CHAN; i <= HI_CHAN; i++)
		{
			Ltne = L_add(Ltne, st->Lch_noise[i]);
		}

		/* Get total noise in dB */
		tne_db = fn10Log10(Ltne, FRACTIONAL_BITS_0);

		/* Initialise instantaneous and long-term peak signal-to-noise ratios */
		xt = sub(tce_db, tne_db);
		st->tsnr = xt;										move16();
	}
	else
	{
		/* Calculate instantaneous frame signal-to-noise ratio */
		/* xt = 10*log10( sum(2.^(ch_snr*0.1*log2(10)))/length(ch_snr) ) */
		Ltmp1 = 0;										move32();
		for (i=LO_CHAN; i<=HI_CHAN; i++) {
			/* Ltmp2 = ch_snr[i] * 0.1 * log2(10); (ch_snr scaled as 7,8) */
			Ltmp2 = L_shr(L_mult(ch_snr[i], 10885), 8);
			L_Extract(Ltmp2, &hi1, &lo1);
			hi1 = add(hi1, 3);			/* 2^3 to compensate for negative SNR */
			Ltmp1 = L_add(Ltmp1, Pow2(hi1, lo1));
		}
		xt = fn10Log10(Ltmp1, 4+3);			/* average by 16, inverse compensation 2^3 */

		/* Estimate long-term "peak" SNR */							test(),test();
		if (sub(xt, st->tsnr) > 0)
		{
			/* tsnr = 0.9*tsnr + 0.1*xt; */
			st->tsnr = round(L_add(L_mult(29491, st->tsnr), L_mult(3277, xt)));
		}
		/* else if (xt > 0.625*tsnr) */	
		else if (sub(xt, mult(20480, st->tsnr)) > 0)
		{
			/* tsnr = 0.998*tsnr + 0.002*xt; */
			st->tsnr = round(L_add(L_mult(32702, st->tsnr), L_mult(66, xt)));
		}
	}

	/* Quantize the long-term SNR in 3 dB steps, limit to 0 <= tsnrq <= 19 */
	tsnrq = shr(mult(st->tsnr, 10923), 8);

	/* tsnrq = min(19, max(0, tsnrq)); */								test(),test();
	if (sub(tsnrq, 19) > 0)
	{
		tsnrq = 19;										move16();
	}
	else if (tsnrq < 0)
	{
		tsnrq = 0;										move16();
	}

	/* Calculate the negative SNR sensitivity bias */
													test();
	if (xt < 0)
	{
		/* negSNRvar = 0.99*negSNRvar + 0.01*xt*xt; */
		/*   xt scaled as 7,8 => xt*xt scaled as 14,17, shift to 7,8 and round */
		tmp = round(L_shl(L_mult(xt, xt), 7));
		st->negSNRvar = round(L_add(L_mult(32440, st->negSNRvar), L_mult(328, tmp)));

		/* if (negSNRvar > 4.0) negSNRvar = 4.0;  */						test();
		if (sub(st->negSNRvar, 1024) > 0)
		{
			st->negSNRvar = 1024;								move16();
		}

		/* negSNRbias = max(12.0*(negSNRvar - 0.65), 0.0); */
		tmp = mult_r(shl(sub(st->negSNRvar, 166), 4), 24576);					test();

		if (tmp < 0)
		{
			st->negSNRbias = 0;								move16();
		}
		else
		{
			st->negSNRbias = shr(tmp, 8);
		}
	}


	/* Determine VAD as a function of the voice metric sum and quantized SNR */

	tmp = add(vm_threshold_table[tsnrq], st->negSNRbias);						test();
	if (sub(vm_sum, tmp) > 0)
	{
		ivad = 1;										move16();
		st->burstcount = add(st->burstcount, 1);						test();
		if (sub(st->burstcount, burstcount_table[tsnrq]) > 0)
		{
			st->hangover = hangover_table[tsnrq];						move16();
		}
	}
	else
	{
		st->burstcount = 0;									move16();
		st->hangover = sub(st->hangover, 1);							test();
		if (st->hangover <= 0)
		{
			ivad = 0;									move16();
			st->hangover = 0;								move16();
		}
		else
		{
			ivad = 1;									move16();
		}
	}


	/* Calculate log spectral deviation */
	ch_enrg_dev = 0;										move16();
													test();
	if (L_sub(st->Lframe_cnt, 1) == 0)
	{
		for (i = LO_CHAN; i <= HI_CHAN; i++)
		{
			st->ch_enrg_long_db[i] = ch_enrg_db[i];						move16();
		}
	}
	else
	{
		for (i = LO_CHAN; i <= HI_CHAN; i++)
		{
			tmp = abs_s(sub(st->ch_enrg_long_db[i], ch_enrg_db[i]));
			ch_enrg_dev = add(ch_enrg_dev, tmp);
		}
	}

	/*
	 * Calculate long term integration constant as a function of instantaneous SNR
	 * (i.e., high SNR (tsnr dB) -> slower integration (alpha = HIGH_ALPHA),
	 *         low SNR (0 dB) -> faster integration (alpha = LOW_ALPHA)
	 */

	/* alpha = HIGH_ALPHA - ALPHA_RANGE * (tsnr - xt) / tsnr, low <= alpha <= high */
	tmp = sub(st->tsnr, xt);						test(),logic16(),test(),test();
	if (tmp <= 0 || st->tsnr <= 0)
	{
		alpha = HIGH_ALPHA;								move16();
		one_m_alpha = 32768L-HIGH_ALPHA;						move16();
	}
	else if (sub(tmp, st->tsnr) > 0)
	{
		alpha = LOW_ALPHA;								move16();
		one_m_alpha = 32768L-LOW_ALPHA;							move16();
	}
	else
	{
		tmp = div_s(tmp, st->tsnr);
		alpha = sub(HIGH_ALPHA, mult(ALPHA_RANGE, tmp));
		one_m_alpha = sub(32767, alpha);
	}

	/* Calc long term log spectral energy */
	for (i = LO_CHAN; i <= HI_CHAN; i++)
	{
		Ltmp1 = L_mult(one_m_alpha, ch_enrg_db[i]);
		Ltmp2 = L_mult(alpha, st->ch_enrg_long_db[i]);
		st->ch_enrg_long_db[i] = round(L_add(Ltmp1, Ltmp2));
	}


	/* Set or clear the noise update flags */
	update_flag = FALSE;										move16();
	st->fupdate_flag = FALSE;									move16();
													test(),test();
	if (sub(vm_sum, UPDATE_THLD) <= 0)
	{												test();
		if (st->burstcount == 0)
		{
			update_flag = TRUE;								move16();
			st->update_cnt = 0;								move16();
		}
	}
	else if (L_sub(Ltce, noise_floor_chan[st->shift_state]) > 0)
	{												test();
		if (sub(ch_enrg_dev, DEV_THLD) < 0)
		{											test();
			if (p2a_flag == FALSE)
			{										test();
				if (st->LTP_flag == FALSE)
				{
					st->update_cnt = add(st->update_cnt, 1);			test();
					if (sub(st->update_cnt, UPDATE_CNT_THLD) >= 0)
					{
						update_flag = TRUE;					move16();
						st->fupdate_flag = TRUE;				move16();
					}
				}
			}
		}
	}
													test();
	if (sub(st->update_cnt, st->last_update_cnt) == 0)
	{
		st->hyster_cnt = add(st->hyster_cnt, 1);
	}
	else
	{
		st->hyster_cnt = 0;									move16();
	}

	st->last_update_cnt = st->update_cnt;								move16();
													test();
	if (sub(st->hyster_cnt, HYSTER_CNT_THLD) > 0)
	{
		st->update_cnt = 0;									move16();
	}


	/* Conditionally update the channel noise estimates */
													test();
	if (update_flag == TRUE)
	{
		/* Check shift state */									test();
		if (st->shift_state == 1)
		{
			/* get factor to shift ch_enrg[] from state 1 to 0 (noise always state 0) */
			tmp = state_change_shift_r[0];							move16();
		}
		else
		{
			/* No shift if already state 0 */
			tmp = 0;									move16();
		}

		/* Update noise energy estimate */
		for (i = LO_CHAN; i <= HI_CHAN; i++)
		{											test();
			/* integrate over time: en[i] = (1-alpha)*en[i] + alpha*e[n] */
			/* (extract with shift compensation for state 1) */
			L_Extract (L_shr(st->Lch_enrg[i], tmp), &hi1, &lo1);
			Ltmp = Mpy_32_16(hi1, lo1, CNE_SM_FAC);

			L_Extract (st->Lch_noise[i], &hi1, &lo1);
			st->Lch_noise[i] = L_add(Ltmp, Mpy_32_16(hi1, lo1, ONE_MINUS_CNE_SM_FAC));	move32();

			/* Limit low level noise */							test();
			if (L_sub(st->Lch_noise[i], MIN_NOISE_ENRG_0) < 0)
			{
				st->Lch_noise[i] = MIN_NOISE_ENRG_0;					move32();
			}
		}
	}

	return(ivad);
}								/* end of vad2 () */
Ejemplo n.º 21
0
void fndppf(short *delay, short *beta, short *buf, short dmin, short dmax, short length)
{
	static short b = -10224;	/* rom storage */

	static short a[3] =
	{-18739, 16024, -4882};		/* a[] scaled down by 4 */

	short dnew = 0;
	short sum;
	long Lsum;
	register short m, i, n;
	static short DECbuf[FrameSize / 4];
	long Lcorrmax, Lcmax, Ltmp;
	short tap1;
	short M1, M2, dnewtmp = 0;
	static short lastgoodpitch = 0;
	static short lastbeta = 0;
	static short memory[3];
	static int FirstTime = 1;
	short Lsum_scale;
	short shift, Lcorr_scale, Lcmax_scale;
	short n1, n2, nq, nq1;
	long Ltempf;
	/* init static variables (should be in init routine for implementation) */
	if (FirstTime)
	{
		FirstTime = 0;
		n1 = (shr(FrameSize, 2));
		for (i = 0; i < n1; i++)
			DECbuf[i] = 0;
		memory[0] = memory[1] = memory[2] = 0;
	}

	/* Shift  memory of DECbuf */
	for (i = 0; i < shr(length, 3); i++)
	{
		DECbuf[i] = DECbuf[i + shr(length, 3)];
	}
	/* filter signal and decimate */
	for (i = 0, n = shr(length, 3); i < shr(length, 1); i++)
	{
		Ltempf = L_shr(L_deposit_h(buf[i + shr(length, 1)]), 4);
		Ltempf = L_msu(Ltempf, memory[0], a[0]);
		Ltempf = L_msu(Ltempf, memory[1], a[1]);
		Ltempf = L_msu(Ltempf, memory[2], a[2]);
		Ltempf = L_shl(Ltempf, 2);

		shift = 0;
		if ((i + 1) % 4 == 0)
		{
			Lsum = L_add(Ltempf, L_deposit_h(memory[2]));
			Lsum = L_mac(Lsum, memory[0], b);
			Lsum = L_mac(Lsum, memory[1], b);

			DECbuf[n++] = round(L_shl(Lsum, 1));
		}
		memory[2] = memory[1];
		memory[1] = memory[0];
		memory[0] = round(Ltempf);
	}

	/* perform first search for best delay value in decimated domain */
	Lcorrmax = (LW_MIN);
        Lcorr_scale = 1;

	for (m = shr(dmin, 2); m <= shr(dmax, 2); m++)
	{
                n1 = 1;
		for (i = 0, Lsum = 0; i < sub(shr(length, 2), m); i++)
		{
			Ltempf = L_mult(DECbuf[i], DECbuf[i + m]);
			Ltempf = L_shr(Ltempf, n1);
			Lsum = L_add(Lsum, Ltempf);
			if (L_abs(Lsum) >= 0x40000000)
			{
				Lsum = L_shr(Lsum, 1);
				n1++;
			}
		}
		if (
		    ((Lcorr_scale >= n1) && (L_shr(Lsum, sub(Lcorr_scale, n1)) > Lcorrmax))
		 || ((Lcorr_scale < n1) && (Lsum > L_shr(Lcorrmax, sub(n1, Lcorr_scale))))
		 ) 
		{
			Lcorrmax = Lsum;
			Lcorr_scale = n1;
			dnew = m;
		}

	}

	/* Compare against lastgoodpitch */
	if (lastgoodpitch != 0 && (abs_s(sub(lastgoodpitch, shl(dnew, 2))) > 2))
	{
		M1 = sub(shr(lastgoodpitch, 2), 2);
		if (M1 < shr(dmin, 2))
			M1 = shr(dmin, 2);
		M2 = add(M1, 4);
		if (M2 > shr(dmax, 2))
			M2 = shr(dmax, 2);

		Lcmax = LW_MIN;
                Lcmax_scale = 1;
		for (m = M1; m <= M2; m++)
		{
                        n1 = 1;
			for (i = 0, Lsum = 0; i < sub(shr(length, 2), m); i++)
			{
				Ltempf = L_mult(DECbuf[i], DECbuf[i + m]);
				Ltempf = L_shr(Ltempf, n1);
				Lsum = L_add(Lsum, Ltempf);
				if (L_abs(Lsum) >= 0x40000000)
				{
					Lsum = L_shr(Lsum, 1);
					n1++;
				}
			}

			if (
			    ((Lcmax_scale >= n1) && (L_shr(Lsum, sub(Lcmax_scale, n1)) > Lcmax))
			 || ((Lcmax_scale < n1) && (Lsum > L_shr(Lcmax, sub(n1, Lcmax_scale))))
			   ) 
			{					/* Gives some bias to low delays */
				Lcmax = Lsum;
				Lcmax_scale = n1;
				dnewtmp = m;
			}
		}
		Lsum = L_mpy_ls(Lcorrmax, 27361);
		if (
		    ((Lcmax_scale >= Lcorr_scale) && (L_shr(Lsum, sub(Lcmax_scale, Lcorr_scale)) < Lcmax))
		 || ((Lcmax_scale < Lcorr_scale) && (Lsum < L_shr(Lcmax, sub(Lcorr_scale, Lcmax_scale))))
		   ) 
		{
			dnew = dnewtmp;
		}
	}

	/* perform first search for best delay value in non-decimated buffer */
	M1 = Max(sub(shl(dnew, 2), 3), dmin);
	if (M1 < dmin)
		M1 = dmin;
	M2 = Min(add(shl(dnew, 2), 3), dmax);
	if (M2 > dmax)
		M2 = dmax;
	Lcorrmax = LW_MIN;
        Lcorr_scale = 1;
	for (m = M1; m <= M2; m++)
	{
                n1 = 1;
		for (i = 0, Lsum = 0; i < sub(length, m); i++)
		{
			Ltempf = L_mult(buf[i], buf[i + m]);

			Ltempf = L_shr(Ltempf, n1);
			Lsum = L_add(Lsum, Ltempf);
			if (L_abs(Lsum) >= 0x40000000)
			{
				Lsum = L_shr(Lsum, 1);
				n1++;
			}
		}

		if (
		    ((Lcorr_scale >= n1) && (L_shr(Lsum, sub(Lcorr_scale, n1)) > Lcorrmax))
		 || ((Lcorr_scale < n1) && (Lsum > L_shr(Lcorrmax, sub(n1, Lcorr_scale))))
		   ) 
		{
			Lcorrmax = Lsum;
			Lcorr_scale = n1;
			dnew = m;
		}
	}
        Lsum_scale = 1;
	for (i = 0, Lsum = 0; i < sub(length, dnew); i++)
	{
		Ltempf = L_mult(buf[i + dnew], buf[i + dnew]);
		Ltempf = L_shr(Ltempf, Lsum_scale);
		Lsum = L_add(Lsum, Ltempf);
		if (L_abs(Lsum) >= 0x40000000)
		{
			Lsum = L_shr(Lsum, 1);
			Lsum_scale++;
		}
	}

        Lcmax_scale = 1;
	for (i = 0, Lcmax = 0; i < length - dnew; i++)
	{
		Ltempf = L_mult(buf[i], buf[i]);
		Ltempf = L_shr(Ltempf, Lcmax_scale);
		Lcmax = L_add(Lcmax, Ltempf);
		if (L_abs(Lcmax) >= 0x40000000)
		{
			Lcmax = L_shr(Lcmax, 1);
			Lcmax_scale++;
		}
	}
	nq = norm_l(Lsum);
	Lsum = L_shl(Lsum, nq);
	nq1 = norm_l(Lcmax);
	Lcmax = L_shl(Lcmax, nq1);
	Lsum = L_mpy_ll(Lsum, Lcmax);
	n1 = norm_l(Lsum);
	Lsum = L_shl(Lsum, n1);
	sum = sqroot(Lsum);
	n1 = add(add(n1, nq), nq1);
	n1 = sub(sub(n1, Lcmax_scale), Lsum_scale);
	n2 = shr(n1, 1);

	if (n1 & 1)
		Lsum = L_mult(sum, 23170);
	else
		Lsum = L_deposit_h(sum);

	n2 = add(n2, Lcorr_scale);
	Lcorrmax = L_shl(Lcorrmax, n2);

	if ((Lsum == 0) || (Lcorrmax <= 0))
		*beta = 0;
	else if (Lcorrmax > Lsum)
		*beta = 0x7fff;
	else
		*beta = round(L_divide(Lcorrmax, Lsum));

	/* perform search for best delay value in around old pitch delay */
	if (lastgoodpitch != 0)
	{
		M1 = lastgoodpitch - 6;
		M2 = lastgoodpitch + 6;

		if (M1 < dmin)
			M1 = dmin;
		if (M2 > dmax)
			M2 = dmax;

		if (dnew > M2 || dnew < M1)
		{
			Lcmax = LW_MIN;
                        Lcmax_scale = 1;
			for (m = M1; m <= M2; m++)
			{
                                n1 = 1;
				for (i = 0, Lsum = 0; i < length - m; i++)
				{
					Ltempf = L_mult(buf[i], buf[i + m]);
					Ltempf = L_shr(Ltempf, n1);
					Lsum = L_add(Lsum, Ltempf);
					if (L_abs(Lsum) >= 0x40000000)
					{
						Lsum = L_shr(Lsum, 1);
						n1++;
					}
				}

				if (
				    ((Lcmax_scale >= n1) && (L_shr(Lsum, sub(Lcmax_scale, n1)) > Lcmax))
				 || ((Lcmax_scale < n1) && (Lsum > L_shr(Lcmax, sub(n1, Lcmax_scale))))
				   ) 
				{
					Lcmax = Lsum;
					dnewtmp = m;
					Lcmax_scale = n1;
				}
			}
                        Lcorr_scale = 1;
			for (i = 0, Ltmp = 0; i < length - dnewtmp; i++)
			{
				Ltempf = L_mult(buf[i + dnewtmp], buf[i + dnewtmp]);
				Ltempf = L_shr(Ltempf, Lcorr_scale);
				Ltmp = L_add(Ltmp, Ltempf);
				if (L_abs(Ltmp) >= 0x40000000)
				{
					Ltmp = L_shr(Ltmp, 1);
					Lcorr_scale++;
				}

			}
                        Lsum_scale = 1;
			for (i = 0, Lsum = 0; i < length - dnewtmp; i++)
			{

				Ltempf = L_mult(buf[i], buf[i]);
				Ltempf = L_shr(Ltempf, Lsum_scale);
				Lsum = L_add(Lsum, Ltempf);
				if (L_abs(Lsum) >= 0x40000000)
				{
					Lsum = L_shr(Lsum, 1);
					Lsum_scale++;
				}
			}

			nq = norm_l(Ltmp);
			Ltmp = L_shl(Ltmp, nq);
			nq1 = norm_l(Lsum);
			Lsum = L_shl(Lsum, nq1);
			Ltmp = L_mpy_ll(Ltmp, Lsum);
			n1 = norm_l(Ltmp);
			Ltmp = L_shl(Ltmp, n1);
			sum = sqroot(Ltmp);

			n1 = add(add(n1, nq), nq1);
			n1 = sub(sub(n1, Lsum_scale), Lcorr_scale);
			n2 = shr(n1, 1);

			if (n1 & 1)
				Ltmp = L_mult(sum, 23170);
			else
				Ltmp = L_deposit_h(sum);

			n2 = add(n2, Lcmax_scale);
			Lcmax = L_shl(Lcmax, n2);

			if ((Ltmp == 0) || (Lcmax <= 0))
				tap1 = 0;
			else if (Lcmax >= Ltmp)
				tap1 = 0x7fff;
			else
				tap1 = round(L_divide(Lcmax, Ltmp));

			/* Replace dnew with dnewtmp if tap1 is large enough */
			if ((dnew > M2 && (shr(tap1, 1) > mult_r(9830, *beta))) ||
				(dnew < M1 && (shr(tap1, 1) > mult_r(19661, *beta))))
			{
				dnew = dnewtmp;
				*beta = (tap1);
			}
		}
	}

	*delay = dnew;
	if (*beta > 13107)
	{
		lastgoodpitch = dnew;
		lastbeta = *beta;
	}
	else
	{
		lastbeta = mult_r(24576, lastbeta);
		if (lastbeta < 9830)
			lastgoodpitch = 0;
	}
}
Ejemplo n.º 22
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;
}
Ejemplo n.º 23
0
/*
**
** Function:           Calc_Exc_Rand()
**
** Description:        Computation of random excitation for inactive frames:
**                     Adaptive codebook entry selected randomly
**                     Higher rate innovation pattern selected randomly
**                     Computes innovation gain to match curGain
**
** Links to text:
**
** Arguments:
**
**  Word16 curGain     current average gain to match
**  Word16 *PrevExc    previous/current excitation (updated)
**  Word16 *DataEXc    current frame excitation
**  Word16 *nRandom    random generator status (input/output)
**
** Outputs:
**
**  Word16 *PrevExc
**  Word16 *DataExc
**  Word16 *nRandom
**
** Return value:       None
**
*/
void Calc_Exc_Rand(Word16 curGain, Word16 *PrevExc, Word16 *DataExc,
                                      Word16 *nRandom, LINEDEF *Line)
{
    int i, i_subfr, iblk;
    Word16 temp, temp2;
    Word16 j;
    Word16 TabPos[2*NbPulsBlk], TabSign[2*NbPulsBlk];
    Word16 *ptr_TabPos, *ptr_TabSign;
    Word16 *ptr1, *curExc;
    Word16 sh1, x1, x2, inter_exc, delta, b0;
    Word32 L_acc, L_c, L_temp;
    Word16 tmp[SubFrLen/Sgrid];
    Word16 offset[SubFrames];
    Word16 tempExc[SubFrLenD];

 /*
  * generate LTP codes
  */
    Line->Olp[0] = random_number(21, nRandom) + (Word16)123;
    Line->Olp[1] = random_number(21, nRandom) + (Word16)123;
    for(i_subfr=0; i_subfr<SubFrames; i_subfr++) {  /* in [1, NbFilt] */
        Line->Sfs[i_subfr].AcGn = random_number(NbFilt, nRandom) + (Word16)1;
    }
    Line->Sfs[0].AcLg = 1;
    Line->Sfs[1].AcLg = 0;
    Line->Sfs[2].AcLg = 1;
    Line->Sfs[3].AcLg = 3;


 /*
  * Random innovation :
  * Selection of the grids, signs and pulse positions
  */

    /* Signs and Grids */
    ptr_TabSign = TabSign;
    ptr1 = offset;
    for(iblk=0; iblk<SubFrames/2; iblk++) {
        temp    = random_number((1 << (NbPulsBlk+2)), nRandom);
        *ptr1++ = temp & (Word16)0x0001;
        temp    = shr(temp, 1);
        *ptr1++ = add( (Word16) SubFrLen, (Word16) (temp & 0x0001) );
        for(i=0; i<NbPulsBlk; i++) {
            *ptr_TabSign++= shl(sub((temp & (Word16)0x0002), 1), 14);
            temp = shr(temp, 1);
        }
    }

    /* Positions */
    ptr_TabPos  = TabPos;
    for(i_subfr=0; i_subfr<SubFrames; i_subfr++) {

        for(i=0; i<(SubFrLen/Sgrid); i++) tmp[i] = (Word16)i;
        temp = (SubFrLen/Sgrid);
        for(i=0; i<Nb_puls[i_subfr]; i++) {
            j = random_number(temp, nRandom);
            *ptr_TabPos++ = add(shl(tmp[(int)j],1), offset[i_subfr]);
            temp = sub(temp, 1);
            tmp[(int)j] = tmp[(int)temp];
        }
    }

 /*
  * Compute fixed codebook gains
  */

    ptr_TabPos = TabPos;
    ptr_TabSign = TabSign;
    curExc = DataExc;
    i_subfr = 0;
    for(iblk=0; iblk<SubFrames/2; iblk++) {

        /* decode LTP only */
        Decod_Acbk(curExc, &PrevExc[0], Line->Olp[iblk],
                    Line->Sfs[i_subfr].AcLg, Line->Sfs[i_subfr].AcGn);
        Decod_Acbk(&curExc[SubFrLen], &PrevExc[SubFrLen], Line->Olp[iblk],
            Line->Sfs[i_subfr+1].AcLg, Line->Sfs[i_subfr+1].AcGn);

        temp2 = 0;
        for(i=0; i<SubFrLenD; i++) {
            temp = abs_s(curExc[i]);
            if(temp > temp2) temp2 = temp;
        }
        if(temp2 == 0) sh1 = 0;
        else {
            sh1 = sub(4,norm_s(temp2)); /* 4 bits of margin  */
            if(sh1 < -2) sh1 = -2;
        }

        L_temp = 0L;
        for(i=0; i<SubFrLenD; i++) {
            temp  = shr(curExc[i], sh1); /* left if sh1 < 0 */
            L_temp = L_mac(L_temp, temp, temp);
            tempExc[i] = temp;
        }  /* ener_ltp x 2**(-2sh1+1) */

        L_acc = 0L;
        for(i=0; i<NbPulsBlk; i++) {
            L_acc = L_mac(L_acc, tempExc[(int)ptr_TabPos[i]], ptr_TabSign[i]);
        }
        inter_exc = extract_h(L_shl(L_acc, 1)); /* inter_exc x 2-sh1 */

        /* compute SubFrLenD x curGain**2 x 2**(-2sh1+1)    */
        /* curGain input = 2**5 curGain                     */
//        L_acc = L_mult(curGain, SubFrLen);
		L_MULT(curGain, SubFrLen, L_acc);
        L_acc = L_shr(L_acc, 6);
        temp  = extract_l(L_acc);   /* SubFrLen x curGain : avoids overflows */
 //       L_acc = L_mult(temp, curGain);
		L_MULT(temp, curGain, L_acc);
        temp = shl(sh1, 1);
        temp = add(temp, 4);
        L_acc = L_shr(L_acc, temp); /* SubFrLenD x curGain**2 x 2**(-2sh1+1) */

        /* c = (ener_ltp - SubFrLenD x curGain**2)/nb_pulses_blk */
        /* compute L_c = c >> 2sh1-1                                */
        L_acc = L_sub(L_temp, L_acc);
        /* x 1/nb_pulses_blk */
        L_c  = L_mls(L_acc, InvNbPulsBlk);

/*
 * Solve EQ(X) = X**2 + 2 b0 X + c
 */
        /* delta = b0 x b0 - c */
        b0 = mult_r(inter_exc, InvNbPulsBlk);   /* b0 >> sh1 */
        L_acc = L_msu(L_c, b0, b0);             /* (c - b0**2) >> 2sh1-1 */
        L_acc = L_negate(L_acc);                /* delta x 2**(-2sh1+1) */

        /* Case delta <= 0 */
        if(L_acc <= 0) {  /* delta <= 0 */
            x1 = negate(b0);        /* sh1 */
        }

        /* Case delta > 0 */
        else {
            delta = Sqrt_lbc(L_acc);  /* >> sh1 */
            x1 = sub(delta, b0);      /* x1 >> sh1 */
            x2 = add(b0, delta);      /* (-x2) >> sh1 */
            if(abs_s(x2) < abs_s(x1)) {
                x1 = negate(x2);
            }
        }

        /* Update DataExc */
        sh1 = add(sh1, 1);
        temp = shl(x1, sh1);
        if(temp > (2*Gexc_Max)) temp = (2*Gexc_Max);
        if(temp < -(2*Gexc_Max)) temp = -(2*Gexc_Max);
        for(i=0; i<NbPulsBlk; i++) {
            j = *ptr_TabPos++;
            curExc[(int)j] = add(curExc[(int)j], mult(temp,
                                                (*ptr_TabSign++)) );
        }

        /* update PrevExc */
        ptr1 = PrevExc;
        for(i=SubFrLenD; i<PitchMax; i++)   *ptr1++ = PrevExc[i];
        for(i=0; i<SubFrLenD; i++)  *ptr1++ = curExc[i];

        curExc += SubFrLenD;
        i_subfr += 2;

    } /* end of loop on LTP blocks */

    return;
}
void QD0_OnCompare(void)
{
  /* finding of source of interrupt (COMPARE1 or COMPARE2) */
  Timer0Value=getReg(TMRA0_CNTR);
  Timer0Difference1=abs_s((Timer0Value-QD0_GetCompare1Value()));
  Timer0Difference2=abs_s((Timer0Value-QD0_GetCompare2Value()));
//  can_printf("CMP1 %d", QD0_GetCompare1Value());
//  can_printf("CMP2 %d", QD0_GetCompare2Value());
//  can_printf("T %d",Timer0Value);
//  can_printf("DF2 %d DF1 ,%d",Timer0Difference2, Timer0Difference1);	
  /* according to finding of interrupt source */
  if (Timer0Difference1<Timer0Difference2)
    {
    /* set direction of spinning */
    DirectionSpinning0 = 1;
    
    /* increment commutation counter */
    if (CommutationCounter0<6) 
    {
      CommutationCounter0++;
    }
    else 
    {
      CommutationCounter0=1;
    }
   
    /* set new value to COMPARE1/2 registers and compensate rounding of NORMAL_COMMUTATION_INTERVAL */
    if (CommutationCounter0==4) 
    {
      QD0_SetCompare1(QD0_GetCompare1Value() + SHORT_COMMUTATION_INTERVAL);
      QD0_SetCompare2(QD0_GetCompare2Value() + SHORT_COMMUTATION_INTERVAL);
  
    }
    else 
    {
      QD0_SetCompare1(QD0_GetCompare1Value() + NORMAL_COMMUTATION_INTERVAL);
      QD0_SetCompare2(QD0_GetCompare2Value() + NORMAL_COMMUTATION_INTERVAL);
    }
  }
  else 
  {
    /* set direction of spinning */
    DirectionSpinning0 = -1;
    /* decrement commutation counter */
    if (CommutationCounter0>1) 
    {
      CommutationCounter0--;
    }
    else 
    {
      CommutationCounter0=6;
    }
    /* set new value to COMPARE1/2 registers and compensate rounding of NORMAL_COMMUTATION_INTERVAL */
    if (CommutationCounter0==3) 
    {
      QD0_SetCompare2(QD0_GetCompare2Value() - SHORT_COMMUTATION_INTERVAL);
      QD0_SetCompare1(QD0_GetCompare1Value() - SHORT_COMMUTATION_INTERVAL);
    }
    else 
    {
      QD0_SetCompare2(QD0_GetCompare2Value() - NORMAL_COMMUTATION_INTERVAL);
      QD0_SetCompare1(QD0_GetCompare1Value() - NORMAL_COMMUTATION_INTERVAL);
    }
  }
  
  status0 = COMMUTATION_CONVERSION_TABLE[CommutationCounter0];
  
  // write mask to PWM Channel Control Register 
  PWMState[0]= pTable0[status0];
  tmp = getReg(PWMA_PMOUT) & 0x8000;
  val=tmp | PWMState[0].MaskOut | (PWMState[0].Mask<<8);
  setReg(PWMA_PMOUT,val); 
  old_status0 = status0;
}
Ejemplo n.º 25
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;
}
Ejemplo n.º 26
0
void A_Refl(
    Word16 a[],        /* i   : Directform coefficients */
    Word16 refl[],     /* o   : Reflection coefficients */
    Flag   *pOverflow
)
{
    /* local variables */
    Word16 i;
    Word16 j;
    Word16 aState[M];
    Word16 bState[M];
    Word16 normShift;
    Word16 normProd;
    Word32 L_acc;
    Word16 scale;
    Word32 L_temp;
    Word16 temp;
    Word16 mult;

    /* initialize states */
    for (i = 0; i < M; i++)
    {
        aState[i] = a[i];
    }

    /* backward Levinson recursion */
    for (i = M - 1; i >= 0; i--)
    {
        if (abs_s(aState[i]) >= 4096)
        {
            for (i = 0; i < M; i++)
            {
                refl[i] = 0;
            }
            break;
        }

        refl[i] = shl(aState[i], 3, pOverflow);

        L_temp = L_mult(refl[i], refl[i], pOverflow);
        L_acc = L_sub(MAX_32, L_temp, pOverflow);

        normShift = norm_l(L_acc);
        scale = sub(15, normShift, pOverflow);

        L_acc = L_shl(L_acc, normShift, pOverflow);
        normProd = pv_round(L_acc, pOverflow);

        mult = div_s(16384, normProd);

        for (j = 0; j < i; j++)
        {
            L_acc = L_deposit_h(aState[j]);
            L_acc = L_msu(L_acc, refl[i], aState[i-j-1], pOverflow);

            temp = pv_round(L_acc, pOverflow);
            L_temp = L_mult(mult, temp, pOverflow);
            L_temp = L_shr_r(L_temp, scale, pOverflow);

            if (L_abs(L_temp) > 32767)
            {
                for (i = 0; i < M; i++)
                {
                    refl[i] = 0;
                }
                break;
            }

            bState[j] = extract_l(L_temp);
        }

        for (j = 0; j < i; j++)
        {
            aState[j] = bState[j];
        }
    }
    return;
}
Ejemplo n.º 27
0
/*-----------------------------------------------------------*
 * procedure Cod_cng:                                        *
 *           ~~~~~~~~                                        *
 *   computes DTX decision                                   *
 *   encodes SID frames                                      *
 *   computes CNG excitation for encoder update              *
 *-----------------------------------------------------------*/
void Cod_cng(
  DtxStatus *handle,
  Word16 *exc,          /* (i/o) : excitation array                     */
  Word16 pastVad,       /* (i)   : previous VAD decision                */
  Word16 *lsp_old_q,    /* (i/o) : previous quantized lsp               */
  Word16 *Aq,           /* (o)   : set of interpolated LPC coefficients */
  Word16 *ana,          /* (o)   : coded SID parameters                 */
  Word16 freq_prev[MA_NP][M],
                        /* (i/o) : previous LPS for quantization        */
  Word16 *seed          /* (i/o) : random generator seed                */
)
{

  Word16 i;

  Word16 curAcf[MP1];
  Word16 bid[M], zero[MP1];
  Word16 curCoeff[MP1];
  Word16 lsp_new[M];
  Word16 *lpcCoeff;
  Word16 cur_igain;
  Word16 energyq, temp;

  /* Update Ener and sh_ener */
  for(i = NB_GAIN-1; i>=1; i--) {
    handle->ener[i] = handle->ener[i-1];
    handle->sh_ener[i] = handle->sh_ener[i-1];
  }

  /* Compute current Acfs */
  Calc_sum_acf(handle->Acf, handle->sh_Acf, curAcf, &(handle->sh_ener[0]), NB_CURACF);

  /* Compute LPC coefficients and residual energy */
  if(curAcf[0] == 0) {
    handle->ener[0] = 0;                /* should not happen */
  }
  else {
    Set_zero(zero, MP1);
    Levinson(handle, curAcf, zero, curCoeff, bid, &(handle->ener[0]));
  }

  /* if first frame of silence => SID frame */
  if(pastVad != 0) {
    ana[0] = 2;
    handle->count_fr0 = 0;
    handle->nb_ener = 1;
    Qua_Sidgain(handle->ener, handle->sh_ener, handle->nb_ener, &energyq, &cur_igain);

  }
  else {
    handle->nb_ener = add(handle->nb_ener, 1);
    if(sub(handle->nb_ener, NB_GAIN) > 0) handle->nb_ener = NB_GAIN;
    Qua_Sidgain(handle->ener, handle->sh_ener, handle->nb_ener, &energyq, &cur_igain);
      
    /* Compute stationarity of current filter   */
    /* versus reference filter                  */
    if(Cmp_filt(handle->RCoeff, handle->sh_RCoeff, curAcf, handle->ener[0], FRAC_THRESH1) != 0) {
      handle->flag_chang = 1;
    }
      
    /* compare energy difference between current frame and last frame */
    temp = abs_s(sub(handle->prev_energy, energyq));
    temp = sub(temp, 2);
    if (temp > 0) handle->flag_chang = 1;
      
    handle->count_fr0 = add(handle->count_fr0, 1);
    if(sub(handle->count_fr0, FR_SID_MIN) < 0) {
      ana[0] = 0;               /* no transmission */
    }
    else {
      if(handle->flag_chang != 0) {
        ana[0] = 2;             /* transmit SID frame */
      }
      else{
        ana[0] = 0;
      }
        
      handle->count_fr0 = FR_SID_MIN;   /* to avoid overflow */
    }
  }


  if(sub(ana[0], 2) == 0) {
      
    /* Reset frame count and change flag */
    handle->count_fr0 = 0;
    handle->flag_chang = 0;
      
    /* Compute past average filter */
    Calc_pastfilt(handle, handle->pastCoeff);
    Calc_RCoeff(handle->pastCoeff, handle->RCoeff, &(handle->sh_RCoeff));

    /* Compute stationarity of current filter   */
    /* versus past average filter               */


    /* if stationary */
    /* transmit average filter => new ref. filter */
    if(Cmp_filt(handle->RCoeff, handle->sh_RCoeff, curAcf, handle->ener[0], FRAC_THRESH2) == 0) {
      lpcCoeff = handle->pastCoeff;
    }

    /* else */
    /* transmit current filter => new ref. filter */
    else {
      lpcCoeff = curCoeff;
      Calc_RCoeff(curCoeff, handle->RCoeff, &(handle->sh_RCoeff));
    }

    /* Compute SID frame codes */

    Az_lsp(lpcCoeff, lsp_new, lsp_old_q); /* From A(z) to lsp */

    /* LSP quantization */
    lsfq_noise(lsp_new, handle->lspSid_q, freq_prev, &ana[1]);

    handle->prev_energy = energyq;
    ana[4] = cur_igain;
    handle->sid_gain = tab_Sidgain[cur_igain];


  } /* end of SID frame case */

  /* Compute new excitation */
  if(pastVad != 0) {
    handle->cur_gain = handle->sid_gain;
  }
  else {
    handle->cur_gain = mult_r(handle->cur_gain, A_GAIN0);
    handle->cur_gain = add(handle->cur_gain, mult_r(handle->sid_gain, A_GAIN1));
  }

  Calc_exc_rand(handle->L_exc_err, handle->cur_gain, exc, seed, FLAG_COD);

  Int_qlpc(lsp_old_q, handle->lspSid_q, Aq);
  for(i=0; i<M; i++) {
    lsp_old_q[i]   = handle->lspSid_q[i];
  }

  /* Update sumAcf if fr_cur = 0 */
  if(handle->fr_cur == 0) {
    Update_sumAcf(handle);
  }

  return;
}
Ejemplo n.º 28
0
/***************************************************************************
 Function:    vector_huffman

 Syntax:      Word16 vector_huffman(Word16  category,     
                                    Word16  power_index,  
                                    Word16  *raw_mlt_ptr,  
                                    UWord32 *word_ptr)     
                                              
              inputs:     Word16  category
                          Word16  power_index
                          Word16  *raw_mlt_ptr
             
              outputs:    number_of_region_bits
                          *word_ptr
                                      

 Description: Huffman encoding for each region based on category and power_index  

 WMOPS:     7kHz |    24kbit    |     32kbit
          -------|--------------|----------------
            AVG  |    0.03      |     0.03
          -------|--------------|----------------  
            MAX  |    0.04      |     0.04
          -------|--------------|---------------- 

           14kHz |    24kbit    |     32kbit     |     48kbit
          -------|--------------|----------------|----------------
            AVG  |    0.03      |     0.03       |     0.03
          -------|--------------|----------------|----------------
            MAX  |    0.04      |     0.04       |     0.04
          -------|--------------|----------------|----------------

***************************************************************************/
Word16 vector_huffman(Word16 category,
                      Word16 power_index,
                      Word16 *raw_mlt_ptr,
                      UWord32 *word_ptr)
{
 

    Word16  inv_of_step_size_times_std_dev;
    Word16  j,n;
    Word16  k;
    Word16  number_of_region_bits;
    Word16  number_of_non_zero;
    Word16  vec_dim;
    Word16  num_vecs;
    Word16  kmax, kmax_plus_one;
    Word16  index,signs_index;
    Word16  *bitcount_table_ptr;
    UWord16 *code_table_ptr;
    Word32  code_bits;
    Word16  number_of_code_bits;
    UWord32 current_word;
    Word16  current_word_bits_free;
    
    Word32 acca;
    Word32 accb;
    Word16 temp;

    Word16 mytemp;			 /* new variable in Release 1.2 */
    Word16 myacca;			 /* new variable in Release 1.2 */


    /* initialize variables */
    vec_dim = vector_dimension[category];
    move16();

    num_vecs = number_of_vectors[category];
    move16();

    kmax = max_bin[category];
    move16();

    kmax_plus_one = add(kmax,1);
    move16();

    current_word = 0L;
    move16();

    current_word_bits_free = 32;
    move16();

    number_of_region_bits = 0;
    move16();

    /* set up table pointers */
    bitcount_table_ptr = (Word16 *)table_of_bitcount_tables[category];
    code_table_ptr = (UWord16 *) table_of_code_tables[category];

    /* compute inverse of step size * standard deviation */
    acca = L_mult(step_size_inverse_table[category],standard_deviation_inverse_table[power_index]);
    acca = L_shr_nocheck(acca,1);
    acca = L_add(acca,4096);
    acca = L_shr_nocheck(acca,13);

	/*
	 *  The next two lines are new to Release 1.2 
	 */
     
	mytemp = (Word16)(acca & 0x3);
    acca = L_shr_nocheck(acca,2);

    inv_of_step_size_times_std_dev = extract_l(acca);


    for (n=0; n<num_vecs; n++)
    {
        index = 0;
        move16();
        
        signs_index = 0;
        move16();
        
        number_of_non_zero = 0;
        move16();
        
        for (j=0; j<vec_dim; j++)
        {
            k = abs_s(*raw_mlt_ptr);
            
            acca = L_mult(k,inv_of_step_size_times_std_dev);
            acca = L_shr_nocheck(acca,1);
		    
			/*
			 *  The next four lines are new to Release 1.2
			 */

			myacca = (Word16)L_mult(k,mytemp);
			myacca = (Word16)L_shr_nocheck(myacca,1);
			myacca = (Word16)L_add(myacca,int_dead_zone_low_bits[category]);
			myacca = (Word16)L_shr_nocheck(myacca,2);

            acca = L_add(acca,int_dead_zone[category]);

			/*
			 *  The next two lines are new to Release 1.2
			 */

			acca = L_add(acca,myacca);
			acca = L_shr_nocheck(acca,13);

            k = extract_l(acca);

            test();
            if (k != 0)
            {
                number_of_non_zero = add(number_of_non_zero,1);
                signs_index = shl_nocheck(signs_index,1);
                
                test();
                if (*raw_mlt_ptr > 0)
                {
                    signs_index = add(signs_index,1);
                }
                
                temp = sub(k,kmax);
                test();
                if (temp > 0)
                {
                    k = kmax;
                    move16();
                }
            }
            acca = L_shr_nocheck(L_mult(index,(kmax_plus_one)),1);
            index = extract_l(acca);
            index = add(index,k);
            raw_mlt_ptr++;
        }

        code_bits = *(code_table_ptr+index);
        number_of_code_bits = add((*(bitcount_table_ptr+index)),number_of_non_zero);
        number_of_region_bits = add(number_of_region_bits,number_of_code_bits);

        acca = code_bits << number_of_non_zero;
        accb = L_deposit_l(signs_index);
        acca = L_add(acca,accb);
        code_bits = acca;
        move32();

        /* msb of codebits is transmitted first. */
        j = sub(current_word_bits_free,number_of_code_bits);
        test();
        if (j >= 0)
        {
            test();
            acca = code_bits << j;
            current_word = L_add(current_word,acca);
            current_word_bits_free = j;
            move16();
        }
        else
        {
            j = negate(j);
            acca = L_shr_nocheck(code_bits,j);
            current_word = L_add(current_word,acca);
            
            *word_ptr++ = current_word;
            move16();

            current_word_bits_free = sub(32,j);
            test();
            current_word = code_bits << current_word_bits_free;
        }
    }

    *word_ptr++ = current_word;
    move16();

    return (number_of_region_bits);
}
Ejemplo n.º 29
0
/*
**************************************************************************
*
*  Function    : Az_lsp
*  Purpose     : Compute the LSPs from  the LP coefficients
*
**************************************************************************
*/
void Az_lsp (
    Word16 a[],         /* (i)  : predictor coefficients (MP1)               */
    Word16 lsp[],       /* (o)  : line spectral pairs (M)                    */
    Word16 old_lsp[]    /* (i)  : old lsp[] (in case not found 10 roots) (M) */
)
{
    Word16 i, j, nf, ip;
    Word16 xlow, ylow, xhigh, yhigh, xmid, ymid, xint;
    Word16 x, y, sign, exp;
    Word16 *coef;
    Word16 f1[M / 2 + 1], f2[M / 2 + 1];
    Word32 t0;

    /*-------------------------------------------------------------*
     *  find the sum and diff. pol. F1(z) and F2(z)                *
     *    F1(z) <--- F1(z)/(1+z**-1) & F2(z) <--- F2(z)/(1-z**-1)  *
     *                                                             *
     * f1[0] = 1.0;                                                *
     * f2[0] = 1.0;                                                *
     *                                                             *
     * for (i = 0; i< NC; i++)                                     *
     * {                                                           *
     *   f1[i+1] = a[i+1] + a[M-i] - f1[i] ;                       *
     *   f2[i+1] = a[i+1] - a[M-i] + f2[i] ;                       *
     * }                                                           *
     *-------------------------------------------------------------*/

    f1[0] = 1024;                  move16 (); /* f1[0] = 1.0 */
    f2[0] = 1024;                  move16 (); /* f2[0] = 1.0 */

    for (i = 0; i < NC; i++)
    {
        t0 = L_mult (a[i + 1], 8192);   /* x = (a[i+1] + a[M-i]) >> 2  */
        t0 = L_mac (t0, a[M - i], 8192);
        x = extract_h (t0);
        /* f1[i+1] = a[i+1] + a[M-i] - f1[i] */
        f1[i + 1] = sub (x, f1[i]);move16 (); 

        t0 = L_mult (a[i + 1], 8192);   /* x = (a[i+1] - a[M-i]) >> 2 */
        t0 = L_msu (t0, a[M - i], 8192);
        x = extract_h (t0);
        /* f2[i+1] = a[i+1] - a[M-i] + f2[i] */
        f2[i + 1] = add (x, f2[i]);move16 (); 
    }

    /*-------------------------------------------------------------*
     * find the LSPs using the Chebychev pol. evaluation           *
     *-------------------------------------------------------------*/

    nf = 0;                        move16 (); /* number of found frequencies */
    ip = 0;                        move16 (); /* indicator for f1 or f2      */

    coef = f1;                     move16 (); 

    xlow = grid[0];                move16 (); 
    ylow = Chebps (xlow, coef, NC);move16 (); 

    j = 0;
    test (); test (); 
    /* while ( (nf < M) && (j < grid_points) ) */
    while ((sub (nf, M) < 0) && (sub (j, grid_points) < 0))
    {
        j++;
        xhigh = xlow;              move16 (); 
        yhigh = ylow;              move16 (); 
        xlow = grid[j];            move16 (); 
        ylow = Chebps (xlow, coef, NC);
                                   move16 (); 

        test (); 
        if (L_mult (ylow, yhigh) <= (Word32) 0L)
        {

            /* divide 4 times the interval */

            for (i = 0; i < 4; i++)
            {
                /* xmid = (xlow + xhigh)/2 */
                xmid = add (shr (xlow, 1), shr (xhigh, 1));
                ymid = Chebps (xmid, coef, NC);
                                   move16 (); 

                test (); 
                if (L_mult (ylow, ymid) <= (Word32) 0L)
                {
                    yhigh = ymid;  move16 (); 
                    xhigh = xmid;  move16 (); 
                }
                else
                {
                    ylow = ymid;   move16 (); 
                    xlow = xmid;   move16 (); 
                }
            }

            /*-------------------------------------------------------------*
             * Linear interpolation                                        *
             *    xint = xlow - ylow*(xhigh-xlow)/(yhigh-ylow);            *
             *-------------------------------------------------------------*/

            x = sub (xhigh, xlow);
            y = sub (yhigh, ylow);

            test (); 
            if (y == 0)
            {
                xint = xlow;       move16 (); 
            }
            else
            {
                sign = y;          move16 (); 
                y = abs_s (y);
                exp = norm_s (y);
                y = shl (y, exp);
                y = div_s ((Word16) 16383, y);
                t0 = L_mult (x, y);
                t0 = L_shr (t0, sub (20, exp));
                y = extract_l (t0);     /* y= (xhigh-xlow)/(yhigh-ylow) */

                test (); 
                if (sign < 0)
                    y = negate (y);

                t0 = L_mult (ylow, y);
                t0 = L_shr (t0, 11);
                xint = sub (xlow, extract_l (t0)); /* xint = xlow - ylow*y */
            }

            lsp[nf] = xint;        move16 (); 
            xlow = xint;           move16 (); 
            nf++;

            test (); 
            if (ip == 0)
            {
                ip = 1;            move16 (); 
                coef = f2;         move16 (); 
            }
            else
            {
                ip = 0;            move16 (); 
                coef = f1;         move16 (); 
            }
            ylow = Chebps (xlow, coef, NC);
                                   move16 (); 

        }
        test (); test (); 
    }

    /* Check if M roots found */

    test (); 
    if (sub (nf, M) < 0)
    {
        for (i = 0; i < M; i++)
        {
            lsp[i] = old_lsp[i];   move16 (); 
        }

    }
    return;
}
Ejemplo n.º 30
0
void Coder_ld8g(
  Word16 ana[],     /* (o)     : analysis parameters                        */
 Word16 frame,                   /* input : frame counter */
  Word16 dtx_enable,               /* input : DTX enable flag */
  Word16 rate           /* input   : rate selector/frame  =0 6.4kbps , =1 8kbps,= 2 11.8 kbps*/
)
{

  /* LPC analysis */
    Word16 r_l_fwd[NP+1], r_h_fwd[NP+1];    /* Autocorrelations low and hi (forward) */
    Word32 r_bwd[M_BWDP1];      /* Autocorrelations (backward) */
    Word16 r_l_bwd[M_BWDP1];      /* Autocorrelations low (backward) */
    Word16 r_h_bwd[M_BWDP1];      /* Autocorrelations high (backward) */
    Word16 rc_fwd[M];                 /* Reflection coefficients : forward analysis */
    Word16 rc_bwd[M_BWD];         /* Reflection coefficients : backward analysis */
    Word16 A_t_fwd[MP1*2];          /* A(z) forward unquantized for the 2 subframes */
    Word16 A_t_fwd_q[MP1*2];      /* A(z) forward quantized for the 2 subframes */
    Word16 A_t_bwd[2*M_BWDP1];    /* A(z) backward for the 2 subframes */
    Word16 *Aq;           /* A(z) "quantized" for the 2 subframes */
    Word16 *Ap;           /* A(z) "unquantized" for the 2 subframes */
    Word16 *pAp, *pAq;
    Word16 Ap1[M_BWDP1];          /* A(z) with spectral expansion         */
    Word16 Ap2[M_BWDP1];          /* A(z) with spectral expansion         */
    Word16 lsp_new[M], lsp_new_q[M]; /* LSPs at 2th subframe                 */
    Word16 lsf_int[M];               /* Interpolated LSF 1st subframe.       */
    Word16 lsf_new[M];
    Word16 lp_mode;                  /* Backward / Forward Indication mode */
    Word16 m_ap, m_aq, i_gamma;
    Word16 code_lsp[2];

    /* Other vectors */

    Word16 h1[L_SUBFR];            /* Impulse response h1[]              */
    Word16 xn[L_SUBFR];            /* Target vector for pitch search     */
    Word16 xn2[L_SUBFR];           /* Target vector for codebook search  */
    Word16 code[L_SUBFR];          /* Fixed codebook excitation          */
    Word16 y1[L_SUBFR];            /* Filtered adaptive excitation       */
    Word16 y2[L_SUBFR];            /* Filtered fixed codebook excitation */
    Word16 g_coeff[4];             /* Correlations between xn & y1       */
    Word16 res2[L_SUBFR];          /* residual after long term prediction*/
    Word16 g_coeff_cs[5];
    Word16 exp_g_coeff_cs[5];      /* Correlations between xn, y1, & y2
                                     <y1,y1>, -2<xn,y1>,
                                          <y2,y2>, -2<xn,y2>, 2<y1,y2> */
    /* Scalars */
    Word16 i, j, k, i_subfr;
    Word16 T_op, T0, T0_min, T0_max, T0_frac;
    Word16 gain_pit, gain_code, index;
    Word16 taming, pit_sharp;
    Word16 sat_filter;
    Word32 L_temp;
    Word16 freq_cur[M];

    /* For G.729B */
    Word16 rh_nbe[MP1];             
    Word16 lsfq_mem[MA_NP][M];
    Word16 exp_R0, Vad;
    Word16 tmp1, tmp2,avg_lag;
    
    Word16 temp, Energy_db;
    
/*------------------------------------------------------------------------*
 *  - Perform LPC analysis:                                               *
 *       * autocorrelation + lag windowing                                *
 *       * Levinson-durbin algorithm to find a[]                          *
 *       * convert a[] to lsp[]                                           *
 *       * quantize and code the LSPs                                     *
 *       * find the interpolated LSPs and convert to a[] for the 2        *
 *         subframes (both quantized and unquantized)                     *
 *------------------------------------------------------------------------*/
    /* ------------------- */
    /* LP Forward analysis */
    /* ------------------- */
    Autocorrg(p_window, NP, r_h_fwd, r_l_fwd, &exp_R0);    /* Autocorrelations */
    Copy(r_h_fwd, rh_nbe, MP1);
    Lag_window(NP, r_h_fwd, r_l_fwd);                     /* Lag windowing    */
    Levinsong(M, r_h_fwd, r_l_fwd, &A_t_fwd[MP1], rc_fwd, old_A_fwd, old_rc_fwd,&temp ); /* Levinson Durbin  */
    Az_lsp(&A_t_fwd[MP1], lsp_new, lsp_old);      /* From A(z) to lsp */
    
    /* For G.729B */
    /* ------ VAD ------- */
    if (dtx_enable == 1) {
        Lsp_lsf(lsp_new, lsf_new, M);
        vadg(rc_fwd[1], lsf_new, r_h_fwd, r_l_fwd, exp_R0, p_window, frame,
            pastVad, ppastVad, &Vad, &Energy_db);
        
        musdetect( rate, r_h_fwd[0], r_l_fwd[0], exp_R0,rc_fwd ,lag_buf , pgain_buf,
            prev_lp_mode, frame,pastVad, &Vad, Energy_db);
        
        Update_cng(rh_nbe, exp_R0, Vad);
    }
    else Vad = 1;
    

    /* -------------------- */
    /* LP Backward analysis */
    /* -------------------- */
    /* -------------------- */
    /* LP Backward analysis */
    /* -------------------- */
    if ( (rate-(1-Vad))== G729E) {
        
        /* LPC recursive Window as in G728 */
        autocorr_hyb_window(synth, r_bwd, rexp); /* Autocorrelations */
        
        Lag_window_bwd(r_bwd, r_h_bwd, r_l_bwd);  /* Lag windowing    */
        
        /* Fixed Point Levinson (as in G729) */
        Levinsong(M_BWD, r_h_bwd, r_l_bwd, &A_t_bwd[M_BWDP1], rc_bwd,
            old_A_bwd, old_rc_bwd, &temp );
        
        /* Tests saturation of A_t_bwd */
        sat_filter = 0;
        for (i=M_BWDP1; i<2*M_BWDP1; i++) if (A_t_bwd[i] >= 32767) sat_filter = 1;
        if (sat_filter == 1) Copy(A_t_bwd_mem, &A_t_bwd[M_BWDP1], M_BWDP1);
        else Copy(&A_t_bwd[M_BWDP1], A_t_bwd_mem, M_BWDP1);
        
        /* Additional bandwidth expansion on backward filter */
        Weight_Az(&A_t_bwd[M_BWDP1], GAMMA_BWD, M_BWD, &A_t_bwd[M_BWDP1]);
    }
    /*--------------------------------------------------*
    * Update synthesis signal for next frame.          *
    *--------------------------------------------------*/
    Copy(&synth[L_FRAME], &synth[0], MEM_SYN_BWD);
    
    /*--------------------------------------------------------------------*
    * Find interpolated LPC parameters in all subframes (unquantized).                                                  *
    * The interpolated parameters are in array A_t[] of size (M+1)*4     *
    *--------------------------------------------------------------------*/
    if( prev_lp_mode == 0) {
        Int_lpc(lsp_old, lsp_new, lsf_int, lsf_new, A_t_fwd);
    }
    else {
        /* no interpolation */
        /* unquantized */
        Lsp_Az(lsp_new, A_t_fwd);           /* Subframe 1 */
        Lsp_lsf(lsp_new, lsf_new, M);  /* transformation from LSP to LSF (freq.domain) */
        Copy(lsf_new, lsf_int, M);      /* Subframe 1 */
        
    }
    
    if(Vad == 1) {
        /* ---------------- */
        /* LSP quantization */
        /* ---------------- */
        Qua_lspe(lsp_new, lsp_new_q, code_lsp, freq_prev, freq_cur);

        /*--------------------------------------------------------------------*
        * Find interpolated LPC parameters in all subframes (quantized)  *
        * the quantized interpolated parameters are in array Aq_t[]      *
        *--------------------------------------------------------------------*/
        if( prev_lp_mode == 0) {
            Int_qlpc(lsp_old_q, lsp_new_q, A_t_fwd_q);
        }
        else {
            /* no interpolation */
            Lsp_Az(lsp_new_q, &A_t_fwd_q[MP1]);              /* Subframe 2 */
            Copy(&A_t_fwd_q[MP1], A_t_fwd_q, MP1);      /* Subframe 1 */
        }
        /*---------------------------------------------------------------------*
        * - Decision for the switch Forward / Backward                        *
        *---------------------------------------------------------------------*/
        if(rate == G729E) {
            set_lpc_modeg(speech, A_t_fwd_q, A_t_bwd, &lp_mode,
                lsp_new, lsp_old, &bwd_dominant, prev_lp_mode, prev_filter,
                &C_int, &glob_stat, &stat_bwd, &val_stat_bwd);
        }
        else {
            update_bwd( &lp_mode, &bwd_dominant, &C_int, &glob_stat);
        }
    }
    else update_bwd( &lp_mode, &bwd_dominant, &C_int, &glob_stat);
    
    /* ---------------------------------- */
    /* update the LSPs for the next frame */
    /* ---------------------------------- */
    Copy(lsp_new, lsp_old, M);
    
    /*----------------------------------------------------------------------*
    * - Find the weighted input speech w_sp[] for the whole speech frame   *
    *----------------------------------------------------------------------*/
    if(lp_mode == 0) {
        m_ap = M;
        if (bwd_dominant == 0) Ap = A_t_fwd;
        else Ap = A_t_fwd_q;
        perc_var(gamma1, gamma2, lsf_int, lsf_new, rc_fwd);
    }
    else {
        if (bwd_dominant == 0) {
            m_ap = M;
            Ap = A_t_fwd;
        }
        else {
            m_ap = M_BWD;
            Ap = A_t_bwd;
        }
        perc_vare(gamma1, gamma2, bwd_dominant);
    }
    pAp = Ap;
    for (i=0; i<2; i++) {
        Weight_Az(pAp, gamma1[i], m_ap, Ap1);
        Weight_Az(pAp, gamma2[i], m_ap, Ap2);
        Residue(m_ap, Ap1, &speech[i*L_SUBFR], &wsp[i*L_SUBFR], L_SUBFR);
        Syn_filte(m_ap,  Ap2, &wsp[i*L_SUBFR], &wsp[i*L_SUBFR], L_SUBFR,
            &mem_w[M_BWD-m_ap], 0);
        for(j=0; j<M_BWD; j++) mem_w[j] = wsp[i*L_SUBFR+L_SUBFR-M_BWD+j];
        pAp += m_ap+1;
    }

    /* ---------------------- */
    /* Case of Inactive frame */
    /* ---------------------- */
    if (Vad == 0){

        for (i=0; i<MA_NP; i++) Copy(&freq_prev[i][0], &lsfq_mem[i][0], M);
        Cod_cngg(exc, pastVad, lsp_old_q, old_A_fwd, old_rc_fwd, A_t_fwd_q, ana, lsfq_mem, &seed);
        for (i=0; i<MA_NP; i++) Copy(&lsfq_mem[i][0], &freq_prev[i][0], M);
        ppastVad = pastVad;
        pastVad = Vad;

        /* UPDATE wsp, mem_w, mem_syn, mem_err, and mem_w0 */
        pAp  = A_t_fwd;     /* pointer to interpolated LPC parameters           */
        pAq = A_t_fwd_q;    /* pointer to interpolated quantized LPC parameters */
        i_gamma = 0;
        for(i_subfr=0; i_subfr < L_FRAME; i_subfr += L_SUBFR) {
            Weight_Az(pAp, gamma1[i_gamma], M, Ap1);
            Weight_Az(pAp, gamma2[i_gamma], M, Ap2);
              i_gamma = add(i_gamma,1);

            /* update mem_syn */
            Syn_filte(M, pAq, &exc[i_subfr], &synth_ptr[i_subfr], L_SUBFR, &mem_syn[M_BWD-M], 0);
            for(j=0; j<M_BWD; j++) mem_syn[j] = synth_ptr[i_subfr+L_SUBFR-M_BWD+j];

            /* update mem_w0 */
            for (i=0; i<L_SUBFR; i++)
                error[i] = speech[i_subfr+i] - synth_ptr[i_subfr+i];
            Residue(M, Ap1, error, xn, L_SUBFR);
            Syn_filte(M, Ap2, xn, xn, L_SUBFR, &mem_w0[M_BWD-M], 0);
            for(j=0; j<M_BWD; j++) mem_w0[j] = xn[L_SUBFR-M_BWD+j];

            /* update mem_err */
            for (i = L_SUBFR-M_BWD, j = 0; i < L_SUBFR; i++, j++)
                mem_err[j] = error[i];

            for (i= 0; i< 4; i++)
                pgain_buf[i] = pgain_buf[i+1];
            pgain_buf[4] =  8192;

            pAp += MP1;
            pAq += MP1;
        }
        /* update previous filter for next frame */
        Copy(&A_t_fwd_q[MP1], prev_filter, MP1);
        for(i=MP1; i <M_BWDP1; i++) prev_filter[i] = 0;
        prev_lp_mode = lp_mode;

        sharp = SHARPMIN;

        /* Update memories for next frames */
        Copy(&old_speech[L_FRAME], &old_speech[0], L_TOTAL-L_FRAME);
        Copy(&old_wsp[L_FRAME], &old_wsp[0], PIT_MAX);
        Copy(&old_exc[L_FRAME], &old_exc[0], PIT_MAX+L_INTERPOL);
        return;

    }  /* End of inactive frame case */

    /* -------------------- */
    /* Case of Active frame */
    /* -------------------- */
    *ana++ = rate+ (Word16)2; /* bit rate mode */

    if(lp_mode == 0) {
        m_aq = M;
        Aq = A_t_fwd_q;
        /* update previous filter for next frame */
        Copy(&Aq[MP1], prev_filter, MP1);
        for(i=MP1; i <M_BWDP1; i++) prev_filter[i] = 0;
        for(j=MP1; j<M_BWDP1; j++) ai_zero[j] = 0;
    }
    else {
        m_aq = M_BWD;
        Aq = A_t_bwd;
        if (bwd_dominant == 0) {
            for(j=MP1; j<M_BWDP1; j++) ai_zero[j] = 0;
        }
        /* update previous filter for next frame */
        Copy(&Aq[M_BWDP1], prev_filter, M_BWDP1);
    }

    if(dtx_enable == 1) {
        seed = INIT_SEED;
        ppastVad = pastVad;
        pastVad = Vad;
    }
    if (rate == G729E) *ana++ = lp_mode;

    /*----------------------------------------------------------------------*
    * - Find the weighted input speech w_sp[] for the whole speech frame   *
    * - Find the open-loop pitch delay                                     *
    *----------------------------------------------------------------------*/
    if( lp_mode == 0) {
        Copy(lsp_new_q, lsp_old_q, M);
        Lsp_prev_update(freq_cur, freq_prev);
        *ana++ = code_lsp[0];
        *ana++ = code_lsp[1];
    }

    /* Find open loop pitch lag */
    T_op = Pitch_ol(wsp, PIT_MIN, PIT_MAX, L_FRAME);

    for (i= 0; i< 4; i++)
        lag_buf[i] = lag_buf[i+1];

        avg_lag = add(lag_buf[0],lag_buf[1]);
        avg_lag = add(avg_lag,lag_buf[2]);
        avg_lag = add(avg_lag,lag_buf[3]);
        avg_lag = mult_r(avg_lag,8192);

        tmp1 = sub(T_op,shl(avg_lag,1)); 
        tmp2 = sub(T_op,add(shl(avg_lag,1),avg_lag));
        if( sub(abs_s(tmp1), 4)<0){
           lag_buf[4] = shr(T_op,1);
        }
        else if( sub(abs_s(tmp2),6)<0){
           lag_buf[4] = mult(T_op,10923);
        }
    else{
        lag_buf[4] = T_op;
        }


    /* Range for closed loop pitch search in 1st subframe */
    T0_min = sub(T_op, 3);
    if (sub(T0_min,PIT_MIN)<0) {
        T0_min = PIT_MIN;
    }

    T0_max = add(T0_min, 6);
    if (sub(T0_max ,PIT_MAX)>0)
    {
        T0_max = PIT_MAX;
        T0_min = sub(T0_max, 6);
    }

    /*------------------------------------------------------------------------*
    *          Loop for every subframe in the analysis frame                 *
    *------------------------------------------------------------------------*
    *  To find the pitch and innovation parameters. The subframe size is     *
    *  L_SUBFR and the loop is repeated 2 times.                             *
    *     - find the weighted LPC coefficients                               *
    *     - find the LPC residual signal res[]                               *
    *     - compute the target signal for pitch search                       *
    *     - compute impulse response of weighted synthesis filter (h1[])     *
    *     - find the closed-loop pitch parameters                            *
    *     - encode the pitch delay                                           *
    *     - update the impulse response h1[] by including fixed-gain pitch   *
    *     - find target vector for codebook search                           *
    *     - codebook search                                                  *
    *     - encode codebook address                                          *
    *     - VQ of pitch and codebook gains                                   *
    *     - find synthesis speech                                            *
    *     - update states of weighting filter                                *
    *------------------------------------------------------------------------*/
    pAp  = Ap;     /* pointer to interpolated "unquantized"LPC parameters           */
    pAq = Aq;    /* pointer to interpolated "quantized" LPC parameters */

    i_gamma = 0;

    for (i_subfr = 0;  i_subfr < L_FRAME; i_subfr += L_SUBFR) {

        /*---------------------------------------------------------------*
        * Find the weighted LPC coefficients for the weighting filter.  *
        *---------------------------------------------------------------*/
        Weight_Az(pAp, gamma1[i_gamma], m_ap, Ap1);
        Weight_Az(pAp, gamma2[i_gamma], m_ap, Ap2);

        /*---------------------------------------------------------------*
        * Compute impulse response, h1[], of weighted synthesis filter  *
        *---------------------------------------------------------------*/
        for (i = 0; i <=m_ap; i++) ai_zero[i] = Ap1[i];
        Syn_filte(m_aq,  pAq, ai_zero, h1, L_SUBFR, zero, 0);
        Syn_filte(m_ap,  Ap2, h1, h1, L_SUBFR, zero, 0);

        /*------------------------------------------------------------------------*
        *                                                                        *
        *          Find the target vector for pitch search:                      *
        *          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                       *
        *                                                                        *
        *              |------|  res[n]                                          *
        *  speech[n]---| A(z) |--------                                          *
        *              |------|       |   |--------| error[n]  |------|          *
        *                    zero -- (-)--| 1/A(z) |-----------| W(z) |-- target *
        *                    exc          |--------|           |------|          *
        *                                                                        *
        * Instead of subtracting the zero-input response of filters from         *
        * the weighted input speech, the above configuration is used to          *
        * compute the target vector. This configuration gives better performance *
        * with fixed-point implementation. The memory of 1/A(z) is updated by    *
        * filtering (res[n]-exc[n]) through 1/A(z), or simply by subtracting     *
        * the synthesis speech from the input speech:                            *
        *    error[n] = speech[n] - syn[n].                                      *
        * The memory of W(z) is updated by filtering error[n] through W(z),      *
        * or more simply by subtracting the filtered adaptive and fixed          *
        * codebook excitations from the target:                                  *
        *     target[n] - gain_pit*y1[n] - gain_code*y2[n]                       *
        * as these signals are already available.                                *
        *                                                                        *
        *------------------------------------------------------------------------*/
        Residue(m_aq, pAq, &speech[i_subfr], &exc[i_subfr], L_SUBFR);   /* LPC residual */
        for (i=0; i<L_SUBFR; i++) res2[i] = exc[i_subfr+i];
        Syn_filte(m_aq,  pAq, &exc[i_subfr], error, L_SUBFR,
                &mem_err[M_BWD-m_aq], 0);
        Residue(m_ap, Ap1, error, xn, L_SUBFR);
        Syn_filte(m_ap,  Ap2, xn, xn, L_SUBFR, &mem_w0[M_BWD-m_ap], 0);    /* target signal xn[]*/

        /*----------------------------------------------------------------------*
        *                 Closed-loop fractional pitch search                  *
        *----------------------------------------------------------------------*/
        T0 = Pitch_fr3(&exc[i_subfr], xn, h1, L_SUBFR, T0_min, T0_max,
                               i_subfr, &T0_frac);

        index = Enc_lag3(T0, T0_frac, &T0_min, &T0_max,PIT_MIN,PIT_MAX,
                            i_subfr);

        *ana++ = index;

        if ( (i_subfr == 0) ) {
            *ana = Parity_Pitch(index);
            if( rate == G729E) {
                *ana ^= (shr(index, 1) & 0x0001);
            }
            ana++;
        }
       /*-----------------------------------------------------------------*
        *   - find unity gain pitch excitation (adaptive codebook entry)  *
        *     with fractional interpolation.                              *
        *   - find filtered pitch exc. y1[]=exc[] convolve with h1[])     *
        *   - compute pitch gain and limit between 0 and 1.2              *
        *   - update target vector for codebook search                    *
        *   - find LTP residual.                                          *
        *-----------------------------------------------------------------*/

        Pred_lt_3(&exc[i_subfr], T0, T0_frac, L_SUBFR);

        Convolve(&exc[i_subfr], h1, y1, L_SUBFR);

        gain_pit = G_pitch(xn, y1, g_coeff, L_SUBFR);


        /* clip pitch gain if taming is necessary */
        taming = test_err(T0, T0_frac);
        if( taming == 1){
            if (sub(gain_pit, GPCLIP) > 0) {
                gain_pit = GPCLIP;
            }
        }

        /* xn2[i]   = xn[i] - y1[i] * gain_pit  */
        for (i = 0; i < L_SUBFR; i++) {
            L_temp = L_mult(y1[i], gain_pit);
            L_temp = L_shl(L_temp, 1);               /* gain_pit in Q14 */
            xn2[i] = sub(xn[i], extract_h(L_temp));
        }

        /*-----------------------------------------------------*
        * - Innovative codebook search.                       *
        *-----------------------------------------------------*/
        switch (rate) {

            case G729:    /* 8 kbit/s */
            {

             /* case 8 kbit/s */
                index = ACELP_Codebook(xn2, h1, T0, sharp, i_subfr, code, y2, &i);
                *ana++ = index;        /* Positions index */
                *ana++ = i;            /* Signs index     */
                break;
            }

            case G729E:    /* 11.8 kbit/s */
            {

           /*-----------------------------------------------------------------*
            * Include fixed-gain pitch contribution into impulse resp. h[]    *
            *-----------------------------------------------------------------*/
            pit_sharp = shl(sharp, 1);        /* From Q14 to Q15 */
            if(T0 < L_SUBFR) {
                for (i = T0; i < L_SUBFR; i++){   /* h[i] += pitch_sharp*h[i-T0] */
                  h1[i] = add(h1[i], mult(h1[i-T0], pit_sharp));
                }
            }
            /* calculate residual after long term prediction */
            /* res2[i] -= exc[i+i_subfr] * gain_pit */
            for (i = 0; i < L_SUBFR; i++) {
                L_temp = L_mult(exc[i+i_subfr], gain_pit);
                L_temp = L_shl(L_temp, 1);               /* gain_pit in Q14 */
                res2[i] = sub(res2[i], extract_h(L_temp));
            }
            if (lp_mode == 0) ACELP_10i40_35bits(xn2, res2, h1, code, y2, ana); /* Forward */
            else ACELP_12i40_44bits(xn2, res2, h1, code, y2, ana); /* Backward */
            ana += 5;

           /*-----------------------------------------------------------------*
            * Include fixed-gain pitch contribution into code[].              *
            *-----------------------------------------------------------------*/
            if(T0 < L_SUBFR) {
                for (i = T0; i < L_SUBFR; i++) {   /* code[i] += pitch_sharp*code[i-T0] */
                    code[i] = add(code[i], mult(code[i-T0], pit_sharp));
                }
            }
            break;

        }
            default : {
                printf("Unrecognized bit rate\n");
                exit(-1);
            }
        }  /* end of switch */

        /*-----------------------------------------------------*
        * - Quantization of gains.                            *
        *-----------------------------------------------------*/

        g_coeff_cs[0]     = g_coeff[0];                   /* <y1,y1> */
        exp_g_coeff_cs[0] = negate(g_coeff[1]);           /* Q-Format:XXX -> JPN  */
        g_coeff_cs[1]     = negate(g_coeff[2]);           /* (xn,y1) -> -2<xn,y1> */
        exp_g_coeff_cs[1] = negate(add(g_coeff[3], 1));   /* Q-Format:XXX -> JPN  */

        Corr_xy2( xn, y1, y2, g_coeff_cs, exp_g_coeff_cs );  /* Q0 Q0 Q12 ^Qx ^Q0 */
                         /* g_coeff_cs[3]:exp_g_coeff_cs[3] = <y2,y2>   */
                         /* g_coeff_cs[4]:exp_g_coeff_cs[4] = -2<xn,y2> */
                         /* g_coeff_cs[5]:exp_g_coeff_cs[5] = 2<y1,y2>  */

        index = Qua_gain(code, g_coeff_cs, exp_g_coeff_cs, L_SUBFR,
                &gain_pit, &gain_code, taming);

        *ana++ = index;

        /*------------------------------------------------------------*
        * - Update pitch sharpening "sharp" with quantized gain_pit  *
        *------------------------------------------------------------*/
        for (i= 0; i< 4; i++)
            pgain_buf[i] = pgain_buf[i+1];
        pgain_buf[4] = gain_pit;

        sharp = gain_pit;
        if (sub(sharp, SHARPMAX) > 0) sharp = SHARPMAX;
        else {
            if (sub(sharp, SHARPMIN) < 0) sharp = SHARPMIN;
        }

        /*------------------------------------------------------*
        * - Find the total excitation                          *
        * - find synthesis speech corresponding to exc[]       *
        * - update filters memories for finding the target     *
        *   vector in the next subframe                        *
        *   (update error[-m..-1] and mem_w_err[])             *
        *   update error function for taming process           *
        *------------------------------------------------------*/
        for (i = 0; i < L_SUBFR;  i++) {
            /* exc[i] = gain_pit*exc[i] + gain_code*code[i]; */
            /* exc[i]  in Q0   gain_pit in Q14               */
            /* code[i] in Q13  gain_cod in Q1                */

            L_temp = L_mult(exc[i+i_subfr], gain_pit);
            L_temp = L_mac(L_temp, code[i], gain_code);
            L_temp = L_shl(L_temp, 1);
            exc[i+i_subfr] = round(L_temp);
        }

        update_exc_err(gain_pit, T0);

        Syn_filte(m_aq,  pAq, &exc[i_subfr], &synth_ptr[i_subfr], L_SUBFR,
                &mem_syn[M_BWD-m_aq], 0);
        for(j=0; j<M_BWD; j++) mem_syn[j] = synth_ptr[i_subfr+L_SUBFR-M_BWD+j];

        for (i = L_SUBFR-M_BWD, j = 0; i < L_SUBFR; i++, j++) {
            mem_err[j] = sub(speech[i_subfr+i], synth_ptr[i_subfr+i]);
            temp       = extract_h(L_shl( L_mult(y1[i], gain_pit),  1) );
            k          = extract_h(L_shl( L_mult(y2[i], gain_code), 2) );
            mem_w0[j]  = sub(xn[i], add(temp, k));
        }
        pAp   += m_ap+1;
        pAq   += m_aq+1;
        i_gamma = add(i_gamma,1);
    }

    /*--------------------------------------------------*
    * Update signal for next frame.                    *
    * -> shift to the left by L_FRAME:                 *
    *     speech[], wsp[] and  exc[]                   *
    *--------------------------------------------------*/
    Copy(&old_speech[L_FRAME], &old_speech[0], L_TOTAL-L_FRAME);
    Copy(&old_wsp[L_FRAME], &old_wsp[0], PIT_MAX);
    Copy(&old_exc[L_FRAME], &old_exc[0], PIT_MAX+L_INTERPOL);
    prev_lp_mode = lp_mode;
    return;
}