//ASR.h
#include #include
#define MAXDATA (256*400) //一般采样数据大小,语音文件的数据不能大于该数据
#define SFREMQ (8000) //采样数据的采样频率8khz
typedef struct WaveStruck//wav数据结构
{
//data head
struct HEAD{
char cRiffFlag[4];
int nFileLen;
char cWaveFlag[4];//WAV文件标志
char cFmtFlag[4];
int cTransition;
short nFormatTag;
short nChannels;
int nSamplesPerSec;//采样频率,mfcc为8khz
int nAvgBytesperSec;
short nBlockAlign;
short nBitNumPerSample;//样本数据位数,mfcc为12bit
} head;
//data block
struct BLOCK{
char cDataFlag[4];//数据标志符(data)
int nAudioLength;//采样数据总数
} block;
} WAVE;
typedef struct //定义实数结构
{
double real;
double image;
}complex;
//获取wav数据样本数据,sample数组的长度至少为MAXDATA,函数返回读入的数据的长度
int getWaveData(char* file,double *sample);
int copyData(double *src,double *dest,int num);//实数数据复制
//所有mfcc操作都是基于每帧操作的,len为总长度,unitsize为采样点组成的观察单位,256||512
//emp_v为欲加重因子,hanming_v为汉明窗因子,fft_v为傅里叶变化级数
//filter_v为mel滤波器个数,dct_v为dct变换因子
//函数返回mfcc识别后特征参数数组,数组长度存储在第0个元素中
double* MFCC(double *sample,int len ,int unitsize=256,double emp_v=0.97,double hanming_v=0.46,int filter_v=20,int dct=12);
//MFCC欲加重,len为数组sample的长度,factor为加重因子
bool _mfcc_preEmphasize(double *sample,int len,double factor=0.9);
//框化数据即分帧,同事在原始采样数据中插入重叠区数据
//函数返回总的帧数,和分帧后的数据sample
int _mfcc_Frame(double *sample,int unitsize,int len);
//加汉明窗,factor为汉明窗因子
bool _mfcc_HanmingWindow(double *sample,int unitsize,int frames,double hanming_factor=0.46);
//快速傅里叶变换,输入参数sample为实数,无虚数部分,len为sample的总大小,也为傅里叶变换点数
//函数返回时complex为fft变换后的频率能量复数数值,总长度为len,频率从0-SFREMQ(8khz)
complex* _mfcc_FFT(double *sample,int len);
//功率计算,返回计算后的功率实数powersample,总长度为len,频率从0-SFREMQ(8khz)
bool _mfcc_Power(complex* fftdata,double *powersample,int len);
//三角滤波,len为powersample数字长度,num为mei滤波个数
//函数返回mel频率下的滤波器内的对数能量double*(长度为num)
double* _mfcc_filter(double *powersample,int len,int num);
//离散余弦变换,lnpower(长度为len)为滤波器内积对数能量,num与mel滤波器一致,dctnum为dct变换级数
//函数返回时double*的长度为dctnum,代表dct变换后的倒频参数
double* _mfcc_DCT(double *lnpower,int len,int dctnum);
//求音框1的能量+音框2的能量+....+音框frames的能量+dct参数
//函数返回double *,其长度为(dctlen+1)*frames
double* _mfc_Logenergy(double *powersample,int unitsize,int frames,double * dctdata,int dctlen);
//差量倒频谱参数,函数返回double*,数组长度为len*2
double* _mfcc_differential(double *logenergy,int len);
//asp.cpp
#include "stdafx.h"
#include "ASR.h"
//获取wav数据样本数据
int getWaveData(char* file,double *sample)
{
WAVE wave[1];
FILE * f;
f = fopen(file,"rb");
if(!f)
{
printf("Cannot open %s for