📄 ol_ltp.c
字号:
}
else
{
pst->old_T0_med = p_max1;
pst->ada_w = (pst->ada_w*29491 >>15); /* = ada_w = ada_w * 0.9 */
}
pst->wght_flg = ( pst->ada_w >= 9830 );
#ifndef VAD2 if (dtx) { /* no test() call since this if is only in simulation env */ if ( idx == 1)
{ /* calculate max high-passed filtered correlation of all lags */ hp_max (corr_ptr, scal_sig, L_frame, pit_max, pit_min, &corr_hp_max);
/* update complex background detector */ // vad_complex_detection_update(vadSt, corr_hp_max);
pvadSt->best_corr_hp = corr_hp_max;
} }#endif return (p_max1);
}
/*************************************************************************** Function: cl_ltp* Purpose: closed-loop fractional pitch search****************************************************************************/
int cl_ltp ( clLtpState *clSt, tonStabState *tonSt, Mode mode, Word16 frameOffset, Word16 T_op[], Word16 *h1,
Word16 *exc, Word16 res2[], Word16 xn[], Word16 lsp_flag, Word16 xn2[],
Word16 y1[], Word16 *T0, Word16 *T0_frac, Word16 *gain_pit,Word16 g_coeff[], Word16 **anap, Word16 *gp_limit )
{
Word16 i;
Word16 index; Word32 L_temp; /* temporarily variable */ Word16 resu3; /* flag for upsample resolution */ Word16 gpc_flag; /*----------------------------------------------------------------------* * Closed-loop fractional pitch search * *----------------------------------------------------------------------*/ *T0 = Pitch_fr(clSt->pitchSt, mode, T_op, exc, xn, h1, L_SUBFR, frameOffset, T0_frac, &resu3, &index);
*(*anap)++ = index; /*-----------------------------------------------------------------* * - find unity gain pitch excitation (adapitve codebook entry) * * with fractional interpolation. * * - find filtered pitch exc. y1[]=exc[] convolve with h1[]) * * - compute pitch gain and limit between 0 and 1.2 * * - update target vector for codebook search * * - find LTP residual. * *-----------------------------------------------------------------*/ Pred_lt_3or6(exc, *T0, *T0_frac, L_SUBFR, resu3); Convolve(exc, h1, y1, L_SUBFR); /* gain_pit is Q14 for all modes */ *gain_pit = G_pitch(mode, xn, y1, g_coeff, L_SUBFR); /* check if the pitch gain should be limit due to resonance in LPC filter */ gpc_flag = 0; *gp_limit = MAX_16; if ((lsp_flag != 0) && (*gain_pit > GP_CLIP) ) { // gpc_flag = check_gp_clipping(tonSt, *gain_pit);
L_temp = *gain_pit>> 3; /* Division by 8 */
for (i = 0; i < N_FRAME; i++) { L_temp += tonSt->gp[i] ;
} gpc_flag = L_temp > GP_CLIP ? 1 : 0;
} /* special for the MR475, MR515 mode; limit the gain to 0.85 to */ /* cope with bit errors in the decoder in a better way. */ if (( mode == MR475) || (mode == MR515)) { if ( *gain_pit >13926) { *gain_pit = 13926; /* 0.85 in Q14 */ } if (gpc_flag != 0) { *gp_limit = GP_CLIP; } } else { if (gpc_flag != 0) { *gp_limit = GP_CLIP; *gain_pit = GP_CLIP; } /* For MR122, gain_pit is quantized here and not in gainQuant */ if (mode == MR122 ) { *(*anap)++ = q_gain_pitch(MR122, *gp_limit, gain_pit, NULL, NULL); } } /* update target vector und evaluate LTP residual */ for (i = 0; i < L_SUBFR; i++) { L_temp = y1[i]*(*gain_pit) << 1; L_temp = (L_temp<<1); xn2[i] = (Word16)(xn[i]- (L_temp>>16 )); L_temp = exc[i]*( *gain_pit) << 1; L_temp <<= 1 ; res2[i] = (Word16)(res2[i] -(L_temp >> 16 )); }
return 0;}
/*************************************************************************
* * FUNCTION: G_pitch * * PURPOSE: Compute the pitch (adaptive codebook) gain. * Result in Q14 (NOTE: 12.2 bit exact using Q12) * * DESCRIPTION: * The adaptive codebook gain is given by * * g = <x[], y[]> / <y[], y[]> * * where x[] is the target vector, y[] is the filtered adaptive * codevector, and <> denotes dot product. * The gain is limited to the range [0,1.2] (=0..19661 Q14) * *************************************************************************/Word16 G_pitch ( Mode mode, Word16 xn[], Word16 y1[], Word16 g_coeff[], Word16 L_subfr )
{
Word16 i; Word16 xy, yy, exp_xy, exp_yy, gain; Word32 s; Word16 scaled_y1[L_SUBFR]; /* Usually dynamic allocation of (L_subfr) */ /* divide "y1[]" by 4 to avoid overflow */ for (i = 0; i < L_subfr; i++) { scaled_y1[i] = y1[i]>> 2; } /* Compute scalar product <y1[],y1[]> */ /* Q12 scaling / MR122 */
s = 1L;
for (i = 0; i < L_subfr; i++) {
s += y1[i]* y1[i]<<1;
if ( s < 0)
{ s =MAX_32; break;
} }
if (s != MAX_32 )
{ exp_yy = norm_l (s);
yy = ((s<<exp_yy)>0)&&((s<<exp_yy) + 0x00008000 ) < 0 ? 0x7fff : ((s<<exp_yy) + 0x00008000 )>> 16; } else { s = 1L; for (i = 0; i < L_subfr; i++) { //s = L_mac (s, scaled_y1[i], scaled_y1[i]); s += scaled_y1[i]*scaled_y1[i]<<1; } exp_yy = norm_l (s); yy = ((s<<exp_yy)>0)& (((s<<exp_yy) + 0x00008000 ) < 0) ? 0x7fff : ((s<<exp_yy) + 0x00008000 )>> 16; exp_yy -= 4 ; } /* Compute scalar product <xn[],y1[]> */
s = 1L; for (i = 0; i < L_subfr; i++) {
s += xn[i]* y1[i] <<1;
} if (s != MAX_32 )
{ exp_xy = norm_l (s);
xy = ((s<<exp_xy)>0 )&(((s<<exp_xy) + 0x00008000) < 0) ? 0x7fff: ((s<<exp_xy) + 0x00008000)>>16; } else { s = 1L; for (i = 0; i < L_subfr; i++) {
s += xn[i]*scaled_y1[i] << 1; } exp_xy = norm_l (s);
xy =((s<< exp_xy) > 0 )&(((s<< exp_xy) + 0x00008000 ) < 0) ? 0x7fff : ((s<< exp_xy) + 0x00008000 )>> 16 ; exp_xy -= 2 ; } g_coeff[0] = yy; g_coeff[1] = 15 - exp_yy; g_coeff[2] = xy; g_coeff[3] = 15 - exp_xy; /* If (xy < 4) gain = 0 */ if (xy < 4)
return ((Word16) 0); /* compute gain = xy/yy */
xy >>= 1;
gain = div_s (xy, yy); i = (exp_xy -exp_yy); /* Denormalization of division */
gain = i >0 ? (gain>>i) : ( gain >= (0x7fff>>(-i)) ? 0x7fff: gain<< -i) ;
gain = (gain > 19661) ? 19661 : gain;
gain = (mode == MR122) ? gain & 0xfffC : gain ;
return (gain);
}
Word16 hp_max ( Word32 corr[],Word16 scal_sig[], Word16 L_frame, Word16 lag_max, Word16 lag_min, Word16 *cor_hp_max)
{
Word16 i; Word16 *p, *p1,*p2;
Word32 max, t0, t1,temp32;
Word16 max16, t016, cor_max; Word16 shift, shift1, shift2;
Word32*pcorr = corr;
Word16*pscal_sig = scal_sig, *corhpmax;
corhpmax = cor_hp_max;
max = MIN_32; t0 = 0L;
for (i = lag_max-1; i > lag_min; i--) { /* high-pass filtering */
t0 = (pcorr[-i]<<1)-pcorr[-i-1] -pcorr[-i+1] ;
t0 = t0<0 ? -t0 :t0 ;
max = (t0 >= max ) ? t0 :max;
} /* compute energy */ p = pscal_sig;
p2 = &pscal_sig[0];
t0 = t1 = 0L;
p1 = &pscal_sig[-1];
for (i = 0; i < L_frame; i+=4, p+=4, p2+=4,p1+=4)
{ t0 += (p[0]*p2[0] + p[1]*p2[1]+ p[2]*p2[2]+ p[3]*p2[3])<<1;
t1 += (p[0]*p1[0] + p[1]*p1[1]+ p[2]*p1[2]+ p[3]*p1[3])<<1;
}
/* high-pass filtering */ t0 = (t0 - t1)<< 1;
t0 = t0<0 ? -t0 :t0 ;
//shift1 = norm_l(max) - 1;
if( 0 == max) shift1 = 0;
else
{
temp32 = max;
for (shift1 = 0; temp32 < (Word32) 0x40000000L; shift1++)
{
temp32 <<= 1;
}
}
shift1--;
max16 = (Word16)((max<< shift1) >>16) ;
// shift2 = norm_l(t0);
if(0 == t0) shift2 = 0;
else
{
temp32 = t0;
for (shift2 = 0; temp32 < (Word32) 0x40000000L; shift2++)
{
temp32 <<= 1;
}
}
t016 = (Word16)((t0<< shift2)>>16);
cor_max = (t016 != 0) ? div_s(max16, t016) : 0;
shift = shift1-shift2;
*corhpmax = (shift >= 0) ? cor_max>> shift :(cor_max >= ( MAX_16 >>(-shift)) ? MAX_16 : cor_max << (-shift)) ;
return 0;}
Word16 check_lsp(tonStabState *st, Word16 *lsp) /* i : unquantized LSP's */
{ Word16 dist_min1, dist_min2, dist_th;
Word16 d1,d2,d3;
Word16 *plsp = lsp;
/* Check for a resonance: */ /* Find minimum distance between lsp[i] and lsp[i+1] */ dist_min1 = MAX_16;
d1 = plsp[3]- plsp[4];d2 = plsp[4]- plsp[5]; d3= plsp[5]- plsp[6];
d1 = d1<d2 ? d1 :d2; d1 = d1<d3? d1 : d3;
dist_min1 = dist_min1 > d1 ? d1 : dist_min1;
d1 = plsp[6]- plsp[7];d2 = plsp[7]- plsp[8]; d3= plsp[8]- plsp[9];
d1 = d1<d2 ? d1 :d2; d1 = d1<d3? d1 : d3;
dist_min1 = dist_min1 > d1 ? d1 : dist_min1;
dist_min2 = MAX_16;
d1 = plsp[1]- plsp[2];d2 = plsp[2]- plsp[3];
d1 = d1< d2 ? d1:d2;
dist_min2 = dist_min2 > d1 ? d1 : dist_min2;
if ( plsp[1]>32000)
{ dist_th = 600; } else if (plsp[1] >30500 )
{ dist_th = 800; } else { dist_th = 1100; } if ((dist_min1<1500) || (dist_min2<dist_th) )
{ st->count ++; } else { st->count = 0; } /* Need 12 consecutive frames to set the flag */ if ( st->count >= 12) { st->count = 12; return 1; } else { return 0; }
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -