📄 classify.c
字号:
subEnergyDiff = sub(classStat->subEnergy, classStat[-1].subEnergy);
/* Q11 */
/* ========== Classifier ========== */
if (classStat->subEnergy < SILENCE_DB_Q11)
classy = SILENCE;
else if (classStat->subEnergy <
interp_scalar(voicedEn, silenceEn, X065_Q15)){
/* quite possible it is silence or UNVOICED */
/* unless the noise level is very high */
if ((classStat->zeroCrosRate > X06_Q15) &&
((classStat->corx < X04_Q15) || (lowBandCorx < X05_Q15)))
classy = UNVOICED;
else if ((lowBandCorx > X07_Q15) || ((lowBandCorx > X04_Q15) &&
(classStat->corx > X07_Q15)))
classy = VOICED;
else if ((zeroCrosRateDiff > X03_Q15) || (subEnergyDiff > TWO_Q11) ||
(classStat->peakiness > X16_Q11))
classy = TRANSITION;
else if ((classStat->zeroCrosRate > X055_Q15) ||
((lowhighBandDiff < X05_Q12) &&
(classStat->zeroCrosRate > X04_Q15)))
classy = UNVOICED;
else
classy = SILENCE;
} else if ((zeroCrosRateDiff > X02_Q15) || (subEnergyDiff > TWO_Q11) ||
(classStat->peakiness > X16_Q11)){
if ((lowBandCorx > X07_Q15) || (classStat->corx > X08_Q15))
classy = VOICED;
else
classy = TRANSITION;
} else if (classStat->zeroCrosRate < X02_Q15){
/* unless very low energy, it should be voiced */
if ((lowBandCorx > X05_Q15) ||
((lowBandCorx > X03_Q15) && (classStat->corx > X06_Q15)))
classy = VOICED;
else if (classStat->subEnergy >
interp_scalar(voicedEn, silenceEn, X03_Q15)){
if (classStat->peakiness > X15_Q11)
classy = TRANSITION;
else
classy = VOICED;
} else
classy = SILENCE;
} else if (classStat->zeroCrosRate < X05_Q15){ /* not sure */
if ((lowBandCorx > X055_Q15) ||
((lowBandCorx > X03_Q15) && (classStat->corx > X065_Q15)))
classy = VOICED;
else if ((classStat->subEnergy <
interp_scalar(voicedEn, silenceEn, X06_Q15)) &&
(lowhighBandDiff > ONE_Q12))
classy = SILENCE;
else if (classStat->peakiness > X14_Q11)
classy = TRANSITION;
else
classy = UNVOICED;
} else if (classStat->zeroCrosRate < X07_Q15){
/* quite possible unvoiced */
if (((lowBandCorx > X06_Q15) && (classStat->corx > X03_Q15)) ||
((lowBandCorx > X04_Q15) && (classStat->corx > X07_Q15)))
classy = VOICED;
else if (classStat->peakiness > X15_Q11)
classy = TRANSITION;
else
classy = UNVOICED;
} else { /* very likely unvoiced */
if (((lowBandCorx > X065_Q15) && (classStat->corx > X03_Q15)) ||
((lowBandCorx > X045_Q15) && (classStat->corx > X07_Q15)))
classy = VOICED;
else if (classStat->peakiness > TWO_Q11)
classy = TRANSITION;
else
classy = UNVOICED;
}
classStat->classy = classy;
}
/****************************************************************************
**
** Function: zeroCrosCount
**
** Description: Zero Crossing Rate Computation
**
** Arguments:
**
** Shortword speech[] Input speech buffer (Q0)
**
** Return value:
** Shortword Zero Crossing Rate (Q15)
**
*****************************************************************************/
static Shortword zeroCrosCount(Shortword speech[])
{
register Shortword i;
Shortword dcfree_speech[PIT_SUBFRAME];
Shortword prev_sign, current_sign;
Shortword count;
/* ======== Short term DC remove ======== */
remove_dc(speech, dcfree_speech, PIT_SUBFRAME);
/* ======== Count the number of zero crossings ======== */
count = 0;
if (dcfree_speech[0] >= 0)
prev_sign = 1;
else
prev_sign = -1;
for (i = 1; i < PIT_SUBFRAME; i++){
if (dcfree_speech[i] >= 0)
current_sign = 1;
else
current_sign = -1;
if ((prev_sign + current_sign) == 0)
count ++;
prev_sign = current_sign;
}
return(divide_s(count, PIT_SUBFRAME)); /* Q15 */
}
/****************************************************************************
**
** Function: bandEn
**
** Description: computate the low band energy from autocorrelation func.
**
** Arguments:
**
** Shortword autocorr[] ---- input autocorrelation function (Q15)
**
** Return value:
** Shortword ---- the low band energy (Q12)
**
*****************************************************************************/
static Shortword bandEn(Shortword autocorr[], Shortword band)
{
register Shortword i;
const Shortword *coef; /* Q16 */
Shortword temp;
Longword energy;
if (band == 0) /* low band */
coef = enlpf_coef;
else
coef = enhpf_coef;
/* Accumulated sum for "energy". coef[0] is the one with the largest */
/* absolute value in coef[], but it is still less than 0.5. autocorr[] */
/* are all less than 1. EN_FILTER_ORDER is 17, so energy is at most 17 */
/* (even this is a very loose upper bound). We might use a Q10 Shortword */
/* to store energy after the accumulation is done. */
energy = 0;
for (i = 1; i < EN_FILTER_ORDER; i++){
/* energy += 2.0*coef[i]*autocorr[i]; */
temp = mult(coef[i], autocorr[i]); /* Q14 */
energy = L_add(energy, L_deposit_l(temp));
}
energy = L_shl(energy, 1); /* multiplication by 2 */
temp = mult(coef[0], autocorr[0]); /* Q14 */
energy = L_add(energy, L_deposit_l(temp));
/* energy is Q14. Note that energy could be negative. */
if (energy < ONE_Q14)
return(0);
else {
temp = extract_l(L_shr(energy, 4)); /* Q10 */
temp = log10_fxp(temp, 10); /* Q12 */
/* Note that we return log10(energy) instead of 10.0*log10(energy). */
return(temp);
}
}
/****************************************************************************
**
** Function: frac_cor
**
** Description: computate the correlation coeff around specific pitch
**
** Arguments:
**
** Shortword inbuf[] ---- input data buffer (Q0)
** Shortword pitch ---- the input pitch center (Q0)
** Shortword *cor ---- output cor coeff (Q15)
**
** Return value: None
**
*****************************************************************************/
static void frac_cor(Shortword inbuf[], Shortword pitch, Shortword *cor)
{
register Shortword i, j;
Shortword lowPitch, highPitch; /* Q0 */
Shortword lowStart, highStart;
Shortword gp, maxgp, root, win, temp;
Shortword r0_shift, rk_shift, shift;
Longword L_r0, L_rk, L_temp; /* Q7 */
Word40 ACC_r0, ACC_rk, ACC_A; /* Emulating 40Bit-Accumulator */
/* ------ Calculate the autocorrelation function ------- */
/* This is the new version of the autocorrelation function */
/* (Andre Ebner, 11/30/99) */
lowPitch = sub(pitch, PITCH_RANGE);
highPitch = add(pitch, PITCH_RANGE);
if (lowPitch < MINPITCH)
lowPitch = MINPITCH;
if (highPitch > MAXPITCH)
highPitch = MAXPITCH;
ACC_r0 = 0;
for (i = 0; i < (PIT_COR_LEN - highPitch); i++){
ACC_r0 = L40_mac(ACC_r0, inbuf[i], inbuf[i]);
}
if (ACC_r0 == 0)
ACC_r0 = 1;
r0_shift = norm32(ACC_r0);
ACC_r0 = L40_shl(ACC_r0, r0_shift);
L_r0 = (Longword) ACC_r0;
ACC_rk = 0;
for (i = highPitch; i < PIT_COR_LEN; i++){
ACC_rk = L40_mac(ACC_rk, inbuf[i], inbuf[i]); /* Q31 */
}
if (ACC_rk == 0)
ACC_rk = 1;
rk_shift = norm32(ACC_rk);
ACC_rk = L40_shl(ACC_rk, rk_shift);
L_rk = (Longword) ACC_rk;
ACC_A = 0;
for (i = 0; i < PIT_COR_LEN - highPitch; i++){
ACC_A = L40_mac(ACC_A, inbuf[i], inbuf[i+highPitch]); /* Q31 */
}
shift = add(r0_shift, rk_shift);
if (shift & 1){
L_r0 = L_shr(L_r0, 1);
r0_shift = sub(r0_shift, 1);
shift = add(r0_shift, rk_shift);
}
shift = shr(shift, 1);
ACC_A = L40_shl(ACC_A, shift);
temp = mult(extract_h(L_r0),extract_h(L_rk));
root = sqrt_Q15(temp);
L_temp = (Longword) ACC_A;
temp = extract_h(L_temp);
if (temp < 0)
temp = 0; /* Negative Autocorrelation doesn't make sense here */
maxgp = divide_s(temp, root);
lowStart = 0;
highStart = highPitch;
win = sub(PIT_COR_LEN, highPitch);
for (i = sub(highPitch, 1); i >= lowPitch; i--){
gp = 0;
if (i % 2 == 0){
ACC_r0 = L_r0;
ACC_r0 = L40_shr(ACC_r0, r0_shift);
ACC_r0 = L40_msu(ACC_r0, inbuf[lowStart], inbuf[lowStart]);
ACC_r0 = L40_mac(ACC_r0, inbuf[lowStart+win], inbuf[lowStart+win]);
if (ACC_r0 == 0)
ACC_r0 = 1;
r0_shift = norm32(ACC_r0);
ACC_r0 = L40_shl(ACC_r0, r0_shift);
L_r0 = (Longword) ACC_r0;
lowStart++;
} else {
highStart--;
ACC_rk = L_rk;
ACC_rk = L40_shr(ACC_rk, rk_shift);
ACC_rk = L40_mac(ACC_rk, inbuf[highStart], inbuf[highStart]);
ACC_rk = L40_msu(ACC_rk, inbuf[highStart+win], inbuf[highStart+win]);
if (ACC_rk == 0)
ACC_rk = 1;
rk_shift = norm32(ACC_rk);
ACC_rk = L40_shl(ACC_rk, rk_shift);
L_rk = (Longword) ACC_rk;
}
ACC_A = 0;
for (j = lowStart; j < lowStart + win; j++){
ACC_A = L40_mac(ACC_A, inbuf[j], inbuf[j+i]);
}
shift = add(r0_shift, rk_shift);
if (shift & 1){
L_r0 = L_shr(L_r0, 1);
r0_shift = sub(r0_shift, 1);
shift = add(r0_shift, rk_shift);
}
shift = shr(shift, 1);
ACC_A = L40_shl(ACC_A, shift);
temp = mult(extract_h(L_r0), extract_h(L_rk));
root = sqrt_Q15(temp);
L_temp = (Longword) ACC_A;
temp = extract_h(L_temp);
gp = divide_s(temp, root);
if (gp>maxgp) maxgp = gp;
}
*cor = maxgp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -