声音特征提取-MFCC详解
*****************废话
近来一直想找一篇讲解详尽的文章,奈何文章要么侧重于理论知识,要么对代码部分难以理解(对于新手而言带注释的部分同样令人费解)。经过 prolonged time of thinking and researching,终于能够大致通读并理解其中的一些内容,在此处打算做一个总结和笔记,同时为那些渴望深入了解这一领域的读者提供参考意见。欢迎大家一起交流探讨这个话题,等到 readers们都能大致掌握这个知识点时,则是我们及所有分享者的共同收获了。
****************正题
所谓声音特征提取是什么?我们需要从中获取哪些信息?在提取过程中需要完成哪些步骤?为什么要这样做?这些我不愿涉及;很多已经比我完善。
我的主要目标是通过明确参数来实现功能。我的应用范围仅限于基础操作。其中一些函数比如audioread()等可以在官方文档中的帮助信息中找到详细指导。这些参数的具体设置则应基于具体应用场景进行优化调整。
不墨迹了,还是直接上代码了,原理自己去看吧
预处理比较全的一篇
求参比较全的一篇
原理讲解最细致的
*****************代码分析
第一步:读取声音文件
通过调用audioread函数获取音频数据和采样频率 [sampledata,FS] 后,请根据实际情况调整并建议将文件路径替换为自己的文件路径就可以。
第二步:(如果是双声道,在采集过程中不要自行使用样本文件,并且不必对自己播放复杂的设置)建议切换到双声模式。
道变成单声道。这一部分没有需要咱们做的,不用懂,记得做就可以了。
subroutine sample is defined as calsample with parameters sampledata and FS
[m,n] = size(temp_sample);
if (n == 2)
sample = temp_sample(:,1);
else
sample = temp_sample;
end end
第三步:归一化mel滤波器系组数
bank=melbankm(M,N,fs,0,0.5,'m'); % M:滤波器数量 N:一帧采样个数 fs:前边函数计算得到
该函数自行查看此处:http://www.ee.ic.ac.uk/hp/staff/dmb/voicebox/doc/voicebox/melbankm.html
bank=full(bank);
bank=bank/max(bank(:));
第四步:求dct系数 (此为12*23)
补充一下DCT:离散余弦变换,舍弃高频部分,保留低频,为了进行压缩。
滤波器的数目为^{^{^{^{}}}}个,在本系统中设定的数据维度为^{^{}};经过处理后将获得一维至十二维的基础数据;加入一阶差分处理后将使维度扩展为一维至二十四维;最终生成的数据将被组织成一个由用户的输入数据集构建的N\times ^{^{}}矩阵(可用于后续分类模型训练使用)。
for i=1:12
j=0:23;
dctcoef(i,:)=cos((2j+1)ipi/(224));
end
第五步: 一部分预处理操作
% 预加重
AggrK=double(sampledata); % sampledata:读取文件时得到的
AggrK=filter([1,-0.9375],1,AggrK);
% 分帧 % N个点放在一帧,将128个点重叠
FrameK=enframe(AggrK,N,128);
% 加窗 % 对点N加hamming窗(多种)
for i=1:size(FrameK,1)
FrameK(i,:)=(FrameK(i,:))'.*hamming(N);
end
FrameK=FrameK';
第六步: 离散傅里叶变换
归一化倒谱加窗处理方法中引入窗函数w以增强MFCC频谱特征提取效果。其中w表示窗函数其主要目标是对MFCC中的特定频谱峰进行增强处理以优化特征提取效果。具体实现通过以下公式确定:
w = 1 + 6 \cdot \sin\left(\pi \cdot \frac{[1:12]}{12}\right);
其中系数计算采用归一化处理:
w = w / \max(w);
t=abs(fft(s)); % 傅里叶快速变换算法
t=t.^2;
P=bank*t(1:129,:); % 将功率谱通过滤波器
%取对数后做离散变换
D=dctcoef*log(P);
for i=1:size(D,2)
m(i,:)=(D(:,i).*w')';
end
第七步:差分方程
在将视频中的每一帧转换为连续的过程时,在每相邻三帧中计算当前帧与其前后各一帧之间的十三个特征差异
(十二个倒谱特征加一个能量特征)
dtm=zeros(size(m));
for i=3:size(m,1)-2
dtm(i,:)=-2m(i-2,:)-m(i-1,:)+m(i+1,:)+2m(i+2,:);
end
dtm=dtm/3;
需要可以再求二阶的
第八步:得到MFCC向量
%合并mfcc参数和一阶差分mfcc参数
cc=[m,dtm];
%去除首尾两帧,因为这两帧的一阶差分参数为0
cc=cc(3:size(m,1)-2,:);
