www.pudn.com > g729.rar > pitch_a.c
/*
ITU-T G.729A Speech Coder ANSI-C Source Code
Version 1.1 Last modified: September 1996
Copyright (c) 1996,
AT&T, France Telecom, NTT, Universite de Sherbrooke
All rights reserved.
*/
/*---------------------------------------------------------------------------*
* Pitch related functions *
* ~~~~~~~~~~~~~~~~~~~~~~~ *
*---------------------------------------------------------------------------*/
#include "typedef.h"
#include "basic_op.h"
#include "oper_32b.h"
#include "ld8a.h"
#include "tab_ld8a.h"
/*---------------------------------------------------------------------------*
* Function Pitch_ol_fast *
* ~~~~~~~~~~~~~~~~~~~~~~~ *
* Compute the open loop pitch lag. (fast version) *
* *
*---------------------------------------------------------------------------*/
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 0) { max = sum; T1 = i; }
}
/* compute energy of maximum */
sum = 1; /* to avoid division by zero */
p = &scal_sig[-T1];
for(i=0; i 0) { max = sum; T2 = i; }
}
/* compute energy of maximum */
sum = 1; /* to avoid division by zero */
p = &scal_sig[-T2];
for(i=0; i 0) { max = sum; T3 = i; }
}
/* Test around max3 */
i = T3;
p = scal_sig;
p1 = &scal_sig[-(i+1)];
sum = 0;
for (j=0; j 0) { max = sum; T3 = i+(Word16)1; }
p = scal_sig;
p1 = &scal_sig[-(i-1)];
sum = 0;
for (j=0; j 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 0) {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) && (sub(t0, 84) > 0) )
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);
L_temp = L_sub(corr, max);
if(L_temp > 0) {
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);
L_temp = L_sub(corr, max);
if(L_temp > 0) {
max = corr;
*pit_frac = 1;
}
else
Copy(exc_tmp, exc, L_subfr);
return t0;
}
/*---------------------------------------------------------------------*
* 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 = myadd(myadd(T0, T0), T0);
index = myadd(sub(i, 58), T0_frac);
}
else {
index = myadd(T0, 112);
}
/* find T0_min and T0_max for second subframe */
*T0_min = sub(T0, 5);
if (sub(*T0_min, pit_min) < 0)
{
*T0_min = pit_min;
}
*T0_max = myadd(*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 = myadd(myadd(i, i), i);
index = myadd(myadd(i, 2), T0_frac);
}
return index;
}