📄 pitch.c
字号:
* 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<L_subfr; j++)
scaled_excf[j] = shr(excf[j], 2);
/* Compute energy of excf[] for danger of overflow */
s = 0;
for (j = 0; j < L_subfr; j++)
s = L_mac(s, excf[j], excf[j]);
L_temp = L_sub(s, 67108864L);
if (L_temp <= 0L) /* if (s <= 2^26) */
{
s_excf = excf;
h_fac = 15-12; /* h in Q12 */
scaling = 0;
}
else {
s_excf = scaled_excf; /* "excf[]" is divide by 2 */
h_fac = 15-12-2; /* h in Q12, divide by 2 */
scaling = 2;
}
/* loop for every possible period */
for (i = t_min; i <= t_max; i++)
{
/* Compute 1/sqrt(energy of excf[]) */
s = 0;
for (j = 0; j < L_subfr; j++)
s = L_mac(s, s_excf[j], s_excf[j]);
s = Inv_sqrt(s); /* Result in Q30 */
L_Extract(s, &norm_h, &norm_l);
/* Compute correlation between xn[] and excf[] */
s = 0;
for (j = 0; j < L_subfr; j++)
s = L_mac(s, xn[j], s_excf[j]);
L_Extract(s, &corr_h, &corr_l);
/* Normalize correlation = correlation * (1/sqrt(energy)) */
s = Mpy_32(corr_h, corr_l, norm_h, norm_l);
corr_norm[i] = extract_h(L_shl(s, 16)); /* Result is on 16 bits */
/* modify the filtered excitation excf[] for the next iteration */
if( sub(i, t_max) != 0)
{
k=sub(k,1);
for (j = L_subfr-(Word16)1; j > 0; j--)
{
s = L_mult(exc[k], h[j]);
s = L_shl(s, h_fac); /* h is in Q(12-scaling) */
s_excf[j] = add(extract_h(s), s_excf[j-1]);
}
s_excf[0] = shr(exc[k], scaling);
}
}
return;
}
/*---------------------------------------------------------------------*
* Function G_pitch: *
* ~~~~~~~~ *
*---------------------------------------------------------------------*
* Compute correlations <xn,y1> and <y1,y1> 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<L_subfr; i++)
scaled_y1[i] = shr(y1[i], 2);
/* Compute scalar product <y1[],y1[]> */
Overflow = 0;
s = 1; /* Avoid case of all zeros */
for(i=0; i<L_subfr; i++)
s = L_mac(s, y1[i], y1[i]);
if (Overflow == 0) {
exp_yy = norm_l(s);
yy = round( L_shl(s, exp_yy) );
}
else {
s = 1; /* Avoid case of all zeros */
for(i=0; i<L_subfr; i++)
s = L_mac(s, scaled_y1[i], scaled_y1[i]);
exp_yy = norm_l(s);
yy = round( L_shl(s, exp_yy) );
exp_yy = sub(exp_yy, 4);
}
/* Compute scalar product <xn[],y1[]> */
Overflow = 0;
s = 0;
for(i=0; i<L_subfr; i++)
s = L_mac(s, xn[i], y1[i]);
if (Overflow == 0) {
exp_xy = norm_l(s);
xy = round( L_shl(s, exp_xy) );
}
else {
s = 0;
for(i=0; i<L_subfr; i++)
s = L_mac(s, xn[i], scaled_y1[i]);
exp_xy = norm_l(s);
xy = round( L_shl(s, exp_xy) );
exp_xy = sub(exp_xy, 2);
}
g_coeff[0] = yy;
g_coeff[1] = sub(15, exp_yy);
g_coeff[2] = xy;
g_coeff[3] = sub(15, exp_xy);
/* If (xy <= 0) gain = 0 */
if (xy <= 0)
{
g_coeff[3] = -15; /* Force exp_xy to -15 = (15-30) */
return( (Word16) 0);
}
/* compute gain = xy/yy */
xy = shr(xy, 1); /* Be sure xy < yy */
gain = div_s( xy, yy);
i = sub(exp_xy, exp_yy);
gain = shr(gain, i); /* saturation if > 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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -