声音处理之-梅尔频率倒谱系数(MFCC)

声音处理之-梅尔频率倒谱系数(MFCC)

梅尔(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));endw=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,:);enddtm=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,:);enddtmm=dtmm/3;%合并mfcc参数和一阶差分mfcc参数ccc=[m dtm dtmm];%去除首尾两帧,因为这两帧的一阶差分参数为0ccc=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的函数了,

 

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是在Matlab中提取翻转梅尔频率倒谱系数MFCC)的示例代码: ```matlab % 读取音频文件 [y, Fs] = audioread('example.wav'); % 预处理:对信号进行预加重,使用高通滤波器 preemph = [1, -0.97]; y = filter(preemph, 1, y); % 帧分割:将信号分为若干个帧 frame_size = 0.025; % 帧长(单位:秒) frame_shift = 0.01; % 帧移(单位:秒) frame_length = frame_size * Fs; % 帧长(单位:采样点) frame_step = frame_shift * Fs; % 帧移(单位:采样点) num_frames = floor((length(y) - frame_length) / frame_step) + 1; frames = zeros(frame_length, num_frames); for i = 1:num_frames start_idx = (i-1) * frame_step + 1; frames(:, i) = y(start_idx : start_idx + frame_length - 1); end % 加窗:对每个帧进行汉明窗加窗 window = hamming(frame_length); frames = bsxfun(@times, frames, window); % 快速傅里叶变换:对每个帧进行FFT计算 NFFT = 512; fft_frames = fft(frames, NFFT, 1); % 能量谱:计算每个帧的能量谱 power_frames = abs(fft_frames).^2 / NFFT; % 梅尔滤波器组:计算梅尔滤波器组的系数 num_filters = 20; mel_low_freq = 0; % 梅尔滤波器组的最低频率 mel_high_freq = 2595 * log10(1 + (Fs/2) / 700); % 梅尔滤波器组的最高频率 mel_points = linspace(mel_low_freq, mel_high_freq, num_filters + 2); hz_points = 700 * (10.^(mel_points / 2595) - 1); bin = floor((NFFT + 1) * hz_points / Fs); fbank = zeros(num_filters, NFFT / 2 + 1); for m = 1:num_filters f_m_minus = bin(m); f_m = bin(m+1); f_m_plus = bin(m+2); for k = f_m_minus:f_m fbank(m, k+1) = (k - bin(m)) / (bin(m+1) - bin(m)); end for k = f_m:f_m_plus fbank(m, k+1) = (bin(m+2) - k) / (bin(m+2) - bin(m+1)); end end % 翻转梅尔频率倒谱系数:计算每个帧的MFCC num_ceps = 12; mfcc = zeros(num_ceps, num_frames); for i = 1:num_frames % 将能量谱乘以梅尔滤波器组的系数,得到每个滤波器的输出能量 filter_energies = fbank * power_frames(:, i); % 取对数,得到滤波器组的对数输出能量 log_filter_energies = log(filter_energies + eps); % 对上面的对数输出能量进行离散余弦变换(DCT) mfcc(:, i) = dct(log_filter_energies); % 取前 num_ceps 个系数作为MFCC mfcc(:, i) = mfcc(1:num_ceps, i); end % 翻转MFCC:对每个MFCC向量进行翻转 rfcc = flipud(mfcc); ``` 以上代码中,翻转MFCC的操作是通过 `flipud` 函数实现的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值