精心设计的基于MATLAB的代码设计
主程序:
%
fs=22050; %抽样频率 x=wavread('2.wav');
figure(1);subplot(211);plot(x);
title('原始语音信号波
形','fontsize',16,'fontweight','bold'); xlabel('样点数
','fontsize',16,'fontweight','bold');
ylabel('幅值','fontsize',16,'fontweight','bold');grid on; N=128; n=0:N-1; y=fft(x); mag=abs(y);
f=(0:length(y)-1)'*fs/length(y);%进行对应的频率转换
figure(1);subplot(212);plot(f,mag);
title('原始信号频谱图','fontsize',16,'fontweight','bold'); xlabel('频率(Hz)','fontsize',16,'fontweight','bold'); ylabel('幅值','fontsize',16,'fontweight','bold');grid on;
y=wavread('2.wav');
%预加重
figure();subplot(211);plot(x); xlabel('样点数
','fontsize',16,'fontweight','bold');
ylabel('原始波形(幅值)','fontsize',16,'fontweight','bold'); xx=double(y);
subplot(212);plot(xx); xlabel('样点数','fontsize',16,'fontweight','bold');
ylabel('预加重波形(幅值)','fontsize',16,'fontweight','bold');
%对指定帧位置进行加窗处理 Q=y';
N=256;%窗长
Hamm=hamming(N);%加窗(汉明窗) Rect=rectwin(N);%加窗(矩形窗) frame=60;%需要处理的帧位置
M=Q(((frame-1)*(N/2)+1):((frame-1)*(N/2)+N));
Frame=M.*Hamm';%加窗后的语音帧 frame=M.*Rect';
figure();subplot(211);plot(Frame); ylabel('汉明窗
','fontsize',16,'fontweight','bold'); subplot(212);plot(frame); ylabel('矩形窗
','fontsize',16,'fontweight','bold');
%语音信号分帧
figure();subplot(211);plot(y);
xlabel('样点数','fontsize',16,'fontweight','bold');
ylabel('原始','fontsize',16,'fontweight','bold'); y=enframe(y,256,80);
subplot(212);plot(y);xlabel('帧数','fontsize',16,'fontweight','bold');
ylabel('分帧','fontsize',16,'fontweight','bold');
%端点检测
[x1,x2]=vad(x);%调用函数vad实现
%浊音, 取13270--13510个点 %短时自相关函数 temp=y(13271:13510); Rn1=zeros(1,240); for nn=1:240
for ii=1:240-nn
Rn1(nn)=Rn1(nn)+temp(ii)*temp(nn+ii); end end
figure(6);
subplot(211);jj=1:240;plot(jj,Rn1,'b');title('浊音自相关函数','fontsize',16,'fontweight','bold');
xlabel('帧数','fontsize',16,'fontweight','bold'); ylabel('短时自相关函数
精心设计的基于MATLAB的代码设计
','fontsize',16,'fontweight','bold');grid on;
%清音, 取12120--12360个点 %短时自相关函数 temp=y(12121:12360); Rn2=zeros(1,240); for nn=1:240
for ii=1:240-nn
Rn2(nn)=Rn2(nn)+temp(ii)*temp(nn+ii); end end
figure(6);
subplot(212);jj=1:240;plot(jj,Rn2,'b'); title('清音自相关函
数
','fontsize',16,'fontweight','bold');
xlabel('帧数','fontsize',16,'fontweight','bold'); ylabel('短时自相关函数','fontsize',16,'fontweight','bold');grid on;
分帧功能子程序:
function f=enframe(x,win,inc)
% F = ENFRAME(X,LEN) splits the vector X(:) up into
% frames. Each frame is of length LEN and occupies
% one row of the output matrix. The last few frames of X
% will be ignored if its length is not divisible by LEN.
% It is an error if X is shorter than LEN.
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(x) % [x]=audioread('1.wav');
%幅度归一化到[-1,1] x = double(x);
x = x / max(abs(x));
%常数设置
FrameLen = 240; FrameInc = 80;
amp1 = 10; amp2 = 2; zcr1 = 10; zcr2 = 5;
maxsilence = 8; % 6*10ms = 30ms minlen = 15; % 15*10ms = 150ms status = 0; count = 0; silence = 0;
%计算过零率
tmp1 = enframe(x(1:end-1), FrameLen, FrameInc);
tmp2 = enframe(x(2:end) , FrameLen, FrameInc);
signs = (tmp1.*tmp2)<0; diffs = (tmp1 -tmp2)>0.02; zcr = sum(signs.*diffs, 2);
精心设计的基于MATLAB的代码设计
%计算短时能量
amp = sum(abs(enframe(filter([1 -0.9375], 1, x), FrameLen, FrameInc)), 2);
%调整能量门限
amp1 = min(amp1, max(amp)/4); amp2 = min(amp2, max(amp)/8);
%开始端点检测 x1 = 0; x2 = 0;
for n=1:length(zcr) goto = 0; switch status
case {0,1} % 0 = 静音, 1 = 可能开始
if amp(n) > amp1 % 确信进入语音段
x1 = max(n-count-1,1); status = 2; silence = 0;
count = count + 1;
elseif amp(n) > amp2 | ... % 可能处于语音段
zcr(n) > zcr2 status = 1;
count = count + 1;
else % 静音状态
status = 0; count = 0; end
case 2, % 2 = 语音段
if amp(n) > amp2 | ... % 保持在语音段
zcr(n) > zcr2
count = count + 1;
else % 语音将结束
silence = silence+1;
if silence < maxsilence % 静音还不够长,尚未结束
count = count + 1;
elseif count < minlen % 语音长度太短,认为是噪声 status = 0; silence = 0; count = 0;
else % 语音结束
status = 3; end end case 3, break; end end
count = count-silence/2; x2 = x1 + count -1;
figure(); subplot(311) plot(x)
axis([1 length(x) -1 1]) ylabel('Speech');
line([x1*FrameInc x1*FrameInc], [-1 1], 'Color', 'red');
line([x2*FrameInc x2*FrameInc], [-1 1], 'Color', 'red');
subplot(312) plot(amp);
axis([1 length(amp) 0 max(amp)]) ylabel('Energy');
line([x1 x1], [min(amp),max(amp)], 'Color', 'red');
line([x2 x2], [min(amp),max(amp)], 'Color', 'red');
subplot(313) plot(zcr);
axis([1 length(zcr) 0 max(zcr)]) ylabel('ZCR');
line([x1 x1], [min(zcr),max(zcr)], 'Color', 'red'); line([x2 x2], [min(zcr),max(zcr)], 'Color', 'red');