📄 zixiangguang.c
字号:
//*****语音基音检测程序*****//
//采用自相关法进行基音检测程序
//输入:sample[] 语音采样点
// length 最大样点数
//输出:Pitch[] 基音周期
//参数解释:FRAME--480 帧长度 ; BETWEEN---160 帧与帧间隔;Fs--12000 采样频率
//准备对100个帧进行处理,设置Pitch长度为100,100*480=48000=0xBB80,换成采样处理时间为1088ms,1分钟
//**************************************************//
//*FUNCTION:对基音检测的(整合成语音回放的一个子程序)封装,加入采集回放主程序中*//
//#include <string.h>
#define FRAME 480
#define BETWEEN 160
#define Fs 12000
//#define length 48000
typedef unsigned long FARPTR ;
//**Declaration all functions**//
int PitchDetect(float sample[]);
float Maxfloat(float Buffer[], int length, int *Maxindx);
void AutoCorrelate(float Buffer[],int length, float Max, float R[]);
float Shap(float Buffer[], int length, int V[],float X[],float Max);
int MaxIntAbs(int Buffer[],int length);
float MaxFloatAbs( float sample[],int length);
float minor(float x1,float x2);
void Filter(int x[],float y[],int length);
//************************************************************
/*
函数名:
调用:
返回值:
参数:
*/
int * PitchesDetect(FARPTR lpch,int length)
{
float y[FRAME];
int i,k=0;
int Pitch[100];
int sample[48000];
int *p;
p=Pitch;
for (i=0;i<length;i++)
{
sample[i]=far_peek(lpch++);
}
for (i=0;i<length-FRAME;i+=BETWEEN)
{
Filter(sample,y,FRAME);
Pitch[k]=PitchDetect(y);
k++;
}
return(p);
}
//*FUNCTION:基音检测*//
int PitchDetect(float sample[])
{
float Maxhead,Maxtail;
int N;
float Max,R[FRAME];
//setmem(R,sizeof(float)*FRAME,'0');
//确定门限
Maxhead = MaxFloatAbs(sample,100);
Maxtail = MaxFloatAbs(&sample[FRAME-100],100);
Max = (0.68*minor(Maxhead,Maxtail));
//作自相关
AutoCorrelate(sample,FRAME,Max,R);
Max = Maxfloat(&R[20],FRAME-20,&N);
N += 20;
if (Max < (0.55 * R[0])) N=0;
return N;
}
float Maxfloat(float Buffer[], int length, int *Maxindx)
{
int i;
float Max;
Max = Buffer[0];
for( i=1; i<length; i++ )
{
if (Max< Buffer[i])
{
Max = Buffer[i];
*Maxindx = i;
}
}
return Max;
}
//*FUNCTION:自相关*//
void AutoCorrelate( float Buffer[],int length, float Max, float R[])
{
int i, j, V[FRAME];
float X[FRAME];
R[0]=Shap(Buffer,length,V,X,Max);
for (j=20; j<160; j++)
{
for ( i=j; i<length; i++ )
{
if ((i+j)<length )
{
if ( V[j]<0 )
R[j] = R[j]-X[i+j];
else if ( V[j]>0 )
R[j] = R[j]+X[i+j];
}
}
}
}
//*FUNCTION:中心削波*//
float Shap( float Buffer[], int length, int V[],float X[],float Max)
{
int i, RO = 0;
for(i = 0;i < length;i++)
{
if (abs(Buffer[i]) < Max)
{
V[i] = 0;
X[i] = 0;
}
else if(Buffer[i] > 0)
{
V[i] = 1;
X[i] = Buffer[i]-Max;
RO += X[i];
}
else
{
V[i]=-1;
X[i]=Buffer[i]+Max;
RO-=X[i];
}//if (abs(Buffer[i]) < Max)
}//for(i = 0;i < length,i++)
return RO;
}
int MaxIntAbs(int Buffer[],int length)
{
int i,Max;
Max=abs(Buffer[0]);
for(i=1; i<length; i++)
{
if(Max<abs(Buffer[i])) Max = abs(Buffer[i]);
}
return Max;
}
float MaxFloatAbs(float sample[],int length)
{
int i;
float max;
max=sample[0];
for(i=0;i<length;i++)
{
if(max < sample[i]) max = sample[i];
}
return(max);
}
float minor(float x1,float x2)
{
float x;
x=x1;
if(x1>x2) x=x2;
return(x);
}
//*20阶,900Hz的低通滤波器,用来分帧以及滤去高频谐波分量,帧间隔13ms(160个样点)*//
//*语音信号的基音频率大约在80Hz--500Hz左右,一般在100HZ--200Hz之间*//
void Filter(int x[],float y[],int length)
{
int i,j;
float H[20]={
0.0035270585,-0.0075853243,-0.022130724,-0.037701912,-0.040792551,
-0.017618544, 0.037134223, 0.1139423, 0.18955371, 0.23657782,
0.23657782, 0.18955371, 0.1139423, 0.037134223,-0.01768544,
-0.040792551, -0.037701912, -0.022130724,-0.0075853243,0.0035270585
};//*滤波器参数,用matlab的fir1函数求出,默认采用汉明窗窗函数法设计的滤波器,返回参数为其冲击响应*//
//setmem(y,sizeof(float)*length,'0');
for(i=0;i<length-11;i++)//*卷积滤波*//
{
for(j=0;j<20;j++)
y[i]+=x[i-j+10]*H[j];//**实现反折,平移,相加功能。即:离散卷积和的功能**//
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -