www.pudn.com > source.rar > PITCH_A.C


/* ITU-T G.729 Software Package Release 2 (November 2006) */ 
/* 
   ITU-T G.729 Annex C - Reference C code for floating point 
                         implementation of G.729 Annex A 
                         Version 1.01 of 15.September.98 
*/ 
 
/* 
---------------------------------------------------------------------- 
                    COPYRIGHT NOTICE 
---------------------------------------------------------------------- 
   ITU-T G.729 Annex C ANSI C source code 
   Copyright (C) 1998, AT&T, France Telecom, NTT, University of 
   Sherbrooke.  All rights reserved. 
 
---------------------------------------------------------------------- 
*/ 
 
/***********************************************************************/ 
/*           Long Term (Pitch) Prediction Functions                    */ 
/***********************************************************************/ 
 
#include  
#include "typedef.h" 
#include "ld8a.h" 
 
/* prototypes for local functions */ 
 
static FLOAT dot_product(FLOAT x[], FLOAT y[], int lg); 
 
/*----------------------------------------------------------------------* 
 * pitch_ol_fast -> compute the open loop pitch lag -> fast version     * 
 *----------------------------------------------------------------------*/ 
 
int pitch_ol_fast(         /* output: open-loop pitch lag       */ 
    FLOAT signal[],        /* input : signal to compute pitch   */ 
                           /*         s[-PIT_MAX : l_frame-1]   */ 
    int l_frame            /* input : error minimization window */ 
) 
{ 
    int  i, j; 
    int  T1, T2, T3; 
    FLOAT  max1, max2, max3; 
    FLOAT  *p, *p1, sum; 
 
 
   /*--------------------------------------------------------------------* 
    *  The pitch lag search is divided in three sections.                * 
    *  Each section cannot have a pitch multiple.                        * 
    *  A maximum is find for each section.                               * 
    *  The final lag is selected by taking into account the multiple.    * 
    *                                                                    * 
    *  First section:  lag delay = 20 to 39                              * 
    *  Second section: lag delay = 40 to 79                              * 
    *  Third section:  lag delay = 80 to 143                             * 
    *--------------------------------------------------------------------*/ 
 
    /* First section */ 
 
    max1 = FLT_MIN_G729; 
    for (i = 20; i < 40; i++) { 
        p  = signal; 
        p1 = &signal[-i]; 
        sum = (F)0.0; 
        /* Dot product with decimation by 2 */ 
        for (j=0; j max1) { max1 = sum; T1 = i;} 
    } 
 
    /* compute energy of maximum1 */ 
 
    sum = (F)0.01;                   /* to avoid division by zero */ 
    p = &signal[-T1]; 
    for(i=0; i max2) { max2 = sum; T2 = i;} 
    } 
 
    /* compute energy of maximum2 */ 
 
    sum = (F)0.01;                   /* to avoid division by zero */ 
    p = &signal[-T2]; 
    for(i=0; i max3) { max3 = sum; T3 = i;} 
    } 
 
     /* Test around max3 */ 
 
     i = T3; 
     p  = signal; 
     p1 = &signal[-(i+1)]; 
     sum = (F)0.0; 
     for (j=0; j max3) { max3 = sum; T3 = i+1;} 
 
     p  = signal; 
     p1 = &signal[-(i-1)]; 
     sum = (F)0.0; 
     for (j=0; j max3) { max3 = sum; T3 = i-1;} 
 
 
    /* compute energy of maximum3 */ 
 
    sum = (F)0.01;                   /* to avoid division by zero */ 
    p = &signal[-T3]; 
    for(i=0; i max) {max = corr; t0 = t;} 
  } 
 
  /* Test fractions */ 
 
  /* Fraction 0 */ 
  pred_lt_3(exc, t0, 0, l_subfr); 
  max = dot_product(dn, exc, l_subfr); 
  *pit_frac = 0; 
 
  /* If first subframe and lag > 84 do not search fractional pitch */ 
 
  if( (i_subfr == 0) && (t0 > 84) ) 
    return t0; 
 
  copy(exc, exc_tmp, l_subfr); 
 
  /* Fraction -1/3 */ 
 
  pred_lt_3(exc, t0, -1, l_subfr); 
  corr = dot_product(dn, exc, l_subfr); 
  if(corr > max){ 
    max = corr; 
    *pit_frac = -1; 
    copy(exc, exc_tmp, l_subfr); 
  } 
 
  /* Fraction +1/3 */ 
 
  pred_lt_3(exc, t0, 1, l_subfr); 
  corr = dot_product(dn, exc, l_subfr); 
  if(corr > max){ 
    max = corr; 
    *pit_frac = 1; 
  } 
  else 
    copy(exc_tmp, exc, l_subfr); 
 
  return t0; 
} 
 
/*---------------------------------------------------------------------------* 
 * g_pitch  - compute adaptive codebook gain and compute  , -2 * 
 *---------------------------------------------------------------------------*/ 
 
FLOAT g_pitch(          /* output: pitch gain                        */ 
  FLOAT xn[],           /* input : target vector                     */ 
  FLOAT y1[],           /* input : filtered adaptive codebook vector */ 
  FLOAT g_coeff[],      /* output:  and -2             */ 
  int l_subfr           /* input : vector dimension                  */ 
) 
{ 
    FLOAT xy, yy, gain; 
    int   i; 
 
    yy = (F)0.01; 
    for (i = 0; i < l_subfr; i++) { 
        yy += y1[i] * y1[i];          /* energy of filtered excitation */ 
    } 
    xy = (F)0.0; 
    for (i = 0; i < l_subfr; i++) { 
        xy += xn[i] * y1[i]; 
    } 
 
    g_coeff[0] = yy; 
    g_coeff[1] = (F)-2.0*xy +(F)0.01; 
 
    /* find pitch gain and bound it by [0,1.2] */ 
 
    gain = xy/yy; 
 
    if (gain<(F)0.0)  gain = (F)0.0; 
    if (gain>GAIN_PIT_MAX) gain = GAIN_PIT_MAX; 
 
    return gain; 
} 
 
/*----------------------------------------------------------------------* 
 *    Functions 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] * 
 *----------------------------------------------------------------------*/ 
int  enc_lag3(     /* output: Return index of encoding */ 
  int  T0,         /* input : Pitch delay              */ 
  int  T0_frac,    /* input : Fractional pitch delay   */ 
  int  *T0_min,    /* in/out: Minimum search delay     */ 
  int  *T0_max,    /* in/out: Maximum search delay     */ 
  int pit_min,     /* input : Minimum pitch delay      */ 
  int pit_max,     /* input : Maximum pitch delay      */ 
  int  i_subfr     /* input : Flag for 1st subframe    */ 
) 
{ 
  int index; 
 
  if (i_subfr == 0)   /* if 1st subframe */ 
  { 
     /* encode pitch delay (with fraction) */ 
 
     if (T0 <= 85) 
       index = T0*3 - 58 + T0_frac; 
     else 
       index = T0 + 112; 
 
     /* find T0_min and T0_max for second subframe */ 
 
     *T0_min = T0 - 5; 
     if (*T0_min < pit_min) *T0_min = pit_min; 
     *T0_max = *T0_min + 9; 
     if (*T0_max > pit_max) 
     { 
         *T0_max = pit_max; 
         *T0_min = *T0_max - 9; 
     } 
  } 
 
  else                    /* second subframe */ 
  { 
     index = T0 - *T0_min; 
     index = index*3 + 2 + T0_frac; 
  } 
  return index; 
}