本文主要是介绍语音知识回顾和总结---短时频域性质,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
从上次的短时时域性质,隔了很长时间才开始进行这个。这个频域写完,后面的安排就是首先就是语音的特征,然后把VQ,DTW,HMM,GMM和语音识别系统的一些东西写下。希望这个系列可以丰富点。由于最近在看信息检索,大数据的一些东西,总是感觉自己学的是不是太广了,所以有时候停下来要不断的去思考自己所走的路,所学的东西。前几天,在qq空间看到一个工作2年的人说没有了目标,学会了安逸。也许就是没有目标吧,我似乎总是能找到需要学的东西,但是这样无形我的压力很大,所以适当的目标是合适,祝愿你可以开心的学习,开心的生活。有点煽情,接下来,我们去看看语音的短时频域分析吧。希望你有所收获。
说到频域,似乎大家都会想到傅里叶变换。对于连续的信号是FFT,对于离散的信号时DFT。一般的傅里叶变换适合周期信号和平稳随机信号,但不适合语音信号。为什么?因为语音是短时平稳的。所以只能用短时傅里叶去分析。就是分帧后才对其进行傅里叶变换。某一帧的短时傅里叶变换的定义如下:
一般我们求短时傅里叶变换时都用汉明窗。为什么用这个窗?而不是用矩阵窗和汉宁窗呢?原因见下图:
原因是:
这些都是《数字语音处理及MATLAB仿真》这本书上的。感觉介绍的比我的好,所以……
最后,说下这个重要性。语音的频域性质就这一个。所以时域解决不了就是它了。后面我希望自己可以把这个代码贴出来。
好吧,找到c的代码。
float stft(float *input,float *output,int fftsize,int hopsize)
{
uintptr_t handle;
int posin,posout,i,data_len;
float *sigframe,*specframe, *window;
FILE *zhong=fopen("zhong.txt","w+");
handle=fa_fft_init(FFTSIZE);
sigframe= (float *)malloc(sizeof(fftsize) * 2);
specframe= (float *)malloc(sizeof(fftsize) *2);
window= (float *)malloc(sizeof(fftsize) *2);q
//window
for (i=0;i<fftsize;i++) //compute hanning at the length of 512
window[i]=(1.0-cos(2.0*pi*i/(fftsize-1)))/2.0; //window is hanning
for(posin=posout=0;posin<data_len;posin+=hopsize)
{
// window a signal frame
for(i= 0;i<fftsize;i++)
if (posin+i<data_len)
sigframe[i] = input[posin+i]*window[i];
else
sigframe[i]=0;
// transform it
fa_fft(handle,sigframe);
for (i = 0; i <fftsize ; i++)
specframe[i]=sqrt(fft_inbuf[2*i]*fft_inbuf[2*i]+fft_inbuf[2*i+1]*fft_inbuf[2*i+1]);
//output it
for ( i=0;i<fftsize;i++,posout++)
output[posout]=specframe[i];
}
free(sigframe);
free(specframe);
return posout ;
}
这里需要调用fft的函数。大家应该可以看到stft'的公式和代码的结合。
matlab的stft的代码在网上很多。我们在求频谱的时候需要用到这个函数。虽然matlab求语音频谱有库函数,但是仔细分析还是挺麻烦的。这里就不贴matlab的代码。有STFT的公式,其实对于matlab代码很快就可以搞定。不知道的可以留言。
好了,这个短时频域分析就说到这里,期待下一次的mfcc,lpcc的特征。
有任何问题,欢迎指正。
这篇关于语音知识回顾和总结---短时频域性质的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!