天天看点

matlab z变换离散化_音频特征MFCC提取的MATLAB实现

从《法证先锋4》的一段剧情说起

在港剧《法证先锋4》第9集中,有一段剧情是这样的:家希的朋友Monica被网络上的一段视频诬陷送外卖上门,于是找到了声纹专家做声纹鉴别、出具专家报告,证明视频中的声音不属于Monica。

至于具体的操作,剧中原话是这样的:

matlab z变换离散化_音频特征MFCC提取的MATLAB实现

MFCC(梅尔频率倒谱系数)除了可以像剧中那样用来做声纹鉴定,更广泛的用途是进行音乐风格分类、音乐检索和语音识别等。那么MFCC到底是什么东西?

MFCC概述

梅尔频率倒谱系数(Mel-scale Frequency Cepstral Coefficients,简称MFCC)是在Mel标度频率域提取出来的倒谱参数。Mel标度描述了人耳频率的非线性特性,它与频率的关系可用下式近似表示:

matlab z变换离散化_音频特征MFCC提取的MATLAB实现

式中f为频率,单位为Hz。

MFCC提取过程及MATLAB实现

要得到一段音频的MFCC,需要经过以下步骤:

matlab z变换离散化_音频特征MFCC提取的MATLAB实现

接下来会给每个步骤的详细介绍以及对应的MATLAB代码。

0、读取音频

这一步比较简单了,直接上代码:

[
           

要注意的是,如果音频文件是双声道,可以转换成单声道进行处理。

1、预加重

将音频信号通过一个高通滤波器,用来增强高频信息:

matlab z变换离散化_音频特征MFCC提取的MATLAB实现

μ的取值在0.9-1.0之间,一般取为0.97。

代码如下:

x
           

2、分帧

在前面提到过,MFCC是在Mel标度频率域上提取出来的。Mel标度可以由频率得到。如果我们直接对音频进行傅里叶变换,就只能得到整段音频的频谱,没办法观察频谱随时间变化的情况。为此,我们需要把音频切成一小段一小段,每一小段称为一帧。之后再对每小段进行傅里叶变换,这样就可以得到随时间变化的频谱了。每一段的频谱拼起来就是所谓的“声谱图”(spectrogram)。

我们通常取20~30ms为一帧。假设声音的采样频率为44.1kHz,一帧长20ms,那么一帧的采样点个数为44100*20/1000=882。为了保证两帧声音之间的差异不大,通常帧与帧之间还存在重叠部分。重叠部分占比称为“重叠率”,一般为1/2~1/3。本文的MATLAB代码取1/2。

matlab z变换离散化_音频特征MFCC提取的MATLAB实现

分帧操作示意图

这段代码需要用到MATLAB的voicebox工具箱。

x
           

3、加窗

为了增加帧左端和右端的连续性,也为了避免频谱泄露,需要对每一帧的音频信号乘上窗函数。这个过程叫“加窗”。通常情况下窗函数选取的是“汉明窗”。假设N为帧的大小,汉明窗W(n)公式为

matlab z变换离散化_音频特征MFCC提取的MATLAB实现

不同的a值会产生不同的汉明窗,一般情况下a取0.46。将a=0.46代入上式得:

matlab z变换离散化_音频特征MFCC提取的MATLAB实现

具体代码如下:

s
           

4、FFT(快速傅里叶变换)

加窗后的音频经过FFT后就可以得到频谱。FFT可以由离散傅里叶变换(DFT)的公式,利用周期性和对称性的性质推导出来。这里不再赘述。

顺便说一句,

分帧、加窗、FFT

这三个操作合起来是一种数字信号处理技术——

STFT(短时傅里叶变换)

。利用STFT可以观察音频在不同时间的频率分布。

对音频信号的频谱取模平方得到语音信号的功率谱。在具体实现中,也可以对频谱直接取绝对值而不作平方,这样得到的是能量谱。本文的MATLAB代码求得的是功率谱。

具体代码如下:

t
           

5、通过Mel滤波器组

将功率谱通过一组Mel尺度的三角带通滤波器组。这个滤波器组有M个三角带通滤波器,它们的中心频率为f(m),m=1,2,...,M。M通常取22-26,本文取24。各f(m)之间的间隔随着m值的减小而缩小,随着m值的增大而增宽,如图所示:

matlab z变换离散化_音频特征MFCC提取的MATLAB实现

Mel频率滤波器组,图中M=6

三角带通滤波器有两个主要目的:

对频谱进行平滑化,并消除谐波的作用,突显原先语音的共振峰。(因此一段语音的音调或音高,是不会呈现在 MFCC 参数内。在《法证先锋4》中,也有相应的台词说明这一点。)

生成Mel滤波器组的具体代码如下:

bank
           

6、取对数

计算每个滤波器组输出的对数能量,即子带能量

matlab z变换离散化_音频特征MFCC提取的MATLAB实现

这一步的MATLAB代码和下一步的放在一起。

7.DCT(离散余弦变换)

直接使用下列公式进行计算:

matlab z变换离散化_音频特征MFCC提取的MATLAB实现

将第6步求得的结果代入离散余弦变换,求出L个MFCC系数,L通常取12-16。本文取12。

6、7步具体代码如下:

for 
           

有的人可能会疑惑,为什么功率谱有这么多的点,只取出1+floor(N/2)个点进行计算?其实这些点是功率谱的正半侧(可以调用MATLAB的fftshift函数对功率谱进行处理后,再观察),我们的Mel滤波器组只需要正半侧的数据。

这样,最基本的12维MFCC的系数已经提取出来了。

完整MATLAB程序如下:

[
           

在此基础上,后续还有倒谱提升公式、MFCC一阶差分系数、MFCC二阶差分系数等。这里不再赘述。

继续阅读