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

📄 classify.c

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