%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%% MFCC %%%%%%%%%%%%%%%%
function feature =mfcc(x,Fs)
%读取语音操作
%声音读取,Fs为采样率
%[x,Fs] = audioread('1.wav');
%语音预处理H(z)=1-uz^(-1)
z=filter([1 -0.9735], 1, double(x));
%分帧加窗
num=16/1000*Fs; %取窗大小,16ms:256
yframe=enframe(z,num,num/2); %enframe实现分帧
[row,col]=size(yframe); %一帧col个点,一共row帧
window1=hamming(num);%汉明窗
yframe1=yframe.*window1; %每一帧信号加汉明窗
%% 三角滤波器组
fs=Fs;
fl=0; fh=fs/2;
bl=1125*log(1+fl/700);%将频率转换为Mel频率
bh=1125*log(1+fh/700);
p=26;%滤波器个数
nfft=num;%FFT点数
B=bh-bl;
y=linspace(0,B,p+2);%产生0到B之间p+2个数
Fb=700*(exp(y/1125)-1);%将Mel频率转换为频率
W2=nfft/2+1;%fs/2内对应的FFT点数
df=fs/nfft;
freq=(0:W2-1)*df;%采样频率值
bank=zeros(26,W2);%生成一个26行W2列的全零数组
for k=2:p+1%why从2开始?因为k-1
f1=Fb(k-1); f2=Fb(k+1); f0=Fb(k);
n1=floor(f1/df)+1;
n2=floor(f2/df)+1;
n0=floor(f0/df)+1;
for i=1 : W2
if i>=n1 & i<=n0
bank(k-1,i)=(i-n1)/(n0-n1);
elseif i>n0 & i<=n2
bank(k-1,i)=(n2-i)/(n2-n0);
end
end
end
%傅里叶变换计算频谱,求出功率谱
yf=zeros(row,col);
for i=1:row
yf(i,:)=fft(yframe1(i,:),num);
mag(i,:)=abs(yf(i,:));
power(i,:)=mag(i,:).*mag(i,:);
power_bank(i,:)=bank*power(i,1:201)';
log_mag1(i,:)=log10(power_bank(i,:));
end
%DCT
for i=1:row
d(i,:)=dct(log_mag1(i,:)); %i指帧,即一行是一帧
end
d(any(isnan(d)'),:)=[]; %去掉所有含NaN的帧
feature=(d(:,1:13))';