📄 mfcc.cpp
字号:
// 语音信号LPC美尔倒谱系数的分析程序
/* 文件名:main.cpp */
#include <STDIO.H>
#define PREEMPHASIS 1 /* pre-emphasis on(1)/off(0) */
#define ERROR -1
#define AD_SIZE 240000 /* max size of A/D data */
#define TRN_SIZE 512 /* file read size (bytes) */
#define W_SIZE 256 /* window size when 12khz, window=21.33msec */
#define MEL_ODR 10 /* ordea of mel-warped lpc cestrum */
#define SHIFT 96 /* window shift (points) when 12khz,frame=8mesc */
#define ORDER 14 /* order of autocorrelation etc. */
#define ALPHA 0.41 /* 0.31 at 8khz sampling */
/* 0.35 at 10khz sampling */
/* 0.41 at 12khz sampling */
/* 函数名称:main */
/* 函数功能:语音参数分析主程序 */
main()
int argc;
char *argv[];
{
static short ad[AD_SIZE+W_SIZE], num_frame;
static short ead[AD_SIZE+W_SIZE];
float rad[W_SIZE];
float cor[ORDER+1];
float ref[ORDER+1];
float alf[ORDER+1];
float cep[ORDER+1];
float mel[ORDER+1];
float resid;
int fp, fp_a, fp_l;
int i, j, n, nn;
FILE *fp_c, *fopen();
char f_a[256], f_l[256], f_p[256], f_c[256];
/* 命令行检查 */
if (argc!=3) {
printf("Usage : %s<PCM_DATA> <MEL_FILE> \n",argv[0]);
exit();
}
f_a[0]=f_l[0]=f_p[0]='\0';
strcpy(f_c,argv[2]);
/* 文件打开 */
if ((fp=open(argv[1],0))==NULL) {
printf("%s:cannot creat file \n",f_c);
exit();
}
/* A/D 数据文件读取 */
nn=0;
for(i=0;i<W_SIZE DATA-- printf(?PCM } break; if(n<TRN_SIZE) nn+="n/2;" exit(); \n?,argv[1]); file read printf(?%s:cannot { if(n="=ERROR)" n="read(fp,&ad[i],TRN_SIZE);" for(i="W_SIZE/2;i<=AD_SIZE+W_SIZE/2-TRN_SIZE/2;i+=TRN_SIZE)" ad[i]="0;" 2;i++)>%s[%d words] \n",argv[1],nn);
if(i>AD_SIZE+W_SIZE/2-TRN_SIZE/2) {
printf("%s:too long data file \n",argv[1]);
exit();
}
for(i=nn+W_SIZE/2;i<NN+W_SIZE;I++) } exit(); file printf(?%s:cannot { for(i="1;i<nn+W_SIZE;i++)" ad[i]="0;" FILE-- printf(?MEL if(f_c[0]!="NULL)" fclose(fp_c); \n?,f_c); write if(fwrite(mel,sizeof(float),MEL_ODR+1,fp_c)!="(MEL_ODR+1))" cepmel(cep,mel); ************************ 14) to (0 -------Cepstrum p[14]-p[28] 4) (1 parm -------Alpha p[0]-p[13] float -------cepstrum p[2]-p[17] -------power p[1] -------pitch p[0] * 每一帧的系数格式 alfcep(ORDER,alf,cep,ORDER); LPC倒谱计算 correl(ORDER,cor,alf,ref,&resid); LPC分析程序 ); correl(rad,cor,W_SIZE,ORDER 自相关计算 \n?); windowing hamming in occured printf(?ERROR if(ham(rad,&ead[i],W_SIZE)="=1)" 汉明窗和路径呼叫得到系数 #endif ead[i]="ad[i]-0.98*ad[i-1];" #else PREEMPHASIS #if ead[0]="ad[0];" D数据预分析 A>%s[%d frames] \n",f_c,num_frame);
}
/* 函数名称:ham
函数功能:计算加窗后的信号
输入参数:r---加汉明窗后的信号数据
nad---读入的信号数据
iw---数据窗的长度(8=<IW<=1024) } { for(i="0;i<iw;i++)" float * if(iw<8||iw wind[i]="(0.54+0.46*cos((double)(d*(2*i-iw+1))));" d="3.14159265/(iw-1);" chckiw="0;" if(chckiw!="iw)" cos(); double d,wind[1024]; static i; int r[]; iw; nad[]; short ham(r,nad,iw)>1024) {
printf("ham err");
return(1);
}
for(i=0;i<IW;I++) } { for(i="0;i<iw;i++)" float * int if(u0 u0+="rsam[i]*rsam[i];" u0="0.0;" u0,u; i,j; iw,ip; rsam[],roor[]; correl(rsam,roor,iw,ip) iw---数据窗的长度 rsam---输入的加窗后的信号量 roor---信号的自相关函数 输入参数:ip----LPC分析的阶数 函数功能:计算信号的自相关函数 函数名称:correl return(0); r[i]="wind[i]*nad[i];">0) {
for(i=1;i<=ip;i++)
{
u=0.0;
for(j=0;j<IW-I;J++) } { for(i="1;i<=ip;i++)" float * int i,j; if(i i+="1;" step3: ss-="alf[i]*cep[m-i];" step2: step3; goto i="0;" ss="0.0;" m+="1;" next: start; m="0;" ss; m,i,j; alf[],cep[]; ip,n; alfcep(ip,alf,cep,n) n---LPC倒谱系数的阶数 cep---LPC倒谱系数(cep[1]cep[n],注意:cep[o]在本程序中未使用) alf---LPC预测系数(alf[1]alf[ip]) 输入参数:ip---LPC分析的阶数 函数功能:由LPC预测系数计算LPC的到谱系数 函数名称:alfcep *resid*="1.0-refi*refi;" alf[i-j]-="refi*alfsave;" if(2*j!="i)" alf[j]="alfsave-refi*alf[i-j];" alfsave="alf[j];" for(j="1;j<i;j++)" alf[i]="(-refi);" ref[i]="refi;" ="(*resid);" refi="cor[i];" refi+="alf[j]*cor[i-j];" *resid="1.0-ref[1]*ref[1];" alf[0]="1.0;" alf[1]="(-ref[1]);" ref[1]="cor[1];" refi,alfsave; cor[],alf[],ref[],*resid; ip; corref(ip,cor,alf,ref,resid) resid---LPC预测参差 ref---反射系数(ref[1]ref[ip],符号与常规的定义相反) alf---LPC系数(alf[1]alf[n],注意:alf[0]="1)" cor---信号的自相关函数(cor[1]cor[ip]) 函数功能:由自相关函数计算LPC预测系数和反射系数 函数名称:corref roor[0]="u0;" roor[i]="u/u0;" else u+="rsam[j]*rsam[j+i];">ip) goto step4;
if(i<M) } { float * double int ss-="alf[m]*m;" goto ="m;" for(n="ORDER;n" u0[ORDER+1]="0.0;" 计算mel[0] u0[ORDER+2],u1[ORDER+2],alpha="ALPHA;" k,n; *cep,*mel; cepmel(cep,mel) mel---Mel倒谱系数 输入参数:cep---LPC倒谱系数 函数功能:由LPC倒谱系数计算Mel倒谱系数 函数名称:cepmel cep[m]="ss;" for(m="2;m<=n;m++)" next; if(m<n) start: step4: step2;>=0;--n)
u0[n]=cep[n]+alpha*u0[n+1];
mel[0]=u0[0];
//计算mel[1]
u1[ORDER+1]=0.0;
for(n=OADER;n>=0;--n)
u1[n]=(1.0-alpha*alpha)*u0[n+1]+alpha*u1[n+1];
mel[1]=u1[0];
//计算mel[2] mel[3]-----mel[ORDER]
for(k=2;k<=ORDER;++k) {
for(n=0;n<=ORDER+1;++n)
u0[n]=u1[n];
for(n=ORDER;n>=0;n--)
u1[n]=u0[n+1]+alpha*(u1[n+1]-u0[n]);
mel[k]=u1[0];
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -