最近做声音识别相关工作,故汇总整理一些声音的资料分享
梅尔(Mel)频率分析
在语音识别(SpeechRecognition)和话者识别(SpeakerRecognition)方面,最常用到的语音特征就是梅尔倒谱系数(Mel-scaleFrequency Cepstral Coefficients,简称MFCC)。根据人耳听觉机理的研究发现,人耳对不同频率的声波有不同的听觉敏感度。从200Hz到5000Hz的语音信号对语音的清晰度影响对大。两个响度不等的声音作用于人耳时,则响度较高的频率成分的存在会影响到对响度较低的频率成分的感受,使其变得不易察觉,这种现象称为掩蔽效应。由于频率较低的声音在内耳蜗基底膜上行波传递的距离大于频率较高的声音,故一般来说,低音容易掩蔽高音,而高音掩蔽低音较困难。在低频处的声音掩蔽的临界带宽较高频要小。所以,人们从低频到高频这一段频带内按临界带宽的大小由密到疏安排一组带通滤波器,对输入信号进行滤波。将每个带通滤波器输出的信号能量作为信号的基本特征,对此特征经过进一步处理后就可以作为语音的输入特征。由于这种特征不依赖于信号的性质,对输入信号不做任何的假设和限制,又利用了听觉模型的研究成果。因此,这种参数比基于声道模型的LPCC相比具有更好的鲁邦性,更符合人耳的听觉特性,而且当信噪比降低时仍然具有较好的识别性能。
梅尔刻度是一种基于人耳对等距的音高(pitch)变化的感官判断而定的非线性频率刻度,和频率的赫兹的关系如下:
m=2595*log10(1+f/700)
所以当在梅尔刻度上面上是均匀分度的话,对于的赫兹之间的距离将会越来越大。梅尔刻度的滤波器组在低频部分的分辨率高,跟人耳的听觉特性是相符的,这也是梅尔刻度的物理意义所在。
倒谱分析
对于一个语音的频谱图,峰值就表示语音的主要频率成分,我们把这些峰值称为共振峰(formants),而共振峰就是携带了声音的辨识属性(就是个人身份证一样)。所以它特别重要。用它就可以识别不同的声音。
我们要提取的不仅仅是共振峰的位置,还得提取它们转变的过程。所以我们提取的是频谱的包络(Spectral Envelope)。这包络就是一条连接这些共振峰点的平滑曲线。我们可以这么理解,将原始的频谱由两部分组成:包络和频谱的细节。这里用到的是对数频谱,所以单位是dB。那现在我们需要把这两部分分离开,这样我们就可以得到包络了。
这就用到了倒谱分析。倒谱(cepstrum)是一种信号的傅里叶变换经对数运算后再进行傅里叶反变换得到的谱。倒谱分析可用于将信号分解,两个信号的卷积转化为两个信号的相加。
假设上面的频率谱X(k),时域信号为x(n),那么满足
X(k)=DFT(x(n))
考虑将频域X(k)拆分为两部分的乘积:
X(k)=H(k)E(k)
假设两部分对应的时域信号分别是h(n)和e(n),那么满足:
x(n)=h(n)∗e(n)
此时我们是无法区分开h(n)和e(n),对频域两边取log:
log(X(k))=log(H(k))+log(E(k))
然后进行反傅里叶变换:
IDFT(log(X(k)))=IDFT(log(H(k)))+IDFT(log(E(k)))
得到的时域信号如下:
X’(n)=h’(n)+e’(n)
此时获得时域信号x’(n)即为倒谱,已经和原始的时域信号x(n)不一样,但是可以把时域信号的卷积关系转化为了线性加关系。倒谱分析已经将两部分对应的时域信号的卷积关系转化为了线性加关系,所以只需要将倒谱通过一个低通滤波器即可获得包络部分对应的时域信号h’(t)。
梅尔频率倒谱系数MFCC
通常,计算MFCC之前,还会通过预加重、分帧和加窗、短时FFT等手段将原始原始声音信号的spectrogram声谱图,MFCC对声谱信号进行分析。
提取MFCC特征的过程:
1)先对语音进行预加重、分帧和加窗;
2)对每一个短时分析窗,通过FFT得到对应的频谱;
3)将上面的频谱通过Mel滤波器组得到Mel频谱;
4)在Mel频谱上面进行倒谱分析(取对数,做逆变换,实际逆变换一般是通过DCT离散余弦变换来代替上文的IDFT,取DCT后的第2个到第13个系数作为MFCC系数),获得Mel频率倒谱系数MFCC。
[x fs]= audioread ('test.wav');
bank=melbankm(24,256,fs,0,0.4,'t');%Mel滤波器的阶数为24,fft变换的长度为256,采样频率为16000Hz
%归一化mel滤波器组系数
bank=full(bank);
bank=bank/max(bank(:));
for k=1:12 %归一化mel滤波器组系数
n=0:23;
dctcoef(k,:)=cos((2*n+1)*k*pi/(2*24));
end
w=1+6*sin(pi*[1:12]./12);%归一化倒谱提升窗口
w=w/max(w);%预加重滤波器
xx=double(x);
xx=filter([1-0.9375],1,xx);%语音信号分帧
xx=enframe(xx,256,80);%对x 256点分为一帧
%计算每帧的MFCC参数
for i=1:size(xx,1)
y=xx(i,:);
s=y'.*hamming(256);
t=abs(fft(s));%fft快速傅立叶变换
t=t.^2;
c1=dctcoef*log(bank*t(1:129));
c2=c1.*w';
m(i,:)=c2';
end
%求取一阶差分系数
dtm=zeros(size(m));
for i=3:size(m,1)-2
dtm(i,:)=-2*m(i-2,:)-m(i-1,:)+m(i+1,:)+2*m(i+2,:);
end
dtm=dtm/3;
%求取二阶差分系数
dtmm=zeros(size(dtm));
for i=3:size(dtm,1)-2
dtmm(i,:)=-2*dtm(i-2,:)-dtm(i-1,:)+dtm(i+1,:)+2*dtm(i+2,:);
end
dtmm=dtmm/3;
%合并mfcc参数和一阶差分mfcc参数
ccc=[m dtm dtmm];
%去除首尾两帧,因为这两帧的一阶差分参数为0
ccc=ccc(3:size(m,1)-2,:);
subplot(2,1,1)
ccc_1=ccc(:,1);
plot(ccc_1);title('MFCC');ylabel('幅值');
[h,w]=size(ccc);
A=size(ccc);
subplot(212)
plot([1,w],A);
xlabel('维数');
ylabel('幅值');
title('维数与幅值的关系')
运行上段代码需要用到matlab的语音处理工具箱,voicebox是一个MATLAB中的语音处理工具箱,支持MATLAB6.5以上的版本。其中包含了对语音的分帧处理,滤波,加窗,参数提取等等函数,是语音识别几乎不可缺少的一个工具箱。
官方下载:http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/voicebox.zip
voicebox的添加
解压下载的voicebox,把解压包放在某一个路径下d:/…/voicebox
打开MATLAB,在命令行设置MATLAB的搜索路径
addpath(genpath('d:/…/voicebox'))
或者
path(' d:/…/voicebox',path)
检验是否设置成功,在命令行上输入 which activlev.m,看一下是否显示正确的路径。这样MATLAB就可以使用voicebox的函数了,