📄 iiii.c
字号:
/*******************************************************************
基音检测
*******************************************************************/
#include "math.h"
#include "VoiceProcess.h"
#include "Dsplib.h"
//////////////////////////////////////////////////////////////////
#pragma DATA_SECTION(fft,".FFT");
/************************* *************************************/
extern Bool int_flag;
extern float VoiceIn[WindowsLong]; //原始数据
extern float VoicePreEmphasisOut[WindowsLong]; //预加重后数据
extern float VoiceHammingOut[WindowsLong]; //加窗后数据后
extern float ALF[LpcNumber]; //LPC系数
extern Uint16 ZhenYi_F; //帧移标志
extern float CEP[CepNumber]; //倒谱系数
extern float PRECEPD[CepNumber]; //预测倒谱系数
extern float CORREL[CepNumber];
extern float Average;
extern int PitchDataIn[800];
extern int PitchDataVer[800];
extern Uint16 PitchPoint;
extern Uint16 SegNew;
extern int MikeOut[0x2010];
extern Uint16 RecPoint;
/******************** PITCH **********************************/
DATA fft[WindowsLong]; //傅立叶变换
DATA fftNew[WindowsLong];
DATA fftError[WindowsLong];
Bool PitchFlag; //点灯标志
int Max_Mov[3][2]; // 区域最大值
Uint16 ApexMov[15]; //峰值
Uint16 SpeechVal;
Uint16 ApexVal;
Uint16 jishuqi; //记录范围内(17--21)峰值的个数
Uint16 Min;
int VoiceCrossNew;
int VoiceCross[64];
long unsigned int Averagefft;
unsigned int Maxfft;
unsigned int AverageNumber;
long unsigned int fftH,fftL;
int fftNumber;
long unsigned int fftH128,fftL18;
int fftHNumber;
int Max,MaxPitch;
int MaxOne1,MaxOne2,MaxOne3;
int MaxTwo1,MaxTwo2,MaxTwo3;
int MaxPitchOne1,MaxPitchOne2,MaxPitchOne3;
int MaxPitchTwo1,MaxPitchTwo2,MaxPitchTwo3;
int ManPitchLick1,ManPitchLickOne1,ManPitchLickOne2,ManPitchLickOne3;
int ManPitchLickTwo1,ManPitchLickTwo2,ManPitchLickTwo3,Score;
#define FFTMIN 18
#define FFTMAX 200
#define FFTLIMIT 30
#define FftLength (FFTMAX-FFTMIN)
#define AdptiveLength 32
unsigned int TimeLong=0;
float FftLong[FftLength];
float FftLong1[FftLength];
float fftSource[FftLength];
int PitchFlagReady,PitchScore;
#define FFTL 18
#define FFTH 50
int PitchPre[(FFTH-FFTL)];
#define FFTA 50
int PitchNew1,PitchNew2;
int amax,bmax,sum,sum1;
///////////////////////////////////////////////////////////////
extern void SoundOut(void);
void ComputerPitch(void);
void bianliang_chushihua(void); //数组变量初始化
// static void LpcAntiFilter(void); // 逆滤波 static
static void PitchCep(void); // 时域--频域
static void Speech(void); //基音周期检测
static void Apex(void); //峰值检出
static void Near(void); //最接近算法
static void ApexNew(void); //峰值检出
static void SpeechNew(void); //基音周期检测
void SearchPitchMax(void);
void PitchJudge(void);
void FftSubAverge(void);
void FftSubLong(void);
void FftLongInit(void);
static void ComputerVar(void);
void PitchSearchAll(void);
/*********************************************************************/
// 基音检测主程序
void ComputerPitch(void)
{
// LpcAntiFilter(); // 逆滤波
PitchCep(); // 时域--频域
ComputerVar();
ApexNew(); //峰值检出
Near(); //靠近法计算基音
SpeechNew(); //基音周期判别并设置亮灯标志
// Speech(); //基音周期判别并设置亮灯标志
}
void PitchSearchAll(void)
{
int i,j,a,b,c,n;
for(i=0;i<18;i++)
{
fft[i]=0; //清0
}
amax=0;
for(i=18;i<200;i++)
{
if(fft[i]>amax)
{ amax=fft[i];
bmax=i;
}
} //求出最大值
sum=0;
for(i=18;i<200;i++)
{
sum+=fft[i];
} //求总和
for(i=0;i<(FFTH-FFTL);i++)
{
PitchPre[i]=0; //清0
}
for(i=FFTL;i<FFTH;i++)
{
n=1;
c=0;
for(n=1;n*i<192;n++)
{
a=0;
for(j=n*i-5;j<n*i+5;j++)
{
if(fft[j]>a)
{ a=fft[j];
b=j;
}
} //局部极值
if(n<=2)
{
if((abs(b-n*i)<=2)&&(a>=0.1*amax)&&(a>=FFTA))
{
c++;
}
}
if((n>2)&&(n<=5)&&(a>=0.1*amax)&&(a>=FFTA))
{
if(abs(b-n*i)<=3)
{
c++;
}
}
if((n>5)&&(a>=0.1*amax)&&(a>=FFTA))
{
if(abs(b-n*i)<=5)
{
c++;
}
}
}
PitchPre[i-FFTL]=c;
}//for
a=0;
b=-1;
for(i=0;i<(FFTH-FFTL);i++)
{
if(PitchPre[i]>a)
{ a=PitchPre[i];
b=i;
}
if(a<=2)
b=0;
}
PitchNew1=b+FFTL;
sum1=0;
for(n=1;n*PitchNew1+5<200;n++)
{
for(i=PitchNew1-3;i<=PitchNew1+3;i++)
{
sum1+=fft[i];
}
}
if((PitchNew1>18)&&(PitchNew1<=30))
{if(((bmax%PitchNew1)<=3)||((bmax%PitchNew1)>=(PitchNew1-3)))
PitchNew2=1;
else PitchNew2=0;
}
else PitchNew2=2;
}
void PitchPretreatment(void)
{
int i,Max1,MaxPoint1;
int Max2,MaxPoint2;
int Max3,MaxPoint3;
int pitch1,pitch2,pitch3;
PitchScore=0;
Max1=0;
for(i=15;i<200;i++)
{
if(fft[i]>Max1)
{ Max1=fft[i];
MaxPoint1=i;
}
}
pitch1=MaxPoint1; //求出第一峰值
if(pitch1<30)
{
PitchScore++;
Max2=0;
for(i=MaxPoint1+15;i<200;i++)
{
if(fft[i]>Max2)
{ Max2=fft[i];
MaxPoint2=i;
}
} //求出第二峰值
pitch2=MaxPoint2-MaxPoint1;
if((pitch1<(pitch2+2))&&(pitch1>(pitch2-2)))
{
PitchScore++;
Max3=0;
for(i=MaxPoint2+15;i<200;i++)
{
if(fft[i]>Max3)
{ Max3=fft[i];
MaxPoint3=i;
}
}
pitch3=MaxPoint3-MaxPoint2;
if((pitch2<(pitch3+2))&&(pitch2>(pitch3-2)))
{
PitchScore++;
goto PitchOut;
}
// if(pitch2
}
if((pitch2<30)&&(pitch2<=60))
{
Max3=0;
for(i=MaxPoint2+15;i<200;i++)
{
if(fft[i]>Max3)
{ Max3=fft[i];
MaxPoint3=i;
}
}
if((MaxPoint3-MaxPoint2)<=30)
{
pitch1=MaxPoint2-MaxPoint1;
}
pitch1=MaxPoint2-MaxPoint1;
}
PitchOut:i++;
}
}
/**************************************************************/
/* 峰值计算
将峰值依次存入数组 ApexMov[]中
*************************************************************/
static void ApexNew(void)
{
Uint16 i,k;
Uint16 Val1,Val2;
ApexVal=0;
k=0;
for(i=0;i<15;i++)
{
fft[i]=0;
}
for(i=180;i<256;i++)
{
fft[i]=0;
}
for(i=0;i<15;i++)
{
ApexMov[i]=0;
}
for(i=15;i<170;i++)
{
if((fft[i]>fft[i-1])&&(fft[i]>fft[i-2])&&(fft[i]>fft[i-3])&&(fft[i]>fft[i-4])&&
(fft[i]>fft[i-5])&&(fft[i]>fft[i-6])&&(fft[i]>fft[i-7])&&(fft[i]>fft[i-8])&&
(fft[i]>fft[i+1])&&(fft[i]>fft[i+2])&&(fft[i]>fft[i+3])&&(fft[i]>fft[i+4])&&
(fft[i]>fft[i+5])&&(fft[i]>fft[i+6])&&(fft[i]>fft[i+7])&&(fft[i]>fft[i+8])&&
(fft[i]>80))
{
ApexMov[k]=i;
i+=10;
k++;
if(k>14)k=14;
}
if(int_flag==1)SoundOut();
}
i=1;
jishuqi=0;
if(ApexMov[0]>21) //22为中心频率
Val2=ApexMov[0]-21;
else
Val2=21-ApexMov[0];
if(Val2<6)jishuqi++;
do{
Val1=ApexMov[i]-ApexMov[i-1];
if(Val1>21)
Val1=Val1-21;
else
Val1=21-Val1;
if((Val1<6))
{
jishuqi++;
}
i++;
}while (ApexMov[i]!=0);
}
/////////////////////////////////////////////////////////////////////////
static void ComputerVar(void)
{
int i;
Averagefft=0;
for(i=20;i<200;i++)
{
Averagefft+=fft[i];
}
Averagefft/=(200-20);
Maxfft=0;
for(i=15;i<200;i++)
{
if(fft[i]>Maxfft)
Maxfft=fft[i];
}
AverageNumber=Maxfft/Averagefft;
fftL=0;
for(i=15;i<38;i++)
{
fftL+=fft[i];
}
fftH=0;
for(i=38;i<200;i++)
{
fftH+=fft[i];
}
fftNumber=fftH/fftL;
fftH128=0;
for(i=128;i<200;i++)
{
fftH128+=fft[i];
}
fftL18=0;
for(i=18;i<128;i++)
{
fftL18+=fft[i];
}
fftHNumber=fftH128/fftL18; //高低自比
}
/*********************************************************************/
/* 基音周期检测并设置亮灯标志 */
// 将第一个位置的数值(及相邻的4个)加上
// 它的2倍位置的数值(及相邻的4个)
//
/**************************************************************/
static void SpeechNew(void)
{
Uint16 i,j,k,h;
Uint16 Total[TotalNumber];
Uint16 MaxAdd;
Uint32 sum;
Uint16 sumX;
SpeechVal=0;
//清0
for(i=0;i<TotalNumber;i++)
{
Total[i]=0;
}
/* //18--128 平均值
sum=0;
for(i=ComputerStart;i<(ComputerStart+BotNumber);i++)
{
sum+=fft[i];
if(int_flag==1)SoundOut();
}
sumX=sum/BotNumber;
*/
//从18开始,
for(j=ComputerStart;j<ComputerEnd;j++)
{
h=j-ComputerStart;
for(i=1;i<5;i++)
{
k=i*j;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -