matlab语言nftames,语言识别的matlab仿真程序

加QQ:1046233911

一、加窗和分帧函数

%

enframe.m 加窗和分帧分帧函数,用在语音处理中的。相当于加了一个移动的窗

% 一般调用格式为

% y=enframe(x,framelength,step);

nx=length(x);

nwin=length(win);

if (nwin == 1)

len = win;

else

len = nwin;

end

if (nargin < 3)

inc = len;

end

nf = fix((nx-len+inc)/inc);

f=zeros(nf,len);

indf= inc*(0:(nf-1)).';

inds = (1:len);

f(:) = x(indf(:,ones(1,len))+inds(ones(nf,1),:));

if (nwin > 1)

w =

win(:)';

f = f .*

w(ones(nf,1),:);

end

二、语音信号端点检测程序

function [x1,x2]=vad(k,fs,i)

%% [X1,X2]=vad(k,fs)

%% 语音信号端点检测程序,k为语音信号,

%% fs为其采样频率,程序绘制出语音信号

%% 相关波形图并返回起止端点所对帧号

%close all;

% 幅度归一化到[-1,1]

k=double(k);

k=k./max(abs(k)); % k>0,k=1;k<=-1.

%------------------------------

%

此处录取部分代码

(3,1,3);

plot(t1,k1);

axis([0.4,0.5,min(k),max(k)]);

z=sprintf('(III) “�.wav”语音结束处放大波形图',i);

title(z);

xlabel('Time:s');

ylabel('Amplitude(normalized)');

%------------------------------

% 计算短时过零率

%------------------------------

FrameLen=240;

FrameInc=80;

FrameTemp1=enframe(k(1:end-1),FrameLen,FrameInc);

FrameTemp2=enframe(k(2:end),FrameLen,FrameInc);

signs=(FrameTemp1.*FrameTemp2)<0;

diffs=abs(FrameTemp1-FrameTemp2)>0.01;

zcr=sum(signs.*diffs,2);

disp('显示原始波形图……');

figure,subplot(3,1,1);

plot(t,k);

axis([0,(length(k)-1)/fs,min(k),max(k)]);

z=sprintf('(I) “�.wav”语音信号波形',i);

title(z);

xlabel('Time:s');

ylabel('Amplitude(normalized)');

disp('显示过短时零率……')

zcrInd=1:length(zcr);

subplot(3,1,2);

plot(zcrInd,zcr);

axis([0,length(zcr),0,max(zcr)]);

title('(II) 短时过零率');

xlabel('Frame');

ylabel('Zcr');

%------------------------------

% 计算短时能量

%------------------------------

amp=sum(abs(enframe(filter([1 -0.9375], 1, k), FrameLen,

FrameInc)), 2);

disp('显示短时能量……')

ampInd=1:length(amp);

subplot(3,1,3);

plot(ampInd,amp);

axis([0,length(amp),0,max(amp)]);

title('(III) 短时能量');

xlabel('Frame');

ylabel('Energy');

%------------------------------

% 设置门限

%------------------------------

disp('设置门限……');

ZcrLow=max([round(mean(zcr)*0.1),3]); %过零率低门限

ZcrHigh=max([round(max(zcr)*0.1),5]); %过零率高门限

AmpLow=min([min(amp)*10,mean(amp)*0.2,max(amp)*0.1]); %能量低门限

AmpHigh=max([min(amp)*10,mean(amp)*0.2,max(amp)*0.1]); %能量高门限

%------------------------------

% 端点检测

%------------------------------

MaxSilence=8; %最长语音间隙时间

MinAudio=16; %最短语音时间

Status=0; %状态:0静音段,1过渡段,2语音段,3结束段

HoldTime=0; %语音持续时间

SilenceTime=0; %语音间隙时间

disp('开始端点检测……');

for n=1:length(zcr)

switch

Status

case{0,1}

if amp(n)>AmpHigh ||

zcr(n)>ZcrHigh

x1=n-HoldTime;

Status=2;

HoldTime=HoldTime+1;

SilenceTime=0;

elseif amp(n)>AmpLow ||

zcr(n)>ZcrLow

Status=1;

HoldTime=HoldTime+1;

此处略去部分代码

HoldTime=HoldTime+1;

else

SilenceTime=SilenceTime+1;

if SilenceTime

HoldTime=HoldTime+1;

elseif (HoldTime-SilenceTime)

Status=0;

HoldTime=0;

SilenceTime=0;

else

Status=3;

end

end

case 3,

break;

end

if

Status==3

break;

end

end

HoldTime=HoldTime-SilenceTime;

x2=x1+HoldTime;

disp('显示端点……');

figure,subplot(3,1,1);

plot(k);

axis([1,length(k),min(k),max(k)]);

z=sprintf('(I) “�.wav”语音信号',i);

title(z);

xlabel('Sample');

ylabel('Speech');

line([x1*FrameInc,x1*FrameInc],[min(k),max(k)],'color','red');

line([x2*FrameInc,x2*FrameInc],[min(k),max(k)],'color','red');

subplot(3,1,2);

plot(zcr);

axis([1,length(zcr),0,max(zcr)]);

title('(II) 短时过零率');

xlabel('Frame');

ylabel('ZCR');

line([x1,x1],[0,max(zcr)],'Color','red');

line([x2,x2],[0,max(zcr)],'Color','red');

subplot(3,1,3);

plot(amp);

axis([1,length(amp),0,max(amp)]);

title('(III) 短时能量');

xlabel('Frame');

ylabel('Energy');

line([x1,x1],[0,max(amp)],'Color','red');

line([x2,x2],[0,max(amp)],'Color','red');

三、计算MFCC系数

function cc=mfcc(k)

%------------------------------

% cc=mfcc(k)计算语音k的MFCC系数

%------------------------------

% M为滤波器个数,N为一帧语音采样点数

M=24; N=256;

% 归一化mel滤波器组系数

bank=melbankm(M,N,8000,0,0.5,'m');

figure;

plot(linspace(0,N/2,129),bank);

title('Mel-Spaced Filterbank');

xlabel('Frequency [Hz]');

bank=full(bank);

bank=bank/max(bank(:));

% DCT系数,12*24

for i=1:12

j=0:23;

dctcoef(i,:)=cos((2*j+1)*i*pi/(2*24));

end

% 归一化倒谱提升窗口

w=1+6*sin(pi*[1:12]./12);

w=w/max(w);

% 预加重

AggrK=double(k);

AggrK=filter([1,-0.9375],1,AggrK);

% 分帧

FrameK=enframe(AggrK,N,80);

% 加窗

for i=1:size(FrameK,1)

FrameK(i,:)=(FrameK(i,:))'.*hamming(N);

end

FrameK=FrameK';

% 计算功率谱

S=(abs(fft(FrameK))).^2;

disp('显示功率谱……')

figure;

plot(S);

axis([1,size(S,1),0,2]);

title('Power Spectrum (M=24, N=256)');

xlabel('Frame');

ylabel('Frequency [Hz]');

colorbar;

% 将功率谱通过滤波器组

P=bank*S(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,:)=-2*m(i-2,:)-m(i-1,:)+m(i+1,:)+2*m(i+2,:);

end

dtm=dtm/3;

%合并mfcc参数和一阶差分mfcc参数

cc=[m,dtm];

%去除首尾两帧,因为这两帧的一阶差分参数为0

cc=cc(3:size(m,1)-2,:);

四、计算MFCC时所需Mel尺度滤波器组

function [x,mn,mx]=melbankm(p,n,fs,fl,fh,w)

%MELBANKM determine matrix for a mel-spaced filterbank

[X,MN,MX]=(P,N,FS,FL,FH,W)

if nargin < 6

w='tz';

if nargin < 5

fh=0.5;

if nargin

< 4

fl=0;

end

end

end

f0=700/fs;

fn2=floor(n/2);

lr=log((f0+fh)/(f0+fl))/(p+1);

% convert to fft bin numbers with 0 for DC term

bl=n*((f0+fl)*exp([0 1 p p+1]*lr)-f0);

b2=ceil(bl(2));

此处略去部分代码

v=2*[0.5 ones(1,b2-1) 1-pf+fp pf-fp

ones(1,fn2-b3-1) 0.5];

mn=1;

mx=fn2+1;

else

b1=floor(bl(1))+1;

b4=min(fn2,ceil(bl(4)))-1;

pf=log((f0+(b1:b4)/n)/(f0+fl))/lr;

fp=floor(pf);

pm=pf-fp;

k2=b2-b1+1;

k3=b3-b1+1;

k4=b4-b1+1;

r=[fp(k2:k4) 1+fp(1:k3)];

c=[k2:k4 1:k3];

v=2*[1-pm(k2:k4) pm(1:k3)];

mn=b1+1;

mx=b4+1;

end

if any(w=='n')

v=1-cos(v*pi/2);

elseif any(w=='m')

v=1-0.92/1.08*cos(v*pi/2);

end

if nargout > 1

x=sparse(r,c,v);

else

x=sparse(r,c+mn-1,v,p,1+fn2);

end

五、DTW算法

function dist = dtw(test, ref)

global x y_min y_max

global t r

global D d

global m n

t = test;

r = ref;

n = size(t,1);

m = size(r,1);

d = zeros(m,1);

D = ones(m,1) * realmax;

D(1) = 0;

% 如果两个模板长度相差过多,匹配失败

if (2*m-n<3) | (2*n-m<2)

dist = realmax;

return

end

% 计算匹配区域

xa = round((2*m-n)/3);

xb = round((2*n-m)*2/3);

if xb>xa

%xb>xa, 按下面三个区域匹配

% 1 :xa

% xa+1:xb

% xb+1:N

for x = 1:xa

y_max = 2*x;

y_min = round(0.5*x);

warp

end

for x = (xa+1):xb

y_max = round(0.5*(x-n)+m);

y_min = round(0.5*x);

warp

end

for x = (xb+1):n

y_max = round(0.5*(x-n)+m);

y_min = round(2*(x-n)+m);

warp

end

elseif xa>xb

%xa>xb, 按下面三个区域匹配

% 0 :xb

% xb+1:xa

% xa+1:N

for x = 1:xb

y_max = 2*x;

y_min = round(0.5*x);

warp

end

for x = (xb+1):xa

y_max = 2*x;

y_min = round(2*(x-n)+m);

warp

end

for x = (xa+1):n

y_max = round(0.5*(x-n)+m);

y_min = round(2*(x-n)+m);

warp

end

elseif xa==xb

%xa=xb, 按下面两个区域匹配

% 0 :xa

% xa+1:N

for x = 1:xa

y_max = 2*x;

y_min = round(0.5*x);

warp

end

for x = (xa+1):n

y_max = round(0.5*(x-n)+m);

y_min = round(2*(x-n)+m);

warp

end

end

%返回匹配分数

dist = D(m);

function warp

global x y_min y_max

global t r

global D d

global m n

d = D;

for y = y_min:y_max

D1 = D(y);

if y>1

D2 = D(y-1);

else

D2 = realmax;

end

if y>2

D3 = D(y-2);

else

D3 = realmax;

end

d(y) =

sum((t(x,:)-r(y,:)).^2) + min([D1,D2,D3]);

end

D = d;

六、语音训练阶段程序

%% train.m

disp('正在生成训练参数……');

for i=0:3

fname=sprintf('train\\�.wav',i );

[k,fs]=wavread(fname);

[x1,x2]=vad(k,fs,i);

cc=mfcc(k);

cc=cc(x1-2:x2-2,:);

ref(i+1).mfcc=cc;

end

disp('正在存储模板库……');

save 'mfcc.mat' ref;

% close all;

clc;

七、基于DTW的语音识别程序

对test中所有语音进行识别

% test1.m

clear;

close all;

clc;

disp('正在导入参考模板参数...');

load mfcc.mat;

disp('正在计算测试模板的参数...')

for i=0:3

fname = sprintf('test\\�.wav',i);

[k,fs]=wavread(fname);

[x1,x2]=vad(k,fs,i);

cc=mfcc(k);

cc=cc(x1-2:x2-2,:);

test(i+1).mfcc=cc;

此处略去部分代码

dist(i,j) = dtw(test(i).mfcc, ref(j).mfcc);

end

end

disp('正在计算匹配结果...')

for i=1:4

[d,j] = min(dist(i,:)); % d为返回值,j为列数

if j==1

fprintf('测试模板 �.wav 的识别结果为:前进\n',i-1);end

if j==2

fprintf('测试模板 �.wav

的识别结果为:后退\n',i-1); end

if j==3

fprintf('测试模板 �.wav 的识别结果为:向左\n',i-1); end

if j==4

fprintf('测试模板 �.wav 的识别结果为:向右\n',i-1); end

end

close all;

对test文件夹中任一个语音进行识别

% test2.m

clear;

close all;

clc;

disp('正在导入参考模板参数...');

load mfcc.mat;

disp('正在计算测试模板的参数...')

i=1;

% i=2;

% i=3;

% i=4;

fname = sprintf('test\\�.wav',i-1);

[k,fs]=wavread(fname);

[x1,x2]=vad(k,fs,i-1);

cc=mfcc(k);

cc=cc(x1-2:x2-2,:);

test(i).mfcc=cc;

disp('正在进行模板匹配...');

dist = zeros(1,4);

for j=1:4;

dist(j)=dtw(test(i).mfcc,ref(j).mfcc);

end

disp('正在计算匹配结果...');

m=min(dist);

[row,column]=find(dist==m);

j=column;

if

j==1; fprintf('测试模板 �.wav 的识别结果为:前进\n',i-1); end

if

j==2; fprintf('测试模板 �.wav

的识别结果为:后退\n',i-1); end

if

j==3; fprintf('测试模板 �.wav

的识别结果为:向左\n',i-1); end

if

j==4; fprintf('测试模板 �.wav

的识别结果为:向右\n',i-1); end

% close all;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值