www.pudn.com > g729_audio_encode.rar > pitch.c


/* 
   ITU-T G.729 Speech Coder ANSI-C Source Code 
   Version 3.3    Last modified: December 26, 1995 
 
   Copyright (c) 1996, 
   AT&T, France Telecom, NTT, Universite de Sherbrooke, Lucent Technologies 
   All rights reserved. 
*/ 
 
/*---------------------------------------------------------------------------* 
 * procedure Pitch_ol                                                        * 
 * ~~~~~~~~~~~~~~~~~~                                                        * 
 * Compute the open loop pitch lag.                                          * 
 *                                                                           * 
 *---------------------------------------------------------------------------*/ 
 
#include "typedef.h" 
#include "basic_op.h" 
#include "oper_32b.h" 
#include "ld8k.h" 
#include "tab_ld8k.h" 
 
/* local function */ 
 
static Word16 Lag_max(        /* output: lag found                           */ 
  Word16 signal[],     /* input : signal used to compute the open loop pitch */ 
  Word16 L_frame,      /* input : length of frame to compute pitch           */ 
  Word16 lag_max,      /* input : maximum lag                                */ 
  Word16 lag_min,      /* input : minimum lag                                */ 
  Word16 *cor_max);    /* output: normalized correlation of selected lag     */ 
 
 
Word16 Pitch_ol(       /* 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_min,   /* input : minimum pitch lag                          */ 
   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  p_max1, p_max2, p_max3; 
  Word32  t0, 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; 
   t0 = 0; 
 
   for(i= -pit_max; i< L_frame; i++) 
     t0 = L_mac(t0, signal[i], signal[i]); 
 
  /*--------------------------------------------------------* 
   * Scaling of input signal.                               * 
   *                                                        * 
   *   if Overflow        -> scal_sig[i] = signal[i]>>3     * 
   *   else if t0 < 1^20  -> scal_sig[i] = signal[i]<<3     * 
   *   else               -> scal_sig[i] = signal[i]        * 
   *--------------------------------------------------------*/ 
 
   if(Overflow == 1) 
   { 
     for(i=-pit_max; i= lag_min; i--) 
  { 
    p  = signal; 
    p1 = &signal[-i]; 
    t0 = 0; 
 
    for (j=0; j= 0L) 
    { 
      max    = t0; 
      p_max = i; 
    } 
  } 
 
  /* compute energy */ 
 
  t0 = 0; 
  p = &signal[-p_max]; 
  for(i=0; i= 0) 
    { 
      max = corr[i]; 
      lag = i; 
    } 
  } 
 
  /* If first subframe and lag > 84 do not search fractional pitch */ 
 
  if( (i_subfr == 0) && (sub(lag, 84) > 0) ) 
  { 
    *pit_frac = 0; 
    return(lag); 
  } 
 
  /* Test the fractions around T0 and choose the one which maximizes   */ 
  /* the interpolated normalized correlation.                          */ 
 
  max  = Interpol_3(&corr[lag], -2); 
  frac = -2; 
 
  for (i = -1; i <= 2; i++) 
  { 
    corr_int = Interpol_3(&corr[lag], i); 
    if (sub(corr_int, max) > 0) 
    { 
      max = corr_int; 
      frac = i; 
    } 
  } 
 
  /* limit the fraction value between -1 and 1 */ 
 
  if (sub(frac, -2) == 0) 
  { 
    frac = 1; 
    lag = sub(lag, 1); 
  } 
  if (sub(frac, 2) == 0) 
  { 
    frac = -1; 
    lag = add(lag, 1); 
  } 
 
  *pit_frac = frac; 
 
 
  return(lag); 
} 
 
/*---------------------------------------------------------------------------* 
 * Function Norm_Corr()                                                      * 
 * ~~~~~~~~~~~~~~~~~~~~                                                      * 
 * Find the normalized correlation between the target vector and the         * 
 * filtered past excitation.                                                 * 
 *---------------------------------------------------------------------------* 
 * Input arguments:                                                          * 
 *     exc[]    : excitation buffer                                          * 
 *     xn[]     : target vector                                              * 
 *     h[]      : impulse response of synthesis and weighting filters (Q12)  * 
 *     L_subfr  : Length of subframe                                         * 
 *     t_min    : minimum value of pitch lag.                                * 
 *     t_max    : maximum value of pitch lag.                                * 
 *                                                                           * 
 * Output arguments:                                                         * 
 *     corr_norm[]:  normalized correlation (correlation between target and  * 
 *                   filtered excitation divided by the square root of       * 
 *                   energy of filtered excitation)                          * 
 *--------------------------------------------------------------------------*/ 
 
static void Norm_Corr(Word16 exc[], Word16 xn[], Word16 h[], Word16 L_subfr, 
               Word16 t_min, Word16 t_max, Word16 corr_norm[]) 
{ 
  Word16 i,j,k; 
  Word16 corr_h, corr_l, norm_h, norm_l; 
  Word32 s, L_temp; 
 
  Word16 excf[L_SUBFR]; 
  Word16 scaling, h_fac, *s_excf, scaled_excf[L_SUBFR]; 
 
 
  k =  negate(t_min); 
 
  /* compute the filtered excitation for the first delay t_min */ 
 
  Convolve(&exc[k], h, excf, L_subfr); 
 
  /* scaled "excf[]" to avoid overflow */ 
 
  for(j=0; j 0; j--) 
      { 
        s = L_mult(exc[k], h[j]); 
        s = L_shl(s, h_fac);             /* h is in Q(12-scaling) */ 
        s_excf[j] = add(extract_h(s), s_excf[j-1]); 
      } 
      s_excf[0] = shr(exc[k], scaling); 
    } 
  } 
  return; 
} 
 
/*---------------------------------------------------------------------* 
 * Function  G_pitch:                                                  * 
 *           ~~~~~~~~                                                  * 
 *---------------------------------------------------------------------* 
 * Compute correlations  and  to use in gains quantizer. * 
 * Also compute the gain of pitch. Result in Q14                       * 
 *  if (gain < 0)  gain =0                                             * 
 *  if (gain >1.2) gain =1.2                                           * 
 *---------------------------------------------------------------------*/ 
 
 
Word16 G_pitch(      /* (o) Q14 : Gain of pitch lag saturated to 1.2       */ 
  Word16 xn[],       /* (i)     : Pitch target.                            */ 
  Word16 y1[],       /* (i)     : Filtered adaptive codebook.              */ 
  Word16 g_coeff[],  /* (i)     : Correlations need for gain quantization. */ 
  Word16 L_subfr     /* (i)     : Length of subframe.                      */ 
) 
{ 
   Word16 i; 
   Word16 xy, yy, exp_xy, exp_yy, gain; 
   Word32 s; 
 
   Word16 scaled_y1[L_SUBFR]; 
 
   /* divide "y1[]" by 4 to avoid overflow */ 
 
   for(i=0; i */ 
 
   Overflow = 0; 
   s = 1;                    /* Avoid case of all zeros */ 
   for(i=0; i */ 
 
   Overflow = 0; 
   s = 0; 
   for(i=0; i 1.99 in Q14 */ 
 
   /* if(gain >1.2) gain = 1.2  in Q14 */ 
 
   if( sub(gain, 19661) > 0) 
   { 
     gain = 19661; 
   } 
 
 
   return(gain); 
} 
 
/*----------------------------------------------------------------------* 
 *    Function Enc_lag3                                                 * 
 *             ~~~~~~~~                                                 * 
 *   Encoding of fractional pitch lag with 1/3 resolution.              * 
 *----------------------------------------------------------------------* 
 * The pitch range for the first subframe is divided as follows:        * 
 *   19 1/3  to   84 2/3   resolution 1/3                               * 
 *   85      to   143      resolution 1                                 * 
 *                                                                      * 
 * The period in the first subframe is encoded with 8 bits.             * 
 * For the range with fractions:                                        * 
 *   index = (T-19)*3 + frac - 1;   where T=[19..85] and frac=[-1,0,1]  * 
 * and for the integer only range                                       * 
 *   index = (T - 85) + 197;        where T=[86..143]                   * 
 *----------------------------------------------------------------------* 
 * For the second subframe a resolution of 1/3 is always used, and the  * 
 * search range is relative to the lag in the first subframe.           * 
 * If t0 is the lag in the first subframe then                          * 
 *  t_min=t0-5   and  t_max=t0+4   and  the range is given by           * 
 *       t_min - 2/3   to  t_max + 2/3                                  * 
 *                                                                      * 
 * The period in the 2nd subframe is encoded with 5 bits:               * 
 *   index = (T-(t_min-1))*3 + frac - 1;    where T[t_min-1 .. t_max+1] * 
 *----------------------------------------------------------------------*/ 
 
 
Word16 Enc_lag3(     /* output: Return index of encoding */ 
  Word16 T0,         /* input : Pitch delay              */ 
  Word16 T0_frac,    /* input : Fractional pitch delay   */ 
  Word16 *T0_min,    /* in/out: Minimum search delay     */ 
  Word16 *T0_max,    /* in/out: Maximum search delay     */ 
  Word16 pit_min,    /* input : Minimum pitch delay      */ 
  Word16 pit_max,    /* input : Maximum pitch delay      */ 
  Word16 pit_flag    /* input : Flag for 1st subframe    */ 
) 
{ 
  Word16 index, i; 
 
  if (pit_flag == 0)   /* if 1st subframe */ 
  { 
    /* encode pitch delay (with fraction) */ 
 
    if (sub(T0, 85) <= 0) 
    { 
      /* index = t0*3 - 58 + t0_frac   */ 
      i = add(add(T0, T0), T0); 
      index = add(sub(i, 58), T0_frac); 
    } 
    else { 
      index = add(T0, 112); 
    } 
 
    /* find T0_min and T0_max for second (or fourth) subframe */ 
 
    *T0_min = sub(T0, 5); 
    if (sub(*T0_min, pit_min) < 0) 
    { 
      *T0_min = pit_min; 
    } 
 
    *T0_max = add(*T0_min, 9); 
    if (sub(*T0_max, pit_max) > 0) 
    { 
      *T0_max = pit_max; 
      *T0_min = sub(*T0_max, 9); 
    } 
  } 
  else      /* if second subframe */ 
  { 
 
    /* i = t0 - t0_min;               */ 
    /* index = i*3 + 2 + t0_frac;     */ 
    i = sub(T0, *T0_min); 
    i = add(add(i, i), i); 
    index = add(add(i, 2), T0_frac); 
  } 
 
 
  return index; 
} 
 
 
/*---------------------------------------------------------------------------* 
 * Procedure Interpol_3()                                                    * 
 * ~~~~~~~~~~~~~~~~~~~~~~                                                    * 
 * For interpolating the normalized correlation with 1/3 resolution.         * 
 *--------------------------------------------------------------------------*/ 
Word16 Interpol_3(      /* (o)  : interpolated value  */ 
  Word16 *x,            /* (i)  : input vector        */ 
  Word16 frac           /* (i)  : fraction            */ 
) 
{ 
  Word16 i, k; 
  Word16 *x1, *x2, *c1, *c2; 
  Word32 s; 
 
  if(frac < 0) 
  { 
    frac = add(frac, UP_SAMP); 
    x--; 
  } 
 
  x1 = &x[0]; 
  x2 = &x[1]; 
  c1 = &inter_3[frac]; 
  c2 = &inter_3[sub(UP_SAMP,frac)]; 
 
  s = 0; 
  for(i=0, k=0; i< L_INTER4; i++, k+=UP_SAMP) 
  { 
    s = L_mac(s, x1[-i], c1[k]); 
    s = L_mac(s, x2[i],  c2[k]); 
  } 
 
 
  return round(s); 
}