📄 ol_ltp.c
字号:
#include "ol_ltp.h"
#include "basic_op.h"
#include "autocorr.h"
#include "qgain475.h"
#include "vad.h"
#include "qgain795.h"
#define UP_SAMP_MAX 6
#define L_INTER_SRCH 4 #define FIR_SIZE (UP_SAMP_MAX*L_INTER_SRCH+1)
static const Word16 inter_6[FIR_SIZE] ={ 29519, 28316, 24906, 19838, 13896, 7945, 2755, -1127, -3459, -4304, -3969, -2899, -1561, -336, 534, 970, 1023, 823, 516, 220, 0, -131, -194, -215, 0};
static const Word16 corrweight[251] = { 20473, 20506, 20539, 20572, 20605, 20644, 20677, 20716, 20749, 20788, 20821, 20860, 20893, 20932, 20972, 21011, 21050, 21089, 21129, 21168, 21207, 21247, 21286, 21332, 21371, 21417, 21456, 21502, 21542, 21588, 21633, 21679, 21725, 21771, 21817, 21863, 21909, 21961, 22007, 22059, 22105, 22158, 22210, 22263, 22315, 22367, 22420, 22472, 22531, 22584, 22643, 22702, 22761, 22820, 22879, 22938, 23003, 23062, 23128, 23193, 23252, 23324, 23390, 23455, 23527, 23600, 23665, 23744, 23816, 23888, 23967, 24045, 24124, 24202, 24288, 24366, 24451, 24537, 24628, 24714, 24805, 24904, 24995, 25094, 25192, 25297, 25395, 25500, 25611, 25723, 25834, 25952, 26070, 26188, 26313, 26444, 26575, 26706, 26844, 26988, 27132, 27283, 27440, 27597, 27761, 27931, 28108, 28285, 28475, 28665, 28869, 29078, 29295, 29524, 29760, 30002, 30258, 30527, 30808, 31457, 32767, 32767, 32767, 32767, 32767, 32767, 32767, 31457, 30808, 30527, 30258, 30002, 29760, 29524, 29295, 29078, 28869, 28665, 28475, 28285, 28108, 27931, 27761, 27597, 27440, 27283, 27132, 26988, 26844, 26706, 26575, 26444, 26313, 26188, 26070, 25952, 25834, 25723, 25611, 25500, 25395, 25297, 25192, 25094, 24995, 24904, 24805, 24714, 24628, 24537, 24451, 24366, 24288, 24202, 24124, 24045, 23967, 23888, 23816, 23744, 23665, 23600, 23527, 23455, 23390, 23324, 23252, 23193, 23128, 23062, 23003, 22938, 22879, 22820, 22761, 22702, 22643, 22584, 22531, 22472, 22420, 22367, 22315, 22263, 22210, 22158, 22105, 22059, 22007, 21961, 21909, 21863, 21817, 21771, 21725, 21679, 21633, 21588, 21542, 21502, 21456, 21417, 21371, 21332, 21286, 21247, 21207, 21168, 21129, 21089, 21050, 21011, 20972, 20932, 20893, 20860, 20821, 20788, 20749, 20716, 20677, 20644, 20605, 20572, 20539, 20506, 20473, 20434, 20401, 20369, 20336};
int ol_ltp( pitchOLWghtState *st, vadState *vadSt, Mode mode, Word16 wsp[], Word16 *T_op, Word16 old_lags[], Word16 ol_gain_flg[], Word16 idx,Flag dtx )
{
if ( mode!= MR102) { ol_gain_flg[0] = 0; ol_gain_flg[1] = 0; } if ((mode == MR475)||(mode == MR515) ) { *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN, PIT_MAX, L_FRAME, idx, dtx); } else { if ( mode <= MR795 ) { *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN, PIT_MAX, L_FRAME_BY2, idx, dtx); } else if ( mode ==MR102 ) { *T_op = Pitch_ol_wgh(st, vadSt, wsp, PIT_MIN, PIT_MAX, L_FRAME_BY2, old_lags, ol_gain_flg, idx, dtx); } else { *T_op = Pitch_ol(vadSt, mode, wsp, PIT_MIN_MR122, PIT_MAX,L_FRAME_BY2, idx, dtx); } }
return 0;}
static const struct { Word16 max_frac_lag; /* lag up to which fractional lags are used */ Word16 flag3; /* enable 1/3 instead of 1/6 fract. resolution */
Word16 first_frac; /* first fractional to check */
Word16 last_frac; /* last fractional to check */
Word16 delta_int_low; /* integer lag below TO to start search from */
Word16 delta_int_range; /* integer range around T0 */
Word16 delta_frc_low; /* fractional below T0 */
Word16 delta_frc_range; /* fractional range around T0 */
Word16 pit_min; /* minimum pitch */
} mode_dep_parm[N_MODES] =
{
/* MR475 */ { 84, 1, -2, 2, 5, 10, 5, 9, PIT_MIN }, /* MR515 */ { 84, 1, -2, 2, 5, 10, 5, 9, PIT_MIN }, /* MR59 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN },
/* MR67 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN },
/* MR74 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN },
/* MR795 */ { 84, 1, -2, 2, 3, 6, 10, 19, PIT_MIN }, /* MR102 */ { 84, 1, -2, 2, 3, 6, 5, 9, PIT_MIN }, /* MR122 */ { 94, 0, -3, 3, 3, 6, 5, 9, PIT_MIN_MR122 }};
/************************************************************************* * * FUNCTION: Norm_Corr() * * PURPOSE: Find the normalized correlation between the target vector * and the filtered past excitation. * * DESCRIPTION: * The normalized correlation is given by the correlation between the * target and filtered past excitation divided by the square root of * the energy of filtered excitation. * corr[k] = <x[], y_k[]>/sqrt(y_k[],y_k[]) * where x[] is the target vector and y_k[] is the filtered past * excitation at delay k. * *************************************************************************/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,temp;
Word32 s;
Word16 excf[L_SUBFR];
Word16 scaling, h_fac, *s_excf, scaled_excf[L_SUBFR];
Word32 s1,s2,s3,s4,s5,s6,s7,s8;
Word16*pexc = exc, *pxn = xn, *ph = h, *pcorr_norm = corr_norm;
k = -t_min;
/* compute the filtered excitation for the first delay t_min */
Convolve (&pexc[k], ph, excf, L_subfr);
s = 0;
for (j = 0; j < 40; j++)
{
s += excf[j]*excf[j] << 1;
if( s < 0)
{
s = MAX_32; break;
}
}
if (s <= 67108864L )
{
s_excf = excf;
h_fac = 3;
scaling = 0;
}
else
{
s_excf = scaled_excf;
h_fac = 1;
scaling = 2;
scaled_excf[0] = excf[0]>> 2; scaled_excf[1] = excf[1]>> 2; scaled_excf[2] = excf[2]>> 2; scaled_excf[3] = excf[3]>> 2; scaled_excf[4] = excf[4]>> 2;
scaled_excf[5] = excf[5]>> 2; scaled_excf[6] = excf[6]>> 2; scaled_excf[7] = excf[7]>> 2; scaled_excf[8] = excf[8]>> 2; scaled_excf[9] = excf[9]>> 2;
scaled_excf[10] = excf[10]>> 2; scaled_excf[11] = excf[11]>> 2; scaled_excf[12] = excf[12]>> 2; scaled_excf[13] = excf[13]>> 2; scaled_excf[14] = excf[14]>> 2;
scaled_excf[15] = excf[15]>> 2; scaled_excf[16] = excf[16]>> 2; scaled_excf[17] = excf[17]>> 2; scaled_excf[18] = excf[18]>> 2; scaled_excf[19] = excf[19]>> 2;
scaled_excf[20] = excf[20]>> 2; scaled_excf[21] = excf[21]>> 2; scaled_excf[22] = excf[22]>> 2; scaled_excf[23] = excf[23]>> 2; scaled_excf[24] = excf[24]>> 2;
scaled_excf[25] = excf[25]>> 2; scaled_excf[26] = excf[26]>> 2; scaled_excf[27] = excf[27]>> 2; scaled_excf[28] = excf[28]>> 2; scaled_excf[29] = excf[29]>> 2;
scaled_excf[30] = excf[30]>> 2; scaled_excf[31] = excf[31]>> 2; scaled_excf[32] = excf[32]>> 2; scaled_excf[33] = excf[33]>> 2; scaled_excf[34] = excf[34]>> 2;
scaled_excf[35] = excf[35]>> 2; scaled_excf[36] = excf[36]>> 2; scaled_excf[37] = excf[37]>> 2; scaled_excf[38] = excf[38]>> 2; scaled_excf[39] = excf[39]>> 2;
}
/* loop for every possible period */
for (i = t_min; i <= t_max; i++)
{
/* Compute 1/sqrt(energy of excf[]) */
s1 = s_excf[0]* s_excf[0] + s_excf[1]* s_excf[1] + s_excf[2]* s_excf[2] + s_excf[3]* s_excf[3]+s_excf[4]* s_excf[4];
s2 = s_excf[5]* s_excf[5] + s_excf[6]* s_excf[6] + s_excf[7]* s_excf[7] + s_excf[8]* s_excf[8]+s_excf[9]* s_excf[9];
s3 = s_excf[10]* s_excf[10] + s_excf[11]* s_excf[11] + s_excf[12]* s_excf[12] + s_excf[13]* s_excf[13]+s_excf[14]* s_excf[14];
s4 = s_excf[15]* s_excf[15] + s_excf[16]* s_excf[16] + s_excf[17]* s_excf[17] + s_excf[18]* s_excf[18]+s_excf[19]* s_excf[19];
s5 = s_excf[20]* s_excf[20] + s_excf[21]* s_excf[21] + s_excf[22]* s_excf[22] + s_excf[23]* s_excf[23]+s_excf[24]* s_excf[24];
s6 = s_excf[25]* s_excf[25] + s_excf[26]* s_excf[26] + s_excf[27]* s_excf[27] + s_excf[28]* s_excf[28]+s_excf[29]* s_excf[29];
s7 = s_excf[30]* s_excf[30] + s_excf[31]* s_excf[31] + s_excf[32]* s_excf[32] + s_excf[33]* s_excf[33]+s_excf[34]* s_excf[34];
s8 = s_excf[35]* s_excf[35] + s_excf[36]* s_excf[36] + s_excf[37]* s_excf[37] + s_excf[38]* s_excf[38]+s_excf[39]* s_excf[39];
s = (s1+s2+s3+s4+s5+s6+s7+s8)<<1;
s = Inv_sqrt (s);
norm_h = (Word16)(s >> 16);
norm_l = (s - (norm_h<<16))>>1;
/* Compute correlation between xn[] and excf[] */
s1 = pxn[0]* s_excf[0] + pxn[1]* s_excf[1] + pxn[2]* s_excf[2] + pxn[3]* s_excf[3] + pxn[4]* s_excf[4];
s2 = pxn[5]* s_excf[5] + pxn[6]* s_excf[6] + pxn[7]* s_excf[7] + pxn[8]* s_excf[8] + pxn[9]* s_excf[9];
s3 = pxn[10]* s_excf[10] + pxn[11]* s_excf[11] + pxn[12]* s_excf[12] + pxn[13]* s_excf[13] + pxn[14]* s_excf[14];
s4 = pxn[15]* s_excf[15] + pxn[16]* s_excf[16] + pxn[17]* s_excf[17] + pxn[18]* s_excf[18] + pxn[19]* s_excf[19];
s5 = pxn[20]* s_excf[20] + pxn[21]* s_excf[21] + pxn[22]* s_excf[22] + pxn[23]* s_excf[23] + pxn[24]* s_excf[24];
s6 = pxn[25]* s_excf[25] + pxn[26]* s_excf[26] + pxn[27]* s_excf[27] + pxn[28]* s_excf[28] + pxn[29]* s_excf[29];
s7 = pxn[30]* s_excf[30] + pxn[31]* s_excf[31] + pxn[32]* s_excf[32] + pxn[33]* s_excf[33] + pxn[34]* s_excf[34];
s8 = pxn[35]* s_excf[35] + pxn[36]* s_excf[36] + pxn[37]* s_excf[37] + pxn[38]* s_excf[38] + pxn[39]* s_excf[39];
s = (s1+s2+s3+s4+s5+s6+s7+s8)<<1;
corr_h = (Word16)(s >> 16);
corr_l = (s - (corr_h<<16))>>1;
/* Normalize correlation = correlation * (1/sqrt(energy)) */
s = (corr_h*norm_h <<1) + (((corr_h*norm_l >>15) +(norm_h*corr_l >>15) ) <<1);
pcorr_norm[i] = (Word16)s;
/* modify the filtered excitation excf[] for the next iteration */
if (i != t_max )
{
k--;
temp = pexc[k];
s_excf[39] = (temp*ph[39] >>(15-h_fac)) + s_excf[38] ; s_excf[38] = (temp*ph[38] >>(15-h_fac)) + s_excf[37] ;
s_excf[37] = (temp*ph[37] >>(15-h_fac)) + s_excf[36] ; s_excf[36] = (temp*ph[36] >>(15-h_fac)) + s_excf[35] ;
s_excf[35] = (temp*ph[35] >>(15-h_fac)) + s_excf[34] ; s_excf[34] = (temp*ph[34] >>(15-h_fac)) + s_excf[33] ;
s_excf[33] = (temp*ph[33] >>(15-h_fac)) + s_excf[32] ; s_excf[32] = (temp*ph[32] >>(15-h_fac)) + s_excf[31] ;
s_excf[31] = (temp*ph[31] >>(15-h_fac)) + s_excf[30] ; s_excf[30] = (temp*ph[30] >>(15-h_fac)) + s_excf[29] ;
s_excf[29] = (temp*ph[29] >>(15-h_fac)) + s_excf[28] ; s_excf[28] = (temp*ph[28] >>(15-h_fac)) + s_excf[27] ;
s_excf[27] = (temp*ph[27] >>(15-h_fac)) + s_excf[26] ; s_excf[26] = (temp*ph[26] >>(15-h_fac)) + s_excf[25] ;
s_excf[25] = (temp*ph[25] >>(15-h_fac)) + s_excf[24] ; s_excf[24] = (temp*ph[24] >>(15-h_fac)) + s_excf[23] ;
s_excf[23] = (temp*ph[23] >>(15-h_fac)) + s_excf[22] ; s_excf[22] = (temp*ph[22] >>(15-h_fac)) + s_excf[21] ;
s_excf[21] = (temp*ph[21] >>(15-h_fac)) + s_excf[20] ; s_excf[20] = (temp*ph[20] >>(15-h_fac)) + s_excf[19] ;
s_excf[19] = (temp*ph[19] >>(15-h_fac)) + s_excf[18] ; s_excf[18] = (temp*ph[18] >>(15-h_fac)) + s_excf[17] ;
s_excf[17] = (temp*ph[17] >>(15-h_fac)) + s_excf[16] ; s_excf[16] = (temp*ph[16] >>(15-h_fac)) + s_excf[15] ;
s_excf[15] = (temp*ph[15] >>(15-h_fac)) + s_excf[14] ; s_excf[14] = (temp*ph[14] >>(15-h_fac)) + s_excf[13] ;
s_excf[13] = (temp*ph[13] >>(15-h_fac)) + s_excf[12] ; s_excf[12] = (temp*ph[12] >>(15-h_fac)) + s_excf[11] ;
s_excf[11] = (temp*ph[11] >>(15-h_fac)) + s_excf[10] ; s_excf[10] = (temp*ph[10] >>(15-h_fac)) + s_excf[9] ;
s_excf[9] = (temp*ph[9 ] >>(15-h_fac)) + s_excf[8] ; s_excf[8] = (temp*ph[8] >>(15-h_fac)) + s_excf[7] ;
s_excf[7] = (temp*ph[7] >>(15-h_fac)) + s_excf[6] ; s_excf[6] = (temp*ph[6] >>(15-h_fac)) + s_excf[5] ;
s_excf[5] = (temp*ph[5] >>(15-h_fac)) + s_excf[4] ; s_excf[4] = (temp*ph[4] >>(15-h_fac)) + s_excf[3] ;
s_excf[3] = (temp*ph[3] >>(15-h_fac)) + s_excf[2] ; s_excf[2] = (temp*ph[2] >>(15-h_fac)) + s_excf[1] ;
s_excf[1] = (temp*ph[1] >>(15-h_fac)) + s_excf[0] ;
s_excf[0] = (pexc[k]>> scaling);
}
}
return;
}/************************************************************************* * * FUNCTION: searchFrac() * * PURPOSE: Find fractional pitch * * DESCRIPTION: * The function interpolates the normalized correlation at the * fractional positions around lag T0. The position at which the * interpolation function reaches its maximum is the fractional pitch. * Starting point of the search is frac, end point is last_frac. * frac is overwritten with the fractional pitch. * *************************************************************************/static void searchFrac ( Word16 *lag, Word16 *frac, Word16 last_frac, Word16 corr[], Word16 flag3 )
{
Word16 i; Word16 max,fra ;
Word16 corr_int;
Word16 *x1, *x2,*x,*fract,*lagg,*pcorr;
const Word16 *c1, *c2,*pinter_6 = inter_6; Word32 s;
fract = frac; lagg= lag; pcorr = corr;
/* Test the fractions around T0 and choose the one which maximizes . the interpolated normalized correlation. */
max = MIN_16;
for (i = (*fract); i <= last_frac; i++)
{ // corr_int = Interpol_3or6 (&corr[*lag], i, flag3);
x = &pcorr[*lagg];
fra = i;
fra <<= (flag3 != 0);
x -= (fra < 0);
fra += UP_SAMP_MAX*(fra < 0);
x1 = &x[0];
x2 = &x[1];
c1 = &pinter_6[fra];
c2 = &pinter_6[UP_SAMP_MAX - fra];
s = (x1[0]*c1[0] + x2[0]*c2[0]+ x1[-1]*c1[6] + x2[1]*c2[6]+ x1[-2]*c1[12] + x2[2]*c2[12]+ x1[-3]*c1[18] + x2[3]*c2[18] )<<1;
corr_int = ((s + 0x00008000)>> 16 );
*fract = corr_int > max ? i : *fract;
max = corr_int > max ? corr_int : max;
}
if (flag3 == 0) {
*lagg -= (*fract== -3);
*fract = (*fract== -3) ? 3 : *fract ;
} else {
*lagg -= ( *fract== -2) ;
*fract = ( *fract== -2) ? 1 : *fract ;
*lagg += ( *fract== 2) ;
*fract = ( *fract== 2) ? -1 : *fract;
}
}
/************************************************************************* * * FUNCTION: Pitch_fr() * * PURPOSE: Find the pitch period with 1/3 or 1/6 subsample resolution * (closed loop). * * DESCRIPTION: * - find the normalized correlation between the target and filtered * past excitation in the search range. * - select the delay with maximum normalized correlation. * - interpolate the normalized correlation at fractions -3/6 to 3/6 * with step 1/6 around the chosen delay. * - The fraction which gives the maximum interpolated value is chosen. * *************************************************************************/Word16 Pitch_fr ( Pitch_frState *st, Mode mode, Word16 T_op[], Word16 exc[], Word16 xn[], Word16 h[],
Word16 L_subfr, Word16 i_subfr, Word16 *pit_frac,Word16 *resu3, Word16 *ana_index )
{
Word16 i;
Word16 t_min, t_max;
Word16 t0_min, t0_max;
Word16 max, lag, frac;
Word16 tmp_lag;
Word16 *corr;
Word16 corr_v[40]; /* Total length = t0_max-t0_min+1+2*L_INTER_SRCH */
Word16 max_frac_lag;
Word16 flag3, flag4;
Word16 last_frac;
Word16 delta_int_low, delta_int_range;
Word16 delta_frc_low, delta_frc_range;
Word16 pit_min;
Word16 frame_offset;
Word16 delta_search;
Word16 index, tmp_ind, uplag;
Pitch_frState *pst = st;
Word16 *pT_op = T_op, *pexc = exc, *pxn = xn, *ph = h;
/*-----------------------------------------------------------------------*
* set mode specific variables *
*-----------------------------------------------------------------------*/
max_frac_lag = mode_dep_parm[mode].max_frac_lag;
flag3 = mode_dep_parm[mode].flag3;
frac = mode_dep_parm[mode].first_frac;
last_frac = mode_dep_parm[mode].last_frac;
delta_int_low = mode_dep_parm[mode].delta_int_low;
delta_int_range = mode_dep_parm[mode].delta_int_range;
delta_frc_low = mode_dep_parm[mode].delta_frc_low;
delta_frc_range = mode_dep_parm[mode].delta_frc_range;
pit_min = mode_dep_parm[mode].pit_min;
/*-----------------------------------------------------------------------*
* decide upon full or differential search *
*-----------------------------------------------------------------------*/
delta_search = 1;
if ((i_subfr == 0) || (i_subfr == L_FRAME_BY2))
{
/* Subframe 1 and 3 */
if ( ((mode != MR475) && (mode != MR515)) ||( i_subfr != L_FRAME_BY2 ) )
{
/* set t0_min, t0_max for full search , this is *not* done for mode MR475, MR515 in subframe 3 */
delta_search = 0; /* no differential search */
/* calculate index into T_op which contains the open-loop . pitch estimations for the 2 big subframes */
frame_offset = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -