📄 melp_ana.c
字号:
if (!uv[2] && !subenergyRelation1(classStat, curTrack)){
if ((voicedCnt < 2) || subenergyRelation2(classStat, curTrack)){
/* Got onset position, should look forward for pitch */
pitCand = pitLookahead(&pitTrack[curTrack], 3);
if (ratio(par[1].pitch, pitCand) > X015_Q15){
if (ratio(pitCand, par[2].pitch) < X015_Q15)
par[1].pitch = pitCand;
else {
npitch = pitLookahead(&pitTrack[curTrack + 1], 3);
if (ratio(npitch, par[2].pitch) < X015_Q15){
if (ratio(pitCand, npitch) < X015_Q15)
par[1].pitch = pitCand;
else if (ratio(par[1].pitch, npitch) > X015_Q15)
par[1].pitch = npitch;
} else if (ratio(pitCand, npitch) < X015_Q15)
par[1].pitch = pitCand;
}
}
} else if (!uv[1]){
/* not onset not offset, just check pitch smooth */
temp1 = sub(par[1].pitch, prev_pitch);
index1 = shr(temp1, 7);
temp2 = sub(par[2].pitch, par[1].pitch);
index2 = shr(temp2, 7);
pitCand = pitLookahead(&pitTrack[curTrack], 3);
if ((abs_s(index1) > 5) && (abs_s(index2) > 5) &&
(index1 * index2 < 0)){
/* here is a pitch jump */
if ((ratio(prev_pitch, pitCand) < X015_Q15) ||
(ratio(pitCand, par[2].pitch) < X02_Q15))
par[1].pitch = pitCand;
else {
/* par[1].pitch = (prev_pitch + par[2].pitch)/2; */
temp1 = shr(prev_pitch, 1);
temp2 = shr(par[2].pitch, 1);
par[1].pitch = add(temp1, temp2); /* Q7 */
}
} else if ((ratio(par[1].pitch, prev_pitch) > X015_Q15) &&
((ratio(par[2].pitch, prev_pitch) < X015_Q15) ||
(ratio(pitCand, prev_pitch) < X015_Q15))){
if (ratio(pitCand, prev_pitch) < X015_Q15)
par[1].pitch = pitCand;
else {
index1 = trackPitch(prev_pitch, &pitTrack[curTrack]);
pitCand = shl(pitTrack[curTrack].pit[index1], 7); /* !!! (12/10/99) */
index2 = trackPitch(par[1].pitch, &pitTrack[curTrack]);
w1_w2 = sub(pitTrack[curTrack].weight[index1],
pitTrack[curTrack].weight[index2]);
if (multiCheck(par[1].pitch, pitCand) < X008_Q15){
if (((par[1].pitch > pitCand) &&
(w1_w2 > MX02_Q15)) || (w1_w2 > X02_Q15))
par[1].pitch = pitCand;
} else if (w1_w2 > MX01_Q15)
par[1].pitch = pitCand;
}
} else if ((L_ratio(par[1].pitch, (Longword) (prev_pitch*2)) <
X008_Q15) ||
(L_ratio(par[1].pitch, (Longword) (prev_pitch*3)) <
X008_Q15)){
/* possible it is a double pitch */
pitCand = pitLookahead(&pitTrack[curTrack], 4);
if (ratio(pitCand, prev_pitch) < X01_Q15)
par[1].pitch = pitCand;
}
}
}
/* ======== The third frame ======== */
prev_pitch = shl(shr(par[1].pitch, 7), 7);
curTrack = CUR_TRACK + 4;
if (!uv[3])
voicedCnt++;
else
voicedCnt = 0;
if (!uv[3] && (classStat[curTrack + 1].classy == VOICED) &&
(classStat[curTrack + 2].classy == VOICED) &&
!subenergyRelation1(classStat, curTrack)){
if ((voicedCnt < 2) ||
subenergyRelation2(classStat, curTrack)){
/* Got onset position, should look forward for pitch */
pitCand = pitLookahead(&pitTrack[curTrack], 2);
if (ratio(par[2].pitch, pitCand) > X015_Q15){
npitch = pitLookahead(&pitTrack[curTrack + 1], 1);
if (ratio(npitch, pitCand) < X015_Q15)
par[2].pitch = pitCand;
else if (ratio(par[2].pitch, npitch) >= X015_Q15)
par[2].pitch = npitch;
}
} else if (!uv[2]){
/* not onset not offset, just check pitch smooth */
pitCand = pitLookahead(&pitTrack[curTrack], 2);
temp1 = sub(par[2].pitch, prev_pitch);
index1 = shr(temp1, 7);
temp2 = sub(pitCand, par[2].pitch);
index2 = shr(temp2, 7);
if ((abs_s(index1) > 5) && (abs_s(index2) > 5) &&
(index1 * index2 < 0)){
/* here is a pitch jump */
if (ratio(prev_pitch, pitCand) < X015_Q15)
par[2].pitch = pitCand;
else {
index1 = trackPitch(pitCand, &pitTrack[curTrack]);
index2 = trackPitch(par[2].pitch, &pitTrack[curTrack]);
w1_w2 = sub(pitTrack[curTrack].weight[index1],
pitTrack[curTrack].weight[index2]);
if (multiCheck(par[2].pitch, pitCand) < X008_Q15){
if (((par[2].pitch > pitCand) &&
(w1_w2 > MX02_Q15)) || (w1_w2 > X02_Q15))
par[2].pitch = pitCand;
} else {
index1 = trackPitch(prev_pitch, &pitTrack[curTrack]);
pitCand = shl(pitTrack[curTrack].pit[index1], 7); /* !!! (12/10/99) */
/* Note that w1 = pitTrack[curTrack].weight[index1] */
/* has ben modified from the value outside of the if */
/* condition. */
w1_w2 = sub(pitTrack[curTrack].weight[index1],
pitTrack[curTrack].weight[index2]);
if (multiCheck(par[2].pitch, pitCand) < X008_Q15){
if (((par[2].pitch > pitCand) &&
(w1_w2 > MX02_Q15)) || (w1_w2 > X02_Q15))
par[2].pitch = pitCand;
} else {
/* par[2].pitch = (prev_pitch + pitCand)/2; */
temp1 = shr(prev_pitch, 1);
temp2 = shr(pitCand, 1);
par[2].pitch = add(temp1, temp2); /* Q7 */
}
}
}
}
}
}
/* ======== Try smooth voicing information ======== */
sbp[0] = prev_sbp3;
for (i = 0; i < NF; i++){
/* Make a copy of par[i].bpvc because the function q_bpvc() will */
/* change them. Hence we use the copy for q_bpvc(). */
v_equ(bpvc_copy, par[i].bpvc, NUM_BANDS);
/* We call q_bpvc() to determine index from the quantization. */
/* However, whether par[i].bpvc[0] > BPTHRESH_Q14 or not cannot be */
/* judged based on the returned index. Therefore we use the returned */
/* value of the function call q_bpvc(). */
if (q_bpvc(bpvc_copy, &index, NUM_BANDS))
sbp[i + 1] = -1;
else
sbp[i + 1] = inv_bp_index_map[bp_index_map[index]];
}
/* At this point sbp[] is either 0, 8, 12, 15 or -1. Note that each bit */
/* of sbp[i] corresponds to the entries of par[i].bpvc[]. The inequality */
/* sbp[] > 12 implies it has to be 15, or par[i].bpvc[] has to satisfy a */
/* certain relationship about whether they are greater or small than */
/* BPTHRESH_Q14. Similarly, when we apply a Max() or Min() operation on */
/* sbp[], more or less we are saying "set par[i].bpvc[] to ONE_Q14" or */
/* "reset par[i].bpvc[] to 0". */
for (i = 1; i < NF; i++){
curTrack = (Shortword) (CUR_TRACK + (i - 1)*2);
if ((sbp[i - 1] > 12) && (sbp[i + 1] > 12)){
if ((classStat[curTrack].subEnergy > voicedEn - X05_Q11) ||
((par[i - 1].bpvc[2] > X05_Q14) &&
(par[i - 1].bpvc[3] > X05_Q14))){
if (sbp[i] < 12)
sbp[i] = 12;
} else {
if (sbp[i] < 8)
sbp[i] = 8;
}
} else if ((sbp[i - 1] > 8) && (sbp[i + 1] > 8)){
if ((classStat[curTrack].subEnergy > voicedEn - ONE_Q11) ||
((par[i - 1].bpvc[2] > X04_Q14) &&
(par[i - 1].bpvc[3] > X04_Q14))){
if (sbp[i] < 8)
sbp[i] = 8;
}
} else if ((sbp[i - 1] < 8) && (sbp[i + 1] < 8)){
if ((classStat[curTrack].subEnergy < voicedEn - X05_Q11) &&
(par[i - 1].bpvc[3] < X07_Q14)){
if (sbp[i] > 12)
sbp[i] = 12;
}
}
}
curTrack = CUR_TRACK + 4;
if ((classStat[curTrack].subEnergy > voicedEn - X03_Q11) &&
(sbp[2] > 12) && (par[1].bpvc[2] > X05_Q14) &&
(par[1].bpvc[3] > X05_Q14)){
if (sbp[3] < 12)
sbp[3] = 12;
} else if ((classStat[curTrack].subEnergy > voicedEn - X05_Q11) &&
(sbp[2] > 8) && (par[1].bpvc[2] > X045_Q14) &&
(par[1].bpvc[3] > X045_Q14)){
if (sbp[3] < 8)
sbp[3] = 8;
}
/* ======== Depack and save back bpvc information ======== */
for (i = 0; i < NF; i++){
/* sbp[i + 1] and it can only be 0, 8, 12, 15 or -1, and it is never */
/* INVALID_BPVC (== 1). On the other hand, we can call q_bpvc_dec() */
/* with its uv_flag input argument passed in as FALSE, so par[i].bpvc */
/* will be completely determined by index. Note that passing uv_flag */
/* as FALSE will alter par[i].bpvc[0], so we save it and restore it. */
temp1 = par[i].bpvc[0];
q_bpvc_dec(par[i].bpvc, sbp[i + 1], FALSE, NUM_BANDS);
par[i].bpvc[0] = temp1;
}
prev_sbp3 = sbp[3];
/* ======== Update voiced and unvoiced counters ======== */
for (i = 0; i < NF; i++){
curTrack = (Shortword) (i * PIT_SUBNUM + CUR_TRACK);
/* ---- update voiced energy ---- */
if (voicedCnt > 2){
/* voicedEn = log10(EN_UP_RATE * pow(10.0, voicedEn) +
(1.0 - EN_UP_RATE) *
pow(10.0, classStat[curTrack].subEnergy)); */
voicedEn = updateEn(voicedEn, EN_UP_RATE_Q15,
classStat[curTrack].subEnergy);
}
if (voicedEn < classStat[curTrack].subEnergy)
voicedEn = classStat[curTrack].subEnergy;
}
/* ======== Update class and pitch structures ======== */
for (i = 0; i < TRACK_NUM - NF*PIT_SUBNUM; i++){
classStat[i] = classStat[i + NF * PIT_SUBNUM];
pitTrack[i] = pitTrack[i + NF * PIT_SUBNUM];
}
prev_uv = par[NF - 1].uv_flag;
/* Set prev_pitch to par[NF - 1].pitch so that it is an integer for its */
/* Q value. We first use shr() to truncate par[NF - 1].pitch and then */
/* use shl() to correct the Q value. */
prev_pitch = shl(shr(par[NF - 1].pitch, 7), 7);
}
static BOOLEAN subenergyRelation1(classParam classStat[], Shortword curTrack)
{
BOOLEAN result;
Shortword prevg, lastg, orig, nextg, futureg; /* Q11 */
prevg = classStat[curTrack - 2].subEnergy;
lastg = classStat[curTrack - 1].subEnergy;
orig = classStat[curTrack].subEnergy;
nextg = classStat[curTrack + 1].subEnergy;
futureg = classStat[curTrack + 2].subEnergy;
result = (BOOLEAN)
(((lastg - prevg < X05_Q11) && (orig - lastg < X05_Q11) &&
(nextg - orig < X05_Q11) &&
((prevg - lastg > X12_Q11) || (lastg - orig > X12_Q11) ||
(orig - nextg > X12_Q11))) ||
((orig - lastg < X03_Q11) && (nextg - orig < X03_Q11) &&
(((lastg - prevg < X03_Q11) &&
((prevg - orig > X08_Q11) || (lastg - nextg > X08_Q11))) ||
((futureg - nextg < X03_Q11) &&
((lastg - nextg > X08_Q11) || (orig - futureg > X08_Q11))))));
return(result);
}
static BOOLEAN subenergyRelation2(classParam classStat[], Shortword curTrack)
{
BOOLEAN result;
Shortword prevg, lastg, orig, nextg, futureg; /* Q11 */
prevg = classStat[curTrack - 2].subEnergy;
lastg = classStat[curTrack - 1].subEnergy;
orig = classStat[curTrack].subEnergy;
nextg = classStat[curTrack + 1].subEnergy;
futureg = classStat[curTrack + 2].subEnergy;
result = (BOOLEAN)
(((lastg - orig < X03_Q11) && (orig - nextg < X03_Q11) &&
(((prevg - lastg < X03_Q11) &&
((orig - prevg > X08_Q11) || (nextg - lastg > X08_Q11))) ||
((nextg - futureg < X03_Q11) &&
((nextg - lastg > X08_Q11) || (futureg - orig > X08_Q11))))) ||
((prevg - lastg < X05_Q11) && (lastg - orig < X05_Q11) &&
(orig - nextg < X05_Q11) &&
((lastg - prevg > X12_Q11) || (orig - lastg > X12_Q11) ||
(nextg - orig > X12_Q11))));
return(result);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -