java版的语音预处理以及提起MFCC参数的程序

过程包括了语音信号处理,预加重,分帧加窗,端点检测与求MFCC

定义PI的值

const float PI1=3.1415926536;
帧的结构体
`typedef struct _AudFrame
{
float fltFrame[FRM_LEN];
float fltSte; //这一帧的短时能量
DWORD dwZcr; //这一帧的过零率
bool blVad;//判断这帧是否有效
struct _AudFrame * AudFrmNext;//下一帧的地址,不知道python有没有地址
}AudFrame;`

读取音频

函数名:ReadWav(CString strFileName)

功能:读取音频

预加重

函数名:AudPreEmphasize(void)

功能:对所有采样点进行预处理

解释:

spSound:处理前的采样数据
fpPreSound:处理后的采样数据
fpPreSound[i] = (float)(spSound[i]) - float(spSound[i - 1]) * 0.9375;

分帧

函数名:AudEnframe(float *Sound,DWORD FrmLen,DWORD FrmSft,DWORD dwSoundLen)

功能:给每一帧的fltFrame[Frmlen]赋采样点的值,个数是帧长

解释:

Sound 输入的采样点数据的起始地址
Frmlen是帧的长度
FrmSft是帧移
dwSoundlen是采样点长度
FrmNum表示有多少帧
由采样点长度,帧长,帧移得到帧的个数FrmNum
FrmNum = (dwSoundLen - (FrmLen - FrmSft)) / FrmSft;

汉明窗系数

函数名:Hamming(DWORD FrmLen)

功能:求汉明窗系数,输入的是每一帧的帧长,要用到PI。这个数组是固定值,只有帧长决定

解释:

FrmLen 帧长,固定值
fltHamm[i] = (float)(0.54 - 0.46cos((2i*PI1) / (FrmLen-1)));

加窗

函数名:AudHamming(DWORD FrmLen)

功能:输入的是每一帧的帧长,需要利用到求得的汉明窗系数,具体是每个采样点的值乘以汉明窗系数,再把结果赋予fltFrame[]

解释:

需要先求得汉明窗系数fltHamm[i];

(stpWav->fltFrame)[i] //每一帧采样点数据
for(DWORD i = 0; i < FrmLen; i++)
{
(stpWav->fltFrame)[i] *= fltHamm[i];
}

每一帧短时能量

函数名:AudSte(fltSound *fpFrmSnd, DWORD FrmLen)

功能:求每一帧的短时能量,即将所有这一帧的所有样点值相加,fpFrmSnd是帧第一个样本值

解释:

fltShortEnergy:每一帧短时能量
fpFrmSnd:每个样本点的值
for(int i = 0; i < FrmLen; i++)
{
fltShortEnergy += fabs(*fpFrmSnd++);
}

一帧的过零率

函数名:AudZcr(fltSound *fpFrmSnd, DWORD FrmLen,fltSound ZcrThresh)

功能:求解一帧的过零率,fpFrmSnd帧第一个采样点地址,FrmLen帧长,ZcrThresh过零率阀值

解释:

##fpFrmSnd样本点的值
DWORD CVad::AudZcr(fltSound *fpFrmSnd, DWORD FrmLen,fltSound ZcrThresh)
{
DWORD dwZcrRate = 0;
for(int i = 0; i < FrmLen - 1; i++)
{
if((fpFrmSnd[i]*fpFrmSnd[i + 1] < 0)&&(fabs(fpFrmSnd[i] - fpFrmSnd[i - 1]) > ZcrThresh))
dwZcrRate++;
}
return dwZcrRate;
}

估计噪声阀值

函数名: AudNoiseEstimate()

功能:计算双门限阀值

解释:

fltSteThresh [2] 短时能量阀值,[0]高 [1]低
dwZcrThresh [2] 过零率阀值, [0]高 [1]低
ZcrThresh = 0;
StrThresh = 0.0;
ZcrThresh = 所有帧的过零率之和
StrThresh = 所有帧的短时能量之和
NoiseFrmLen 信号帧数
dwZcrThresh[0] = (float)(ZcrThresh) / NoiseFrmLen;
dwZcrThresh[1] = (float)(ZcrThresh) / NoiseFrmLen2.5;
fltSteThresh[0] = (float)StrThresh / NoiseFrmLen0.7;
fltSteThresh[1] = (float)(StrThresh / NoiseFrmLen)*0.5;//*0.95;

端点检测

函数名: AudVadEstimate(void)

功能:端点检测,需要用到估计阀值的函数,最后得出有效起始点和有效截止点