www.pudn.com > AVS_M_ver10.rar > open_pitch.c


/* 
*********************************************************************** 
* COPYRIGHT AND WARRANTY INFORMATION 
* 
* Copyright 2007  Audio Video Coding Standard, Part ¢ú 
* 
* This software module was developed by AVS Audio sub-group 
* 
* DISCLAIMER OF WARRANTY 
* 
* These software programs are available to the users without any 
* license fee or royalty on an "as is" basis. The AVS disclaims 
* any and all warranties, whether express, implied, or statutory, 
* including any implied warranties of merchantability or of fitness 
* for a particular purpose. In no event shall the contributors or  
* the AVS be liable for any incidental, punitive, or consequential 
* damages of any kind whatsoever arising from the use of this program. 
* 
* This disclaimer of warranty extends to the user of this program 
* and user's customers, employees, agents, transferees, successors, 
* and assigns. 
* 
* The AVS does not represent or warrant that the program furnished 
* hereunder are free of infringement of any third-party patents. 
* Commercial implementations of AVS, including shareware, may be 
* subject to royalty fees to patent holders. Information regarding 
* the AVS patent policy is available from the AVS Web site at 
* http://www.avs.org.cn 
* 
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY. 
************************************************************************ 
*/ 
 
#include  
#include  
#include  
#include "../include/amr_plus.h" 
#include "../../c-code/include/pre_open_pitch.h" 
#include "../../c-code/include/open_pitch.h" 
 
static int global_pitch = 0; 
static int prevGp = 0; 
static int prev_pitch = 0; 
 
static int pitch_cand = 0; 
static float corr_cand = 0.0; 
 
static char cond_mul = 0;   /* the condition to justify if P0 is multiple of Pc */ 
 
int pos[PITCH_NUM]; 
 
/************************************************************************/ 
/* function sort the peak and peakPos according to peak descend 
   method:  heap sort 
   argument list: 
   float* peak (i): input peak vector 
   float* peakPos (i): input peakPos vector 
   int num (i): the length of the peak vector 
    
   return value: N/A                                                                       */ 
/************************************************************************/ 
 
void sort(float* peak, int p_num, int* peakPos) 
{ 
	int end;            /* the end index to heap sort */ 
	int start;          /* the start index in a heap sort */          
	char odd;           /* if the end index is odd */ 
	float chg_buf;      /* the buf in the sort change */ 
	int chg_buf_pos;    /* the buf in the sort for peakPos */ 
 
	/* initiate the end index to be p_num-1 */ 
	end = p_num - 1; 
	/* justify if the end is odd or even number */ 
    odd = (char)(end & 1); 
	while(end>0) 
	{ 
		start = (end - 1)/2; 
		/* the odd end means the start*2+1 index in peak vector dose not exist */ 
		if(odd){ 
			if(peak[start]>peak[start*2+1]){ 
				/* the queue is wrong */ 
				/* change the two peak value */ 
				chg_buf = peak[start]; 
				peak[start] = peak[start*2+1]; 
				peak[start*2+1] = chg_buf; 
				/* change the two peakPos value */ 
				chg_buf_pos = peakPos[start]; 
				peakPos[start] = peakPos[start*2+1]; 
				peakPos[start*2+1] = chg_buf_pos; 
			} 
			/* update the start value */ 
			start--; 
		} 
		while(start >= 0){ 
			/* find the max value in the peak[start*2+1] and peak[start*2+2] */ 
			if(peak[start*2+2]= 2){ 
		/* case of multiple significant pitches */ 
		pitch = peak_pos[0]; 
		for(i=1; i 0.005||corr < -0.005){ 
			mid_corr = c0_0 * cT_T ; 
			/* to avoid the denominator to be zero */ 
			if(mid_corr < 0.0005) 
				mid_corr = 0.0005 ; 
			if(corr>0) 
				corr = (corr*corr) / mid_corr; 
			else 
				corr = -(corr*corr) / mid_corr; 
		}		 
		/* update for next iteration */ 
		if(i<(upper)){ 
			/* in the last iteration there's no need to update */ 
			cT_T += sig_in[-i-1]*sig_in[-i-1]-sig_in[-i+length-1]*sig_in[-i+length-1]; 
		}		 
		/* justify if the correlation is peak value */ 
		if(peak_able){ 
            /* condition1: compare the two previous delay, the correlation corresponding to the smaller delay is smaller */ 
			if(corr_pre>(float)corr){ 
				/* set peak_able tag */ 
				peak_able = 0; 
				/* the previous correlation is peak value */ 
				/* insert the previous delay and correlation to peak vector */ 
				if(*pch_num < PITCH_NUM){ /* maximum of peak value number is PITCH_NUM */ 
					(*pch_num)++; 
					n = ((*pch_num) - 2);      /* end of search */					 
				} 
				else{ 
					n = 5;      /* end of search */ 
				} 
				m = 0;                   /* begin of search */ 
				j = ((m+n)>>1);             
				while(m<=n){ 
					/* modify begin and end index */ 
					if(corr_pre>maxcr[j]){ 
						n = (j - 1); 
					} 
					else{ 
						m = (j + 1); 
					} 
					j = ((m+n)>>1); 
				} 
				/* set the end of the peak vector */ 
				j = (*pch_num - 1); 
				while(j>m){ 
					/* move the peak vector */ 
					maxcr[j] = maxcr[j-1]; 
					peakPos[j] = peakPos[j-1]; 
					j--; 
				} 
				/* insert current correlation and delay */ 
				if(m0.2){ 
		/* justify is the P0 is multiple of Pc */ 
		if(cond_mul = (char)(Ambiguous_1(maxcr, peakPos, num))){ 
			for(i=1; i0.627264){ 
		/* the first condition to confirm the global pitch */ 
		condition1 = (char)(!cond_mul && fabs(pitch-global_pitch)<8.0); 
		/* the second condition to confirm the global pitch */ 
		condition2 = (char)(maxcr[0]>0.6274 && maxcr[0]/maxcr[1]>1.7); 
		/* the third condition to confirm the global pitch */ 
		condition3 = (char)(cond_mul||Ambiguous_2(peakPos,num,pitch)); 
		/* the fourth condition to confirm the global pitch */ 
		condition4 = (char)(maxcr[0]>0.36 && fabs(global_pitch-2*pitch)<5.0);	 
		/* if the condition is satisfied, set the credible global pitch */ 
		if(condition1 || condition2 || condition3 || condition4){ 
			/* set the global_pitch */ 
			global_pitch = pitch; 
			/* set the hold state to be zero */ 
			gpHoldState = 0; 
			if(global_pitch != 0){ 
				/* the prevGp set to be the last nonzero global_pitch */ 
				prevGp = global_pitch; 
				hold_Gp = 0; 
			} 
		}		 
	} 
	else{ 
		/* if the correlation is too small */ 
		/* the pitch is very weak */ 
		if(maxcr[0]<0.15){ 
			if(global_pitch != 0){ 
				/* the prevGp set to be the last nonzero global_pitch */ 
				prevGp = global_pitch; 
				hold_Gp = 0; 
			} 
			/* set the global pitch to be zero */ 
			global_pitch = 0; 
			/* set the hold state to be zero */ 
			gpHoldState = 0; 
		} 
		/* the hold state limit is 2 */ 
		if(gpHoldState == 2){ 
			if(global_pitch != 0){ 
				/* the prevGp set to be the last nonzero global_pitch */ 
				prevGp = global_pitch; 
				hold_Gp = 0; 
			} 
			/* if the hold state get to the limit, set the global pitch zero */ 
			global_pitch = 0; 
			gpHoldState = 0; 
		} 
		else{ 
			/* if the hold state does not exceed the limit */ 
			gpHoldState++; 
		} 
		/* consider the weak pitch hold state */ 
		if(maxcr[0]<0.15){ 
			if(fbState == 1){ 
				if(global_pitch != 0){ 
					/* the prevGp set to be the last nonzero global_pitch */ 
					prevGp = global_pitch; 
					hold_Gp = 0; 
				} 
				global_pitch = 0; 
			} 
			else{ 
                /* if the weak pitch hold state does not exceed the limit */ 
				fbState++; 
			} 
		} 
		else{ 
			fbState=0; 
		} 
	} 
	/* set the last frame pitch candidate */ 
	gpcd = pitch; 
	/* increase the Gp hold state */ 
	hold_Gp ++; 
	/* the Gp hold state's limit is 4 */ 
	if(hold_Gp >= 4){ 
		prevGp = 0; 
	}	 
    return; 
} 
 
/************************************************************************/ 
/* function : the main function in the pitch determination 
   argument list: 
   float* sig_in (i): the input signal 
   int lower (i): the search down limit 
   int upper (i): the search up limit 
   int length (i): the length of the signal 
   return value: N/A    
	                                                                    */ 
/************************************************************************/ 
 
int find_pitch(float* sig_in, int lower, int upper, int length) 
{ 
    int	i;                      /* the index to look over the vector */ 
	int	peakPos[PITCH_NUM];      /* the peakPos list vector */ 
	float maxcr[PITCH_NUM];     /* the correlation list vector */ 
	 
	float corr_c;               /* the correlation candidate */ 
	int	p_num;                  /* the length of peak vector */ 
	int	pitch_c;                /* the pitch candidate */ 
	int	trkp;                   /* the reference to set the pitch */ 
	 
	int max_i;                  /* the index of the pos which is nearest to trkp */ 
	/* initiate the trkp to zero */ 
	trkp = 0;	 
	/* compute pitch candidates  */ 
    calc_pitch_cand(sig_in, maxcr, peakPos, lower, upper, length, &p_num); 
	/* compute the global pitch */ 
	CheckGlobalPitch(peakPos, maxcr, p_num); 
	/* if the correlation is too small, pitch which corresponding to the max correlation value */ 
	if(maxcr[0]<0.15){ 
		prev_pitch = 0 ; 
		return peakPos[0]; 
	} 
	/* load the pitch candidate and correlation value candidate */ 
	pitch_c = pitch_cand; 
	corr_c = corr_cand; 
	/* consider the global pitch */ 
	if(global_pitch>12 && abs(global_pitch-pitch_c)<5){ 
		/* if the candidate is near to the global pitch */ 
		/* set the candidate to be the pitch */ 
		prev_pitch = pitch_c ; 
		return pitch_c; 
	}	 
	/* if the pitch has not confirmed, use the trkp to weight*/ 
	if(global_pitch){ 
		/* the most preferential trkp is global_pitch */ 
		trkp = global_pitch; 
	} 
	else{ 
		if(prev_pitch){ 
			/* the second preferential trkp is pre_pitch */ 
			trkp = prev_pitch; 
		} 
		else{ 
			if(prevGp){ 
				/* the third preferential trkp is prevGp */ 
				trkp =prevGp; 
			} 
		} 
	}	 
	i=0; 
	max_i = 0 ; 
	if(corr_c<0.6 && trkp){		 
		while((i0.10)){ 
			if(abs(peakPos[i]-trkp)