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

📄 pitch.c

📁 MELPe 1200 bps, fixed point
💻 C
📖 第 1 页 / 共 2 页
字号:
	}

	classStat->corx = corx[0];

	j = 0;
	for (i = MINPITCH; i <= MAXPITCH; i++){
		if (index[i] != 0){
			pitTrack->pit[j] = i;
			pitTrack->weight[j] = corx[index[i] - 1];
			j ++;
		}
	}

	for(; j < NODE; j++){
		pitTrack->pit[j] = 100;

		/* The floating point version set pitTrack->weight[j] to -100.0 */
		/* here we use 0                                                */
		pitTrack->weight[j] = 0;
	}

	/* ---- Modify time domain correlation by muliple checking ---- */
	for (i = 0; i < NODE - 1; i++){
		for (j = (Shortword) (i + 1); j < NODE; j++){
			temp1 = pitTrack->pit[j];
			temp2 = pitTrack->pit[i];
			temp = temp2;
			while (temp < temp1){
				temp = add(temp, temp2);
			}
			temp2 = shr(temp2, 1);
			temp2 = sub(temp, temp2);
			if (temp2 >= temp1)
				temp = sub(temp, pitTrack->pit[i]);

			/* Now temp is the multiples of pitTrack->pit[i] which is the     */
			/* closest to pitTrack->pit[j].                                   */

			/*	rk_f = abs(pitTrack->pit[j] -
						   temp*pitTrack->pit[i])/pitTrack->pit[j]; */
			temp = sub(pitTrack->pit[j], temp);
			temp = abs_s(temp);
			temp2 = divide_s(temp, pitTrack->pit[j]);                  /* Q15 */

			if (temp2 < X008_Q15){
				/*	pitTrack->weight[j] -= pitTrack->weight[i]/5.0; */
				temp1 = pitTrack->weight[i];
				temp1 = mult(temp1, X02_Q15);
				temp2 = pitTrack->weight[j];
				temp2 = sub(temp2, temp1);
				if( temp2 < 0 )	temp2 = 0;
				pitTrack->weight[j] = temp2;
			}
		}
	}
}

/******************************************************************
**
** Function:	multiCheck
**
** Description: multiple or sub-multiple pitch check
**
** Input:
**		Shortword f1	------	the pitch candidate 1 (Q7)
**		Shortword f2	------	the pitch candidate 2 (Q7)
**
** Return: Shortword	----- ratio of f1, f2 with multiple (Q15)
**
********************************************************************/
Shortword multiCheck(Shortword f1, Shortword f2)
{
	Shortword	temp, f2_multiple;                                      /* Q7 */


	if (f1 <= f2){            /* Swap f1 and f2 so that f1 is larger than f2. */
		temp = f1;
		f1 = f2;
		f2 = temp;
	}

	f2_multiple = f2;
	while (f2_multiple <= f1)
		f2_multiple = add(f2_multiple, f2);

	/* Now f2_multiple is larger than f1.  Check whether f2_multiple or       */
	/* (f2_multiple - f2) is closer to f1 and use the better one.             */

	temp = shr(f2, 1);
	temp = sub(f2_multiple, temp);                                      /* Q7 */
	if (temp > f1)
		f2_multiple = sub(f2_multiple, f2);

	return(ratio(f1, f2_multiple));
}

/******************************************************************
**
** Function:	minCostIndex
**
** Description: find first two largest local maxs
**
** Input:
**		Shortword *costBuf	------	the cost buffer Q5
**		Shortword *index1	------	the index of the largest peak
**		Shortword *index2	------	the index of the second largest peak
**
** Return: None
**
********************************************************************/
void minCostIndex(Shortword *costBuf, Shortword *index1, Shortword *index2)
{
	register Shortword i;
	Shortword co = SW_MAX;

	*index1 = 0;			/* largest weight */
	co = costBuf[0];
	for (i = 1; i < NODE; i++){
		if (costBuf[i] < co){
			co = costBuf[i];
			*index1 = i;
		}
	}

	if (*index1 == 0)
		*index2 = 1;		/* second largest weight */
	else
		*index2 = 0;
	co = costBuf[*index2];
	for (i = (Shortword) (*index2 + 1); i < NODE; i++){
		if (*index1 == i)
			continue;
		if (costBuf[i] < co){
			co = costBuf[i];
			*index2 = i;
		}
	}
}

/******************************************************************
**
** Function:	trackPitch
**
** Description: Find coresponding pitch index for pitch tracking
**
** Input:
**		Shortword pitch			------	the pitch candidate (Q7)
**		pitTrackParam *pitTrack ------	The pitch tracker structure
**
** Return: Shortword ----- index of the time domain candidates
**
********************************************************************/
Shortword trackPitch(Shortword pitch, pitTrackParam *pitTrack)
{
	register Shortword	i;
	Shortword	index;
	Shortword	best, temp;                                             /* Q7 */
	Shortword	co = MONE_Q15;                             /* Minus infinity. */


	/* The following loop finds the index for pitTrack->pit[] so that it      */
	/* maximizes pitTrack->weight[] among those indices with                  */
	/* ratio(pitTrack->pit[*], pitch) < 0.2 as a qualification.  If index     */
	/* remains -1, it means none of pitTrack->pit[] qualifies.                */

	index = -1;
	for (i = 0; i < NODE; i++){
		temp = shl(pitTrack->pit[i], 7);                                /* Q7 */
		if (ratio(temp, pitch) < X02_Q15){
			if (pitTrack->weight[i] > co){
				co = pitTrack->weight[i];
				index = i;
			}
		}
	}

	if (index < 0){    /* All of pitTrack->pit[] makes ratio(*, pitch) > 0.2; */
                       /* none of pitTrack->pit[] is close enough to "pitch". */

		/* Then we find the "index" which is the closest to "pitch".          */

		index = 0;
		temp = shl(pitTrack->pit[index], 7);
		temp = sub(temp, pitch);
		best = abs_s(temp);                                             /* Q7 */
		for (i = 1; i < NODE; i++){
			temp = shl(pitTrack->pit[i], 7);
			temp = sub(temp, pitch);
			temp = abs_s(temp);                                         /* Q7 */
			if (temp < best){
				index = i;
				best = temp;
			}
		}
	}

	return(index);
}


/******************************************************************
**
** Function:	pitLookahead	
**
** Description: Find pitch at onset segment
**
** Input:
**		pitTrackParam *pitTrack ------ The pitch tracker structure
**		Shortword num			------ The number of available structures
**
** Return: Shortword ----- the smoothed pitch (Q7)
**
********************************************************************/
Shortword pitLookahead(pitTrackParam *pitTrack, Shortword num)
{
	register Shortword	i, j;
	Shortword	index;
	Longword	L_sum, L_cost;

	/* compute the cost function of the last strucutre */
	for(i = 0; i < NODE; i++){
		L_sum = L_sub(LW_MAX, L_deposit_h(pitTrack[num].weight[i]));
		L_cost = L_mult(extract_h(L_sum), PIT_WEIGHT_Q5);
		pitTrack[num].cost[i] = extract_h(L_cost);					/* Q5 */
	}

	/* -------- forward tracker -------- */
	for(i = sub(num, 1); i >= 0; i--){
		for(j = 0; j < NODE; j++){
			index = trackPitch(shl(pitTrack[i].pit[j], 7), &pitTrack[i + 1]);

			/* pitTrack[i].cost[j] = PIT_WEIGHT*(1.0-pitTrack[i].weight[j]); */
			L_sum = L_sub(LW_MAX, L_deposit_h(pitTrack[i].weight[j]));
			L_cost = L_mult(extract_h(L_sum), PIT_WEIGHT_Q5);		/* Q5 */

			/*	pitTrack[i].cost[j] +=
					abs(pitTrack[i].pit[j] - pitTrack[i + 1].pit[index]); */
			L_sum = L_sub(L_deposit_h(pitTrack[i].pit[j]), 
						  L_deposit_h(pitTrack[i+1].pit[index]));
			L_cost = L_add(L_cost, L_shl(L_abs(L_sum), 5));			/* Q5 */

			/* pitTrack[i].cost[j] += pitTrack[i+1].cost[index]; */
			L_cost = L_add(L_cost, L_deposit_h(pitTrack[i+1].cost[index]));
			pitTrack[i].cost[j] = extract_h(L_cost);				/* Q5 */
		}
	}

	/* find the best index to minimize the cost */
	L_cost = L_deposit_h(pitTrack[0].cost[0]);
	index = 0;
	for( i = 1; i < NODE; i++){
		if( L_deposit_h(pitTrack[0].cost[i]) < L_cost ){
			L_cost = L_deposit_h(pitTrack[0].cost[i]);
			index = i;
		}
	}

	return(shl(pitTrack[0].pit[index], 7));
}

/* ========================================================================== */
/* This function replaces the previous macro declaration for RATIO(x, y):     */
/*                                                                            */
/*    RATIO(x, y) = (fabs((float)(x)-(float)(y))/(float)((x)>(y)?(x):(y)))    */
/*                                                                            */
/* The Shortword Q7 arguments x and y are implied to be positive.  The        */
/* returned value is Q15.                                                     */
/* ========================================================================== */

Shortword ratio(Shortword x, Shortword y)
{
	Shortword	diff, larger;


	diff = sub(x, y);
	diff = abs_s(diff);
	larger = (Shortword) ((x > y) ? x : y);
	return(divide_s(diff, larger));
}


/* ========================================================================== */
/* This function should be functionally almost the same as ratio() except     */
/* that the second argument is Longword.  It is used in sc_ana() of           */
/* "melp_ana.c" when we call ratio() in                                       */
/*                                                                            */
/*    ratio(par[1].pitch, (prev_pitch*3)) < X008_Q15                          */
/*                                                                            */
/* where a Q7 prev_pitch multiplied by 3 could overflow a Shortword.  Both    */
/* inputs are still Q7 and the returned value is still Q15.                   */
/* ========================================================================== */

Shortword L_ratio(Shortword x, Longword y)
{
	Longword	L_x, diff, larger;


	L_x = L_deposit_l(x);
	diff = L_sub(y, L_x);
	if (diff < 0)
		diff = L_negate(diff);
	larger = (L_x > y) ? L_x : y;
	return(L_divider2(diff, larger, 0, 0));
}


/* ========================================================================== */
/* This function updates silenceEn and voicedEn used in sc_ana() of           */
/* "melp_ana.c".   prev_en, curr_en and the returned result are of the same   */
/* Q value (Q11), while ifact is Q15.                                         */
/*                                                                            */
/* Note that because of the dynamic range problem, approximations are used in */
/* the fixed point implementation.  The implementation assumes "ifact" is     */
/* always equal to 0.9.                                                       */
/* ========================================================================== */
Shortword updateEn(Shortword prev_en, Shortword ifact, Shortword curr_en)
{
	Shortword	temp1, temp2;
	Shortword	result;                                                /* Q11 */


	/* Now we want to compute                                                 */
	/* log10(ifact*pow(10.0, prev_en) + (1.0 - ifact)*pow(10.0, curr_en)).    */
	/* We rearrange the expression as                                         */
	/*        prev_en + log10(ifact + (1 - ifact) *                           */
	/*                                pow(10.0, curr_en - prev_en))           */
	/* Depending on the range of (curr_en - prev_en), we might choose to      */
	/* ignore the pow() term, or ignore the "ifact" term inside log10() (so   */
	/* the expression becomes curr_en + log10(1 - ifact)).  This manipulation */
	/* is necessary because pow(10.0, prev_en) and pow(10.0, curr_en) can     */
	/* easily overflow the dynamic range for Shortword.                       */

	temp1 = shr(curr_en, 1);                                           /* Q10 */
	temp2 = shr(prev_en, 1);
	temp1 = sub(temp1, temp2);                                         /* Q10 */
	if (temp1 < negate(ONE_Q10)){                                 /* Case (a) */
		/* Compute log10(ifact) + prev_en. */
		temp1 = log10_fxp(ifact, 15);                                  /* Q12 */
		temp1 = shr(temp1, 1);                                         /* Q11 */
		result = add(temp1, prev_en);
	} else if (temp1 > THREE_Q10){                                /* Case (b) */
		temp1 = sub(ONE_Q15, ifact);                                   /* Q15 */
		temp1 = log10_fxp(temp1, 15);                                  /* Q12 */
		temp1 = shr(temp1, 1);                                         /* Q11 */
		result = add(temp1, curr_en);                                  /* Q11 */
	} else {                                                      /* Case (c) */
		/* temp1 = (curr_en - prev_en) is between -1 and 3. */
		temp1 = shl(temp1, 2);                                         /* Q12 */
		temp1 = pow10_fxp(temp1, 5);                                    /* Q5 */
		temp1 = interp_scalar(temp1, ONE_Q5, ifact);                    /* Q5 */
		temp1 = log10_fxp(temp1, 5);                                   /* Q12 */
		temp1 = shr(temp1, 1);                                         /* Q11 */
		result = add(prev_en, temp1);
	}
	return(result);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -