📄 linshi.c
字号:
/******** 可改动定义 ***************************************/
//#define PitchL 16 // 基音下限 4---62.5Hz
//#define PitchH 24 // 基音上限 12---187Hz,13---203Hz
//#define PitchAm 800 // 基音的门槛 800----2000
//#define BeiShu1 3 // 平均值的倍数1
/***************************************************************/
/*******************************************************************
// Uint16 Max1Sub1,Max1,Max1Add1;
// Uint16 Max2Sub1,Max2,Max2Add1;
// Uint16 Max3Sub1,Max3,Max3Add1;
if((SpeechVal>SpeechValMin)&&(SpeechVal<SpeechValMax))
{
Max1Sub1=fft[SpeechVal-1]; Max1=fft[SpeechVal]; Max1Add1=fft[SpeechVal+1];
Max2Sub1=fft[2*SpeechVal-1]; Max2=fft[2*SpeechVal]; Max2Add1=fft[2*SpeechVal+1];
// Max3Sub1=fft[3*SpeechVal-1]; Max3=fft[3*SpeechVal]; Max3Add1=fft[3*SpeechVal+1];
T=0;
if(((Max1Sub1<MaxAm1)&&(Max1<MaxAm1)&&(Max1Add1<MaxAm1))||
((Max2Sub1<MaxAm2)&&(Max2<MaxAm2)&&(Max2Add1<MaxAm2)))
{
T=1;
}
}
else if((Min>SpeechValMin)&&(Min<SpeechValMax))
{
Max1Sub1=fft[Min-1]; Max1=fft[Min]; Max1Add1=fft[Min+1];
Max2Sub1=fft[2*Min-2]; Max2=fft[2*Min]; Max2Add1=fft[2*Min+2];
// Max3Sub1=fft[3*Min-6]; Max3=fft[3*Min]; Max3Add1=fft[3*Min+6];
T1=0;
//防止Max1、 Max2、Max3绝对值太小
if(((Max1Sub1<MaxAm1)&&(Max1<MaxAm1)&&(Max1Add1<MaxAm1))||
((Max2Sub1<MaxAm2)&&(Max2<MaxAm2)&&(Max2Add1<MaxAm2)))
{
T1=1;
}
}
zj=Max1+Max2;
//单个最大值
zj=0;
for(j=ComputerStart;j<BotNumber;j++) //ComputerEnd;j++)
{
if(zj<fft[j])
{
zj=fft[j];
}
}
*/
/* if(zj<MaxAm3)//当整个频带内峰值都小时
goto abc1;
/////////////////////////////////////////////////////////////////////////
// 两个峰之间的所有值不能高过这两个峰
zj=0;
if((SpeechVal>SpeechValMin)&&(SpeechVal<SpeechValMax))
{
for(i=SpeechVal+5;i<(2*SpeechVal-4);i++)
{
if(fft[i]>zj)
{
zj=fft[i];
}
}
if(fft[SpeechVal]>fft[SpeechVal*2])
T= fft[SpeechVal*2] ;
else T=fft[SpeechVal];
}
}*/
///////////////////////////////////////////////////////////////////////////
/*********************** 逆滤波 static ********************************
功能: 逆滤波
入口: 1、LPC预测系数 ALF[]
2、LPC阶数
3、原始数据(实际数据) SnRe[n] VoiceIn[]
出口: 逆滤波数据残差(补0)
**********************************************************************/
/*
static void LpcAntiFilter(void)
{ float ss;
int i,n;
// 求预测值
ALF[0]=1;
for(n=11;n<WindowsLong;n++)
{
ss=0.0;
for(i=0;i<LpcNumber;i++)
ss+=ALF[i]*VoiceIn[n-i]; //VoicePreEmphasisOut[i] VoiceIn[n-i]
CanCHa[n]=ss;
if(int_flag==1)SoundOut();
}
for(i=0;i<11;i++)
{
CanCHa[i]=CanCHa[11];
}
// 残差
for(n=0;n<WindowsLong;n++)
{
CanCHa[n]=VoiceIn[n]-CanCHa[n]; //VoiceHammingOut
if(int_flag==1)SoundOut();
}
}
*/
/* else
{
Y[0]=ApexMov[m-1]/2;
X[0]=0;
if(Y[0]>35)
{
Min=ApexMov[m-1];
return;
}
i=m;
while(ApexMov[i]!=0)
{
X[1]=X[1]+abs(ApexMov[i]-(i+2)*(ApexMov[m-1]-1));
i++;
}
Y[1]=ApexMov[m-1]-1;
i=m;
while(ApexMov[i]!=0)
{
X[2]=X[2]+abs(ApexMov[i]-(i+2)*(ApexMov[m-1]+1));
i++;
}
Y[2]=ApexMov[m-1]+1;
i=1;
while(ApexMov[i]!=0)
{
X[3]=X[3]+abs(ApexMov[i]-(i+2)*(ApexMov[m-1]-2));
i++;
}
Y[3]=ApexMov[m-1]-2;
i=1;
while(ApexMov[i]!=0)
{
X[4]=X[4]+abs(ApexMov[i]-(i+2)*(ApexMov[m-1]+2));
i++;
}
Y[4]=ApexMov[m-1]+2;
}*/
//----------------------------------------------------------
// 两个峰之间的所有值不能高过这两个峰
/* zj=0;
if((SpeechVal>SpeechValMin)&&(SpeechVal<SpeechValMax))
{
for(i=SpeechVal+5;i<(2*SpeechVal-4);i++)
{
if(fft[i]>zj)
{
zj=fft[i];
}
}
T=(fft[SpeechVal]+fft[SpeechVal*2])/2;
}
else if((Min>SpeechValMin)&&(Min<SpeechValMax))
{
for(i=Min+5;i<(2*Min-4);i++)
{
if(fft[i]>zj)
{
zj=fft[i];
}
}
T=(fft[Min]+fft[Min*2])/2;
}
*/
/* for(i=10;i<100;i++)
{
if(ApexVal<fft[i])
ApexVal+=fft[i];
}
ApexVal/=100; // 计算10---100内的
*/
i=1;
jishuqi=0;
// if(ApexVal<30)F=20;
// else if((ApexVal>29)&&(ApexVal<50)) F=26;
// else if((ApexVal>49)&&(ApexVal<80)) F=33;
// else F=36;
F=20;
if(ApexMov[0]>F) //20为中心频率
Val2=ApexMov[0]-F;
else
Val2=F-ApexMov[0];
if(Val2<4)jishuqi++;
do{
Val1=ApexMov[i]-ApexMov[i-1];
if(Val1>F)
Val1=Val1-F;
else
Val1=F-Val1;
if((Val1<4))
{
jishuqi++; //两个峰之间的距离合适,计数值加一。
}
i++;
}while (ApexMov[i]!=0);
/* for(i=19;i<200;i++)
{
fftTime[i]=0.25*fft[i-1]+0.5*fft[i]+0.25*fft[i+1];
if(int_flag==1)SoundOut();
} //滤波
for(i=18;i<200;i++)
{
fft[i]=4*fftTime[i+1];
if(int_flag==1)SoundOut();
}
fft[0]=0; //回送数据
fft[1]=0;
fft[199]=0; //回送数据
fft[200]=0;
*/
/////////////////////////////////////////////////////////////////////
// 计算汽笛声
// 一般有两种,频率为:1、52左右(点数)及2倍频104左右;
// 2、77左右(点数)及2倍频154
////////////////////////////////////////////////////////////////////
void ComputerBell(void)
{
int a,i;
a=0;
for(i=BellSpeech1-15;i<=BellSpeech1+15;i++) //BellSpeech1=52
{
if(fft[i]>a) //47--67找最大值
{
a=fft[i];
BellFlagL1=i; //极值位置
}
if(int_flag==1)SoundOut();
}
if((a>=BellAm1)&&(BellFlagL1<=BellSpeech1+3) //BellAm1=3000
&&(BellFlagL1>=BellSpeech1-3))
{
BellFlagL1=1; //是汽笛声
}
else
{
BellFlagL1=0;
}
a=0;
for(i=2*BellSpeech1-15;i<=2*BellSpeech1+15;i++) //计算2倍频
{
if(fft[i]>a)
{
a=fft[i];
BellFlagH1=i;
}
}
if(int_flag==1)SoundOut();
if((a>=BellAm1)&&(BellFlagH1<=2*BellSpeech1+5)
&&(BellFlagH1>=2*BellSpeech1-5)) //是否在范围内
{
BellFlagH1=1;
}
else
{
BellFlagH1=0;
}
a=0;
for(i=BellSpeech2-15;i<=BellSpeech2+15;i++) //BellSpeech2=77
{
if(fft[i]>a)
{
a=fft[i];
BellFlagL2=i;
}
}
if(int_flag==1)SoundOut();
if((a>=BellAm2)&&(BellFlagL2<=BellSpeech2+3) //是否在范围内
&&(BellFlagL2>=BellSpeech2-3))
{
BellFlagL2=1;
}
else
{
BellFlagL2=0;
}
a=0;
for(i=2*BellSpeech2-20;i<=2*BellSpeech2+20;i++)
{
if(fft[i]>a)
{
a=fft[i];
BellFlagH2=i;
}
}
if(int_flag==1)SoundOut();
if((a>=BellAm2)&&(BellFlagH2<=2*BellSpeech2+5) //2倍频是否在范围内
&&(BellFlagH2>=2*BellSpeech2-5))
{
BellFlagH2=1;
}
else
{
BellFlagH2=0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -