⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 melp_ana.c

📁 MELPe 1200 bps, fixed point
💻 C
📖 第 1 页 / 共 3 页
字号:
	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 + -