B,n)中怎么使用mfcc特征提取 matlab参数

语音识别-sphinx(8)
&注:老早之前就在看语音信号处理方面的知识,每当过了很久都会忘记,由于之前对语音特征MFCC提取的流程还是非常清楚的,但是对于一些细节以及一些原理一些的东西还是不是很明白,通过这次的总结,我终于明白的其中的技术细节以及设计方法,包括滤波器的设计,以及参数的具体意义,希望这个总结能给自己增加更多的印象,课本上好像对各个三角滤波器的设计没有过多的讲解,也没讲流程,希望这里的总结能有所帮助。
一、MFCC计算总体流程
1.信号的预处理,包括预加重(Preemphasis),分帧(Frame Blocking),加窗(Windowing)。假设语音信号的采样频率fs=8KHz.由于语音信号在10-30ms认为是稳定的,则可设置帧长为80~240点。帧移可以设置为帧长的1/2.
2.对每一帧进行FFT变换,求频谱,进而求得幅度谱。
3.对幅度谱加Mel滤波器组(Mel滤波器组设计问题)。
4.对所有的滤波器输出做对数运算(Logarlithm),再进一步做离散余弦变换DCT可得MFCC。
流程图如下所示:
二、实际频率与Mel频率的转换
Mel频率与实际频率的具体关系如下:
人耳的听觉特性与Mel频率的增长一致。与实际频率在1000Hz以下呈现线性分布,1000Hz以上呈现对数增长。
在Mel频率轴上配置K个通道的三角形滤波器组,K的个数由信号的截止频率决定。
设计的过程如下:
假设语音信号的采样频率,帧长N=256,滤波器个数K=22
由此可得语音信号的最大频率为:
根据下面的公式:
可以求得出最大的Mel频率为:
由于在Mel刻度范围内,各个三角滤波器的中心频率是相等间隔的线性分布。由此,可以计算两个相邻三角滤波器的中心频率的间距为:
因此,各三角形滤波器在mel刻度上的中心频率可以表示为:
由上面的中心频率可以计算出对应的线性刻度上的频率。如下图所示:
下面采用Matlab设计Mel三角形滤波器如下:
//获取Mel三角滤波器的参数
fs为采样频率,filterNum为三角滤波器的个数
maxMelFreq = freq2mel(fs/2); %将线性频率转化为mel频率,得到最大的Mel频率
sideWidth=maxMelFreq/(filterNum+1);%求频带宽带,即Mel滤波器宽度
index=0:filterNum-1;%滤波器的中心
filterBankPrm=floor(mel2freq([index+1;index+2]*sideWidth)/fs*frameSize)+1;
filterBankPrm(end, end)= frameSize/2;
&得到如下的三角形滤波器,横坐标对应于FFT中的点的下标:
&注:这里选择的帧长为256点,然后FFT的点数也为256,由于是对称的,所以只取前面一半的点计算频谱。然后加入到三角滤波器中。
每一个三角形滤波器的中心频率c(l) 在Mel频率轴上等间隔分布。设o(l),c(l),h(l) 分别是第l 个三角形滤波器的下限,中心,和上限频率,则相邻三角形滤波器之间的下限,中心,上限频率的关系如下:c(l)=h(l-1)=o(l+1)
根据语音信号幅度谱求每个三角形滤波器的输出。
对所有的滤波器输出做对数运算,再进一步做离散余弦变换(DCT)即可得到MFCC。
由上公式可知,MFCC特征参数的长度与滤波器的个数无关。只与DCT有关。
% === 对幅度谱进行三角滤波过程
function tbfCoef = triBandFilter(fftMag, P, filterBankParam)
fstart=filterBankParam(1,:);&&&&&&&&&&&&&&& %fftMag一帧数据的幅度谱
fcenter=filterBankParam(2,:);%滤波器的中心点,每列代表一个滤波器的中心频率
fstop=filterBankParam(3,:);
% Triangular bandpass filter.
for i=1:P %滤波器个数
&& for j = fstart(i):fcenter(i), %第i个滤波器起始频谱点和中心频谱点的输出
&&&&& filtmag(j) = (j-fstart(i))/(fcenter(i)-fstart(i));
&& for j = fcenter(i)+1:fstop(i),
&&&&& filtmag(j) = 1-(j-fcenter(i))/(fstop(i)-fcenter(i));
&& tbfCoef(i) = sum(fftMag(fstart(i):fstop(i)).*filtmag(fstart(i):fstop(i))'); %第i个滤波器的输出
tbfCoef=log(eps+tbfCoef.^2); %求得每个滤波器的对数输出,有多少个滤波器就有多少个输出,对应为每一帧
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:11361次
排名:千里之外
原创:11篇
转载:36篇
(1)(2)(1)(1)(1)(4)(1)(2)(3)(2)(1)(7)(2)(2)(7)(11)MFCC特征提取理解
MFCC特征提取理解 ( 20:41:04)
标签:& 杂谈 分类: 语音识别
看了个稀里糊涂,一知半解,觉得以后又会忘记。珍藏下来。边理解边添加。
以下是mfcc_float.cpp的内容
#include "stdlib.h"
#include "stdio.h"
#include "math.h"
#include "MFCC_float.h"
#define PI 3.79
#define PRE_EMP_FACTOR 0.98
#define ENE_FLOOR& 1.0
//-------------------------------------------------------------------------------------
//public functions
//constructor
CMFCC::CMFCC(long aInfo, int aSampleRate, int aN,
&&& int aFl, int
aFh, int aM, int aTypeOfFilterBank, int aP)
&//general
&SampleRate=aSampleR //sample rate
&N=aN; M=aM; P=aP; //fft point number, filterbanks
number, cepstrum order
Fh=aFh;&& //the lowest and
highest frequency (Hz) of all the filterbanks
&//pre-emphasize
&Alfa=PRE_EMP_FACTOR;
&xtmp=new double[N];
&x=new COMPLEX[N];
&X=new double[N];
&HammingWin=NewHammingWin(N);
&//triangular filterbanks
&if(aTypeOfFilterBank==MEL_SCALE)
& NewMelFilterBanks(SampleRate, Fl, Fh, N, M,
FilterBanks, FilterBanksL, FilterBanksH);
& NewLinFilterBanks(SampleRate, Fl, Fh, N, M,
FilterBanks, FilterBanksL, FilterBanksH);
&S=new double[M];
&DctMatrix=NewDctMatrix(P,M);
&//feature temp buffer
&pfFea=new double[P];
//destructor
CMFCC::~CMFCC(void)
&delete X;
&delete HammingW
&delete FilterBanks[0];
&delete FilterB
&delete FilterBanksL;
&delete FilterBanksH;
&delete S;
&delete DctMatrix[0];
&delete DctM
&delete pfF
void CMFCC::Print(void)
&fp=fopen("HammingWin.txt", "wt");
&for(i=0 ; i
& fprintf(fp, "%.6f\n", HammingWin[i]);
&fclose(fp);
&fp=fopen("FilterBanks.txt", "wt");
&for(j=0 ; j
& for(i=0 ; i
&& fprintf(fp, ".6f ",
FilterBanks[i][j]);
& fprintf(fp, "\n");
&fclose(fp);
&fp=fopen("FilterBanksLH.txt", "wt");
&for(i=0 ; i
& fprintf(fp, "%d\t%d\t%d\n", FilterBanksL[i],
FilterBanksH[i], (FilterBanksH[i]-FilterBanksL[i]+1));
&fclose(fp);
&fp=fopen("DCTMatrix.txt", "wt");
&for(i=0 ; i
& for(j=0 ; j
&& fprintf(fp, "%.6f\t",
DctMatrix[i][j]);
& fprintf(fp, "\n");
&fclose(fp);
//extract one sentence of MFCC/LFCC
int CMFCC::MFCCbySentence(short *pnWav, int SampleCount,
float *&pfMFCC, int &FrmCount, int &Dim,
int FrmWidth, int FrmOffst)
&if(FrmWidth&N || FrmOffst&FrmWidth) return
&//compute frame count & dim of feature
vector & allocate memory space
&FrmCount=(SampleCount-FrmWidth)/FrmOffst+1;
&if(FrmCount&=0)&&
return FAILURE;
&if(Info&DCEPS)
& if(FrmCount&=10) return FAILURE;
&if(Info&DCEPS) Dim+=P;
&if(Info&DDCEPS) Dim+=P;
&pfMFCC = new float[FrmCount*Dim];
&//remove DC component
&RemoveDC(pnWav, SampleCount);
&//extract one sentence of MFCC
&for(i=0 ; i
& MFCCbyFrame(&pnWav[i*FrmOffst], FrmWidth,
&pfMFCC[i*Dim], P);
&if(Info&CMS)
& CepsMeanSub(pfMFCC, FrmCount, Dim, P);
&//extract one sentence of DMFCC
&if(Info&DCEPS)
& DMFCCbyFrame(&pfMFCC[0], &pfMFCC[0],
&pfMFCC[0], &pfMFCC[1*Dim], &pfMFCC[2*Dim],
&pfMFCC[P], P);
& DMFCCbyFrame(&pfMFCC[0], &pfMFCC[0],
&pfMFCC[1*Dim], &pfMFCC[2*Dim], &pfMFCC[3*Dim],
&pfMFCC[1*Dim+P], P);
& for(i=2 ; i&=FrmCount-3 ; i++)
DMFCCbyFrame(&pfMFCC[(i-2)*Dim], &pfMFCC[(i-1)*Dim],
&pfMFCC[i*Dim], &pfMFCC[(i+1)*Dim],
&pfMFCC[(i+2)*Dim],
&pfMFCC[i*Dim+P], P);
& DMFCCbyFrame(&pfMFCC[(FrmCount-4)*Dim],
&pfMFCC[(FrmCount-3)*Dim],
&pfMFCC[(FrmCount-2)*Dim], &pfMFCC[(FrmCount-1)*Dim],
&pfMFCC[(FrmCount-1)*Dim],
&pfMFCC[(FrmCount-2)*Dim+P], P);
& DMFCCbyFrame(&pfMFCC[(FrmCount-3)*Dim],
&pfMFCC[(FrmCount-2)*Dim],
&pfMFCC[(FrmCount-1)*Dim], &pfMFCC[(FrmCount-1)*Dim],
&pfMFCC[(FrmCount-1)*Dim],
&pfMFCC[(FrmCount-1)*Dim+P], P);
&//extract one sentence of DDMFCC
&if(Info&DDCEPS)
& for(i=0 ; i
&& pfMFCC[2*P+i] =
pfMFCC[(FrmCount-1)*Dim+2*P+i] = 0;
& for(i=1 ; i&=FrmCount-2 ; i++)
DDMFCCbyFrame(&pfMFCC[(i-1)*Dim+P], &pfMFCC[i*Dim+P],
&pfMFCC[(i+1)*Dim+P],
&pfMFCC[i*Dim+2*P], P);
&return SUCCESS;
//compute one frame of MFCC/LFCC
int CMFCC::MFCCbyFrame(short *pnWav, int FrmWid, float *pfMFCC, int
CepsOrder)
&if(FrmWid&N || CepsOrder!=P) return
&//pre-emphasize& 预加重
&PreEmp(pnWav, FrmWid, xtmp, N, Alfa);
&//apply hamming
window&& 加窗(窗宽度,
&ApplyWindow(xtmp, HammingWin, N, xtmp);
&//FFT& 做fft
&for(i=0 ; i
& x[i].real=xtmp[i];&
//实部,虚部??
& x[i].image=0;
&FFTAmp(x, X, N);
&//apply triangular windows & ln
&ApplyFilterBanks(X, N, S, M,
FilterBanks, FilterBanksL, FilterBanksH);
&ApplyDCT(S, M, pfFea, P, DctMatrix);
&//double -& float
&for(i=0 ; i
& pfMFCC[i] = (float)pfFea[i];
&return SUCCESS;
//extract one frame of DMFCC
void CMFCC::DMFCCbyFrame(float *Prev2Fea, float *Prev1Fea,
float *CurrFea,
float *Next1Fea, float *Next2Fea,
float *DFea, int P)
&for(i=0 ; i
& DFea[i] =
(-0.632456f*Prev2Fea[i]-0.316228f*Prev1Fea[i]+ \
&&&&&&&&&&&&&
0.316228f*Next1Fea[i]+0.632456f*Next2Fea[i]);
//extract one frame of DDMFCC
void CMFCC::DDMFCCbyFrame(float *PrevDFea, float *CurrDFea, float
*NextDFea,
float *DDFea, int P)
&for(i=0 ; i
& DDFea[i] =
0.7071f*(NextDFea[i]-PrevDFea[i]);
//-------------------------------------------------------------------------------------
//private functions
//====== Pre-emphasize ======//
void CMFCC::PreEmp(short *pnWav, int FrmWid, double *x, int N,
double Alfa)
&int s=(N-FrmWid)/2; //start position of data in
COMPLEX x[N]& s=(512-帧宽)/2
&//clear buffer
&for(i=0 ; i
&//compute the first sample
pnWav[0]-Alfa*pnWav[0];&&
//y(n)=x(0)-a*x(0);& 第一个点
&//compute the following samples in one
&for(i=1 ; i
& x[i+s] =
pnWav[i]-Alfa*pnWav[i-1];&
//每个帧宽中的余下点,x(i+s)=后一个wav-前一个wav*a
//====== Hamming window ======//
//generate a hamming window
double* CMFCC::NewHammingWin(int Len)
&double* Win=new double[Len];
&for(int i=0; i
& Win[i]=(0.54-0.46*cos(2*PI*i/Len));
//applying a window
void CMFCC::ApplyWindow(double *In, double *Win, int Len, double
& for(int i=0; i
Out[i]=In[i]*Win[i];& //对于音频,乘以窗函数
//====== FFT ======//
//Func: FFT 2DIT
//In: COMPLEX *input. //one frame of wave data
//& //Point number of FFT
//Out: COMPLEX * //real part and image part after FFT
实部和虚部
void FFT(COMPLEX *input, int n)
&int x, i, nv2, j, k, le, l, le1, ip, nm1;
&COMPLEX t, u,& //复数
&for(x=0; n&1; x++)
&for(i=1; i&=nm1; i++)
& if(i //i是前一个点,j是后一个点
&& t.real =
input[i-1].
&& t.image =
input[i-1].
&& input[i-1].real =
input[j-1].
&& input[i-1].image =
input[j-1].
&& input[j-1].real =
&& input[j-1].image =
t.& //后一个点被前一个点代替
&for(l=1; l&=x; l++)
& u.real = 1.0f;
& u.image = 0.0f;
& w.real = (float)cos(PI/le1);
& w.image = (float)-sin(PI/le1);
& for(j=1; j&=le1; j++)
&& for(i=j; i&=n; i+=le)
&&& t.real =
input[ip-1].real*u.real-input[ip-1].image*u.
&&& t.image =
input[ip-1].real*u.image+input[ip-1].image*u.
input[ip-1].real = input[i-1].real-t.
input[ip-1].image = input[i-1].image-t.
input[i-1].real = t.real+input[i-1].
input[i-1].image = t.image+input[i-1].
&& t.real =
u.real*w.real-u.image*w.
&& t.image =
u.image*w.real+u.real*w.
&& u.real = t.
u.image = t.
//Func: FFTAmp, compute the amplitude of spectrum&
急速频率谱的幅度
//In: COMPLEX *x. //one frame of wave data 一帧的wav
//& int N; //point number of
FFT&& 做fft的点数
//Out: double *A //spectral amplitude of this
frame&& 这一帧的谱幅度
void CMFCC::FFTAmp(COMPLEX *x, double *Amp, int
N)& //实部和虚部的平方和开方,求模
&FFT(x, N);
&//sqrt& 开方
&for(int i=0 ; i&=N/2 ; i++)
& Amp[i]=sqrt(x[i].real*x[i].real +
x[i].image*x[i].image);
//====== DCT ======//
//generate the matrix of DCT, excluding 0'th dimension
double** CMFCC::NewDctMatrix(int nP, int nM)
&double **Matrix=new double*[nP];
&Matrix[0]=new double[nP*nM];
&for(p=1 ; p
&for(p=0 ; p
& for(m=0 ; m
Matrix[p][m]=cos(PI*p*(m+0.5)/nM);& //including
Matrix[p][m]=cos(PI*(p+1)*(m+0.5)/nM); //excluding c0
//applying a transformation matrix&
逆傅里叶变换
void CMFCC::ApplyDCT(double *In, int InDim, double *Out, int
OutDim, double **Matrix)
&for(p=0 ; p
& Out[p]=0;
& for(m=0 ; m
Out[p]+=In[m]*Matrix[p][m];
//====== Generating Filterbanks on Mel-Scale & Linear-Scale
//FFT point to frequency in Hz
double n2f(int n, int Fs, int N)
&if(n&0||n&=N) return 0;
&f=(n+0.5)*Fs/N;
//frequency in Hz to FFT point
int f2n(double f, int Fs, int N)
&if(f&0||f&Fs) return 0;
&n=(int)(f*N/Fs+0.5);
//frequency in Hz to bark
double f2b(double f)
&if(f&0) return 0;
&b=1125*log(1+f/700.0);
//bark to frequency in Hz& 将bark换成频率
double b2f(double b)
&if(b&0) return 0;
&f=700*(exp(b/1125)-1);
//compute the central point of each filterbank on
//for M filterbanks, the central point shoule be extended to
int* MelCentralPoint(int Fl, int Fh, int M,
int Fs, int N)
&double F;
&int *CentralPoint=new int[M+2];
&for(m=0 ; m&=M+1 ; m++)
& //central frequency&
中心频率,高-低加低,乘以m数/点数
& F=b2f(f2b(Fl)+(f2b(Fh)-f2b(Fl))*m/(M+1));
& //central point
& CentralPoint[m]=f2n(F, Fs, N);
&return CentralP
//compute the central point of each filterbank on
linear-scale
//for M filterbanks, the central frequency shoule be extended to
int* LinCentralPoint(int Fl, int Fh, int M,
int Fs, int N)
&double F;
&int *CentralPoint=new int[M+2];
&for(m=0 ; m&=M+1 ; m++)
& //central frequency
& F=Fl+(Fh-Fl)*m*1.0/(M+1);
& //central point
& CentralPoint[m]=f2n(F, Fs, N);
&return CentralP
//generate the one filter
void GenTriangularFilter(double *FilterBank,
int ns, int nm1, int nm2, int nm3, int ne)
&for(n=ns& ;
nFilterBank[n]=0;
&for(n=nm1 ;
nFilterBank[n]=1.0*(n-nm1)/(nm2-nm1);
&for(n=nm2 ;
nFilterBank[n]=1.0*(nm3-n)/(nm3-nm2);
&for(n=nm3 ; n++) FilterBank[n]=0;
//Generate a set of mel-scale filterbanks 一个mel滤波器
//In: int Fs; //sample rate采样率
//& int Fl; //the lowest frequency of all the
filterbanks最低频率
//& int Fh; //the highest frequency of all the
filterbanks
//& int N; //FFT point&
//& int M; //number of
filterbanks& 滤波器的个数
//Out: double **FilterB //Triangular
filters&& 三角滤波器
//& int *FilterBanksL;& //Lower
point number of filters& 低一级的滤波器
//& int *FilterBanksH;& //Higher
point number of filters& 高一级的滤波器
void CMFCC::NewMelFilterBanks(int Fs, int Fl, int Fh, int N, int
double **&FilterBanks, int *&FilterBanksL, int
*&FilterBanksH)
&//allocate memory space for
filters& 为滤波器分配空间
&FilterBanksL=new int[M];
&FilterBanksH=new int[M];
&FilterBanks=new double*[M];
&FilterBanks[0]=new double[M*N];
&for(m=1 ; m //每个滤波器做傅里叶变换的点数是n
&//compute the central points of filterbanks,
totall M+2 points& 计算滤波器的中心点,m个滤波器,是m+2个点
*MelCenPoints=MelCentralPoint(Fl,Fh,M,Fs,N);
&for(m=0 ; m
& FilterBanksL[m]=MelCenPoints[m];
& FilterBanksH[m]=MelCenPoints[m+2];
& GenTriangularFilter(FilterBanks[m], 0,
MelCenPoints[m], MelCenPoints[m+1], MelCenPoints[m+2], N-1);
&delete MelCenP
//Generate a set of linear-scale filterbanks
void CMFCC::NewLinFilterBanks(int Fs, int Fl, int Fh, int N, int
double **&FilterBanks, int *&FilterBanksL, int
*&FilterBanksH)
&//allocate memory space for filters
&FilterBanksL=new int[M];
&FilterBanksH=new int[M];
&FilterBanks=new double*[M];
&FilterBanks[0]=new double[M*N];
&for(m=1 ; m
&//compute the central points of filterbanks,
totall M+2 points
*LinCenPoints=LinCentralPoint(Fl,Fh,M,Fs,N);
&for(m=0 ; m
& FilterBanksL[m]=LinCenPoints[m];
& FilterBanksH[m]=LinCenPoints[m+2];
& GenTriangularFilter(FilterBanks[m], 0,
LinCenPoints[m], LinCenPoints[m+1], LinCenPoints[m+2], N-1);
&delete LinCenP
//====== Applying Filterbanks & Log Compression ======//
加滤波器,对数化
void CMFCC::ApplyFilterBanks(double *X, int N, double *S, int
double **FilterBanks, int *FilterBanksL, int *FilterBanksH)
&for(m=0 ; m
& //get the lowest and the highest point number of
mth filterbank 得到第m个滤波器的最低和最高点
& nl=FilterBanksL[m];&
nh=FilterBanksH[m];
& if(nl&0 || nh&=N || nl&=nh)
&& S[m]=0;
& //filter the signal with mth filterbank
& for(n= n&= n++)
S[m]+=X[n]*FilterBanks[m][n];
& S[m]=log(S[m]);
//====== CMS by Sentence ======//& 得到均值
void CMFCC::CepsMeanSub(float *pfMFCC, int FrmCount, int Dim, int
CepsOrder)
&float *Mean=new float[CepsOrder];
&for(i=0 ; i
& Mean[i]=0;
& for(j=0 ; j
Mean[i]+=pfMFCC[j*Dim+i];
& Mean[i]/=FrmC
&for(i=0 ; i
& for(j=0 ; j
&& pfMFCC[j*Dim+i]-=Mean[i];
//====== Remove DC component ======//
void CMFCC::RemoveDC(short *pnWav, int SampleCount)
&if(pnWav==NULL || SampleCount&=0)
&float sum=0,
&for (i=0 ; i
& sum += pnWav[i];
&sum /= SampleC
&for (i=0 ; i
& wav = pnWav[i]-
& pnWav[i] = (short)
以下是mfcc_float.h的内容
由此可看出,本程序是mfcc特征和差分mfcc的结合,先提取mfcc,在对提取到的特征向量做差分,进一步剥离特征,目的是为了得到说话人言语和速度的变化啊啥的巴拉巴拉。看了一遍程序,总容易各种分心,太多不知道所以看得很晕。这个盒子,总算打开了。
首先,是预加重,是说为了减少嘴唇和声带的效应影响,加重高频部分,理解来就是消除唇部的摩擦,对真实的语音的频率做补偿。方法是y(n)=x(n)-a*x(n-1).这里a是,alfa系数,在0.9到1之间,一般取0.98。
其次是加窗分帧。加窗,又设计到语音的特征巴拉巴拉。语音在长范围内是不停变动的,没有固定的特性无法做处理,所以加个窗,窗外的值设定为0,这样就吧要处理的部分固定在窗内,做处理。这样的窗将分析帧,一般取10-30ms做为窗,为了避免窗边界对信号的遗漏,要对帧做偏移时候,要有帧迭,所以一般取帧长的一半作为帧移。加的窗是汉明窗。公式是在加窗范围内,
w(n)=0.54-0.46*cos(2*pi*n/(n-1)).用汉明窗是因为在时域,是信号乘以窗函数,所以它两端是平滑过渡到0,不像矩形窗变化剧烈,而在频率它能保留高频成分,保留细节信息。
再次就是提取特征了。步骤为先离散傅里叶变换,将信号变换到频域上。这里涉及到dft变换的过程,是实部虚部分别作处理。程序中DFT一段需要细细研究,没看懂。
离散傅里叶变换后得到信号的频谱,然后对它的幅度做平方,就是能量谱。
啥是能量谱?
在这一步步的追溯到太多问题了,查阅资料也各种明白了点,但更多的是一知半解。收集以后一点点明白。
【对于能量信号,常用能量谱来描述。所谓的能量谱,也称为能量谱密度,是指用密度的概念表示信号能量在各频率点的分布情况。也即是说,对能量谱在频域上积分就可以得到信号的能量。能量谱是信号幅度谱的模的平方,其量纲是焦/赫。对于功率信号,常用功率谱来描述。所谓的功率谱,也称为功率谱密度,是指用密度的概念表示信号功率在各频率点的分布情况。也就是说,对功率谱在频域上积分就可以得到信号的功率。从理论上来说,功率谱是信号自相关函数的傅里叶变换。因为功率信号不满足傅里叶变换的条件,其频谱通常不存在,维纳-辛钦定理证明了自相关函数和傅里叶变换之间对应关系。在工程实际中,即便是功率信号,由于持续的时间有限,可以直接对信号进行傅里叶变换,然后对得到的幅度谱的模求平方,再除以持续时间来估计信号的功率谱。】又学习了。
啥是能量信号?
【当且仅当f(t)在所有时间上的能量不为0且有限时,该信号为能量信号,即(1)式中的 T
趋于无穷大的时候E为有限。典型的能量信号如方波信号、三角波信号等。但是有些信号不满足能量信号的条件,如周期信号和能量无限的随机信号,此时就需要用功率来描述这类信号。当且仅当x(t)在所有时间上的功率不为0且有限时,该信号为功率信号】一般来说,周期信号和随机信号是功率信号,而非周期的确定信号是能量信号。
因为语音信号是非周期的,且有人的能量。所以它是能量信号。
啥是能量?啥是功率?
功率是单位时间做的功,单位时间的能量,能量是连续时间内的功,能量就是对功率在一段时间内做积分。
再回去,得到能量谱后,用一组mel尺度的三角形滤波器组对能量谱做滤波。滤波器的个数为24-40个。每个滤波器有个中心频率。m个数小的时候他们间隔小,m多的时候间隔大。他们有交叠,当前滤波器的中心频率是上一个的最高频率,也是下一个的最低频率。
这样得到每个滤波器的输出,滤波器的传递函数有公式。因为是mel尺度的频率,要化为线性频率,所以有个f2b.
每个滤波器的中心频率是线性的。用这些滤波器来模拟人的听觉特性,将线性频率转化为mel频率,是B(f)=1125ln(1+f/700)。这样。就可以计算出对应的mel频率滤波器界限。进而得到滤波器函数,乘以能量谱,再取对数就是滤波器的输出。
然后,对输出做dct变换,是离散余弦变换。
啥是离散余弦变换?dct?
看了百度,有点理解。说是形成一个dct矩阵,左上角是重要部分,右下角是非重要部分,甚至可以抛弃,这样对压缩很有用,捡重要部分来压缩。矩阵的求解有公式。
自此,mfcc特征提取完成了。
还有很多原理上的,编程上的疑问再解决。
问:傅里叶变换过程,滤波器,数字信号处理。。很多流程。。明天理解。
//----------------------------------------------------------------------------------------
#ifndef __MFCCH_FLOAT_H__
#define __MFCCH_FLOAT_H__
#define SUCCESS& 1
#define FAILURE& 0
//----------------------------------------------------------------------------------------
#define MEL_SCALE 0
#define LIN_SCALE 1
#define CMS&&
0x0001& //parameters for long I
#define DCEPS& 0x0002
#define DDCEPS& 0x0004
//complex structure&& 复数
struct COMPLEX
//MFCC extraction class& MFCC提取类
class CMFCC
&//采样率16KHZ,频率为从100到7000,24个滤波器,其余参数不解其意???
&//constructor, allocate memory & generate
pre-set parameters& 构造函数,初始参数
&CMFCC(long aInfo=7, int aSampleRate=16000, int
&&& int aFl=100,
int aFh=7000, int aM=24, int aTypeOfFilterBank=0, int aP=12);
&//destructor, release memory
space& 析构函数,释放内存
&~CMFCC(void);
&void Print(void);
&//Func: extract one sentence of MFCC
&int MFCCbySentence(short *pnWav, int
SampleCount,
float *&pfMFCC, int &FrmCount, int &Dim,
int FrmWidth=512, int FrmOffst=256);
&//Func: extract one frame of MFCC
&//In: short *pnW //one frame of wave
&//& int FrmW //frame
&//Out: float *pfMFCC; //one frame of MFCC
&//& int CepsO //order of
&//Ret: flag of SUCCESS or FAILURE
&int MFCCbyFrame(short *pnWav, int FrmWid, float
*pfMFCC, int CepsOrder);
&//Func: extract one frame of DMFCC
&//In: float *Prev2F //feature vector of
previous second frame
&//& float *Prev1F //feature
vector of previous first frame
&//& float
*CurrF& //feature vector of current frame
&//& float *Next1F //feature
vector of next first frame
&//& float *Next2F //feature
vector of next second frame
&//& int P; //order of delta
&//Out: float *DF //delta cepstrum of current
&void DMFCCbyFrame(float *Prev2Fea, float
*Prev1Fea,
float *CurrFea,
float *Next1Fea, float *Next2Fea,
float *DFea, int P);
&//Func: extract one frame of DDMFCC
&//In: float *PrevDF //delta feature vector of
previous frame
&//& float *CurrDF //delta
feature vector of current frame
&//& float *NextDF //delta
feature vector of next frame
&//& int P; //order of delta
delta cepstrum
&//Out: float *DDF& //delta
delta cepstrum of current frame
&void DDMFCCbyFrame(float *PrevDFea, float
*CurrDFea, float *NextDFea,
float *DDFea, int P);
&//--- general parameters ---//
&int SampleR //sample rate
&int N, P; //point number of FFT, order of
&//--- pre-emphasize ---//
&double A //factor of pre-emphasize
&double *//double xtmp[N], temp buffer for
&//pre-emphasize
&void PreEmp(short *pnWav, int FrmWid, double *x,
int N, double Alfa);
&//--- FFT ---//
&double *HammingW //double HammingWin[N],
weights of hamming window
&//generate the weights of a hamming
&double* NewHammingWin(int Len);
&//apply a hamming window
&void ApplyWindow(double *In, double *Win, int
Len, double *Out);
&COMPLEX *x; //COMPLEX x[N], x.real is the
input for FFT
&double *X;& //double X[N],
spectral amplitude of this frame, only [0,N/2) is efficient
&//compute spectral amplitude
&void FFTAmp(COMPLEX *x, double *Amp, int N);
&//--- triangular filterbanks & ln
&int M; //number of triangular filters
&int Fl, Fh; //lowest and highest frequencies of
all the filterbank, in Hz
&double *S; //double S[M], the output of
filterbanks
&double **FilterB //double
FilterBanks[M][N], the weights of each point and each
filterbanks
&int *FilterBanksL; //int FilterBanksL[M], the
lower point of each filterbanks
&int *FilterBanksH; //int FilterBanksH[M], the
higher point of each filterbanks
&//generate a set of filterbanks on mel-scale
&void NewMelFilterBanks(int Fs, int Fl, int Fh,
int N, int M,
double **&FilterBanks, int *&FilterBanksL, int
*&FilterBanksH);
&//generate a set of filterbanks on
linear-scale& 线性频率上
&void NewLinFilterBanks(int Fs, int Fl, int Fh,
int N, int M,
double **&FilterBanks, int *&FilterBanksL, int
*&FilterBanksH);
&//apply triangular windows & ln
&void ApplyFilterBanks(double *X, int N, double
*S, int M,
double **FilterBanks, int *FilterBanksL, int *FilterBanksH);
&//--- DCT
离散余弦变换
&double **DctM //double DctMatrix[P][M], the
matrix of DCT
&//generate the transform matrix of DCT
&double** NewDctMatrix(int nP, int nM);
&//DCT& dct矩阵
&void ApplyDCT(double *In, int InDim, double *Out,
int OutDim, double **Matrix);
&//--- CMS ---//
&//Cepstrum Mean Subtraction&
差分倒谱系数的提取
&void CepsMeanSub(float *pfMFCC, int FrmCount, int
Dim, int CepsOrder);
&//--- remove DC component ---//
&void RemoveDC(short *pnWav, int SampleCount);
&//--- Operations on a whole sentence
&double *pfF //double pfFea[P]; feature temp
//----------------------------------------------------------------------------------------
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 mfcc特征进行svm训练 的文章

 

随机推荐