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(m 0.2){ /* justify is the P0 is multiple of Pc */ if(cond_mul = (char)(Ambiguous_1(maxcr, peakPos, num))){ for(i=1; i 0.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((i 0.10)){ if(abs(peakPos[i]-trkp)