📄 pst.c
字号:
/* save energy for final decision */
if(sh_ener > 0) {
ener = extract_l(L_shr(L_acc, sh_ener));
}
else {
sh_ener = 0;
ener = extract_l(L_acc);
}
/*************************************/
/* Selects best of 3 integer delays */
/* Maximum of 3 numerators around t0 */
/*************************************/
lambda = sub(t0,1);
ptr_sig_past = ptr_sig_in - lambda;
L_num_int = -1L;
/* initialization used only to suppress Microsoft Visual C++ warnings */
i_max = (Word16)0;
for(i=0; i<3; i++) {
L_acc = 0L;
for(n=0; n<L_SUBFR; n++) {
L_acc = L_mac( L_acc, ptr_sig_in[n] , ptr_sig_past[n]);
}
if(L_acc < 0) {
L_acc = 0L;
}
L_temp =L_sub(L_acc ,L_num_int);
if(L_temp > 0L) {
L_num_int = L_acc;
i_max = (Word16)i;
}
ptr_sig_past--;
}
if(L_num_int == 0) {
*num_gltp = 0;
*den_gltp = 1;
*ltpdel = 0;
*phase = 0;
return;
}
/* Compute den for i_max */
lambda = add(lambda, (Word16)i_max);
ptr_sig_past = ptr_sig_in - lambda;
L_acc = 0L;
for(i=0; i<L_SUBFR; i++) {
temp = *ptr_sig_past++;
L_acc = L_mac( L_acc, temp, temp);
}
if(L_acc == 0L) {
*num_gltp = 0;
*den_gltp = 1;
*ltpdel = 0;
*phase = 0;
return;
}
L_den_int = L_acc;
/***********************************/
/* Select best phase around lambda */
/***********************************/
/* Compute y_up & denominators */
/*******************************/
ptr_y_up = y_up;
L_den_max = L_den_int;
ptr_L_den0 = L_den0;
ptr_L_den1 = L_den1;
ptr_h = tab_hup_s;
temp = sub(lambda, LH_UP_SM1);
ptr_sig_past0 = ptr_sig_in - temp;
/* Loop on phase */
for(phi=1; phi<F_UP_PST; phi++) {
/* Compute y_up for lambda+1 - phi/F_UP_PST */
/* and lambda - phi/F_UP_PST */
ptr_sig_past = ptr_sig_past0;
for(n = 0; n<=L_SUBFR; n++) {
ptr1 = ptr_sig_past++;
L_acc = 0L;
for(i=0; i<LH2_S; i++) {
L_acc = L_mac(L_acc, ptr_h[i], ptr1[-i]);
}
ptr_y_up[n] = round(L_acc);
}
/* compute den0 (lambda+1) and den1 (lambda) */
/* part common to den0 and den1 */
L_acc = 0L;
for(n=1; n<L_SUBFR; n++) {
L_acc = L_mac(L_acc, ptr_y_up[n] ,ptr_y_up[n]);
}
L_temp0 = L_acc; /* saved for den1 */
/* den0 */
L_acc = L_mac(L_acc, ptr_y_up[0] ,ptr_y_up[0]);
*ptr_L_den0 = L_acc;
/* den1 */
L_acc = L_mac(L_temp0, ptr_y_up[L_SUBFR] ,ptr_y_up[L_SUBFR]);
*ptr_L_den1 = L_acc;
if(sub(abs_s(ptr_y_up[0]),abs_s(ptr_y_up[L_SUBFR])) >0) {
L_temp =L_sub(*ptr_L_den0 ,L_den_max );
if(L_temp> 0L) {
L_den_max = *ptr_L_den0;
}
}
else {
L_temp =L_sub(*ptr_L_den1 ,L_den_max );
if(L_temp> 0L) {
L_den_max = *ptr_L_den1;
}
}
ptr_L_den0++;
ptr_L_den1++;
ptr_y_up += L_SUBFRP1;
ptr_h += LH2_S;
}
if(L_den_max == 0) {
*num_gltp = 0;
*den_gltp = 1;
*ltpdel = 0;
*phase = 0;
return;
}
sh_den = sub(16, norm_l(L_den_max));
/* if sh_den <= 0 : dynamic between current frame */
/* and delay line too high */
if(sh_den <= 0) {
*num_gltp = 0;
*den_gltp = 1;
*ltpdel = 0;
*phase = 0;
return;
}
/* search sh_num to justify correlations */
/* sh_num = Max(sh_den, sh_ener) */
sh_num = (sub( sh_den , sh_ener)>=0) ? sh_den : sh_ener;
/* Computation of the numerators */
/* and selection of best num*num/den */
/* for non null phases */
/* Initialize with null phase */
L_acc = L_shr(L_den_int, sh_den); /* sh_den > 0 */
den_max = extract_l(L_acc);
L_acc = L_shr(L_num_int, sh_num); /* sh_num > 0 */
num_max = extract_l(L_acc);
L_acc = L_mult(num_max, num_max);
L_Extract(L_acc, &hi_numsq_max, &lo_numsq_max);
phi_max = 0;
ioff = 1;
ptr_L_den0 = L_den0;
ptr_L_den1 = L_den1;
ptr_y_up = y_up;
/* if den_max = 0 : will be selected and declared unvoiced */
/* if num!=0 & den=0 : will be selected and declared unvoiced */
/* degenerated seldom cases, switch off LT is OK */
/* Loop on phase */
for(phi=1; phi<F_UP_PST; phi++) {
/* compute num for lambda+1 - phi/F_UP_PST */
L_acc = 0L;
for(n = 0; n<L_SUBFR; n++) {
L_acc = L_mac(L_acc, ptr_sig_in[n] ,ptr_y_up[n]);
}
L_acc = L_shr(L_acc, sh_num); /* sh_num > 0 */
if(L_acc < 0L) {
num = 0;
}
else {
num = extract_l(L_acc);
}
/* selection if num**2/den0 max */
L_acc = L_mult(num, num);
L_Extract(L_acc, &hi_numsq, &lo_numsq);
L_temp0 = Mpy_32_16(hi_numsq, lo_numsq, den_max);
L_acc = *ptr_L_den0++;
L_acc = L_shr(L_acc, sh_den); /* sh_den > 0 */
den0 = extract_l(L_acc);
L_temp1 = Mpy_32_16(hi_numsq_max, lo_numsq_max, den0);
L_temp = L_sub(L_temp0, L_temp1);
if(L_temp>0L) {
num_max = num;
hi_numsq_max = hi_numsq;
lo_numsq_max = lo_numsq;
den_max = den0;
ioff = 0;
phi_max = phi;
}
/* compute num for lambda - phi/F_UP_PST */
ptr_y_up++;
L_acc = 0L;
for(n = 0; n<L_SUBFR; n++) {
L_acc = L_mac(L_acc, ptr_sig_in[n] ,ptr_y_up[n]);
}
L_acc = L_shr(L_acc, sh_num); /* sh_num > 0 */
if(L_acc < 0L) {
num = 0;
}
else {
num = extract_l(L_acc);
}
/* selection if num**2/den1 max */
L_acc = L_mult(num, num);
L_Extract(L_acc, &hi_numsq, &lo_numsq);
L_temp0 = Mpy_32_16(hi_numsq, lo_numsq, den_max);
L_acc = *ptr_L_den1++;
L_acc = L_shr(L_acc, sh_den); /* sh_den > 0 */
den1 = extract_l(L_acc);
L_temp1 = Mpy_32_16(hi_numsq_max, lo_numsq_max, den1);
L_temp = L_sub(L_temp0,L_temp1);
if(L_temp> 0L) {
num_max = num;
hi_numsq_max = hi_numsq;
lo_numsq_max = lo_numsq;
den_max = den1;
ioff = 1;
phi_max = phi;
}
ptr_y_up += L_SUBFR;
}
/***************************************************/
/*** test if normalized crit0[iopt] > THRESHCRIT ***/
/***************************************************/
if((num_max == 0) || (sub(den_max,1) <= 0)) {
*num_gltp = 0;
*den_gltp = 1;
*ltpdel = 0;
*phase = 0;
return;
}
/* compare num**2 */
/* to ener * den * 0.5 */
/* (THRESHCRIT = 0.5) */
L_temp1 = L_mult(den_max, ener);
L_temp0 = L_Comp(hi_numsq_max, lo_numsq_max);
/* temp = 2 * sh_num - sh_den - sh_ener + 1 */
/* 16 bits with no overflows */
temp = shl(sh_num,1);
temp = sub(temp, sh_den);
temp = sub(temp, sh_ener);
temp = add(temp, 1);
if(temp < 0) {
temp = negate(temp); /* no overflow */
L_temp0 = L_shr(L_temp0, temp);
}
else {
if(temp > 0) L_temp1 = L_shr(L_temp1, temp);
}
L_temp = L_sub(L_temp0 ,L_temp1);
if(L_temp >= 0L) {
temp = add(lambda, 1);
*ltpdel = sub(temp, ioff);
*off_yup = ioff;
*phase = phi_max;
*num_gltp = num_max;
*den_gltp = den_max;
*sh_den_gltp = sh_den;
*sh_num_gltp = sh_num;
}
else {
*num_gltp = 0;
*den_gltp = 1;
*ltpdel = 0;
*phase = 0;
}
return;
}
/*----------------------------------------------------------------------------
* filt_plt - ltp postfilter
*----------------------------------------------------------------------------
*/
static void filt_plt(
Word16 *s_in, /* input : input signal with past*/
Word16 *s_ltp, /* input : filtered signal with gain 1 */
Word16 *s_out, /* output: output signal */
Word16 gain_plt /* input : filter gain */
)
{
/* Local variables */
int n;
Word32 L_acc;
Word16 gain_plt_1;
gain_plt_1 = sub(32767, gain_plt);
gain_plt_1 = add(gain_plt_1, 1); /* 2**15 (1 - g) */
for(n=0; n<L_SUBFR; n++) {
/* s_out(n) = gain_plt x s_in(n) + gain_plt_1 x s_ltp(n) */
L_acc = L_mult(gain_plt, s_in[n]);
L_acc = L_mac(L_acc, gain_plt_1, s_ltp[n]); /* no overflow */
s_out[n] = round(L_acc);
}
return;
}
/*----------------------------------------------------------------------------
* compute_ltp_l : compute delayed signal,
num & den of gain for fractional delay
* with long interpolation filter
*----------------------------------------------------------------------------
*/
static void compute_ltp_l(
Word16 *s_in, /* input signal with past*/
Word16 ltpdel, /* delay factor */
Word16 phase, /* phase factor */
Word16 *y_up, /* delayed signal */
Word16 *num, /* numerator of LTP gain */
Word16 *den, /* denominator of LTP gain */
Word16 *sh_num, /* justification factor of num */
Word16 *sh_den /* justification factor of den */
)
{
/**** Table of constants declared externally */
extern Word16 tab_hup_l[SIZ_TAB_HUP_L];
/* Pointer on table of constants */
Word16 *ptr_h;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -