由于语音信号的特性随时间的变化是缓慢的,因而可以将其分成相继的短段进行处理,这种短段一般长10~30ms,成为帧,相邻短段可以有部分重叠,这种处理方法称为短时处理方法。
分帧用可以移动的有限长度的窗口进行加权的方法实现,如:直角窗、汉明窗等。
① 加窗
clc
clear all
close all
N=32;nn=0:(N-1);
subplot(311);
w = ones(N,1); %矩形窗实现
stem(nn,w)
xlabel('点数');ylabel('幅度');title('(a)矩形窗')
subplot(312);
w = 0.54 - 0.46*cos(2*pi*(0:N-1)'/(N-1)); %汉明窗实现
stem(nn,w)
xlabel('点数');ylabel('幅度');title('(b)汉明窗')
subplot(313)
w = 0.5*(1 - cos(2*pi*(0:N-1)'/(N-1))); %汉宁窗实现
stem(nn,w)
xlabel('点数');ylabel('幅度');title('(c)汉宁窗')
结果:
②分帧
clc
clear all
close all
[x,Fs]=audioread('C3_1_y.wav'); % 读入数据文件
wlen=200; inc=100; % 给出帧长和帧移
N=length(x); % 信号长度
time=(0:N-1)/Fs; % 计算出信号的时间刻度
signal=enframe(x,wlen,inc)'; % 分帧
i=input('请输入起始帧号(i):');
tlabel=i;
subplot 411; plot((tlabel-1)*inc+1:(tlabel-1)*inc+wlen,signal(:,tlabel),'b'); axis tight% 画出时间波形
xlim([(i-1)*inc+1 (i+2)*inc+wlen])
ylim([-0.1,0.1])
title(['(a)当前波形帧号:', num2str(i)]);
ylabel('幅值'); xlabel('帧长');
tlabel=i+1;
subplot 412; plot((tlabel-1)*inc+1:(tlabel-1)*inc+wlen,signal(:,tlabel),'b'); axis tight% 画出时间波形
xlim([(i-1)*inc+1 (i+2)*inc+wlen])
ylim([-0.1,0.1])
title(['(b)当前波形帧号:', num2str(i+1)]);
ylabel('幅值'); xlabel('帧长');
tlabel=i+2;
subplot 413; plot((tlabel-1)*inc+1:(tlabel-1)*inc+wlen,signal(:,tlabel),'b'); axis tight% 画出时间波形
xlim([(i-1)*inc+1 (i+2)*inc+wlen])
ylim([-0.1,0.1])
title(['(c)当前波形帧号:', num2str(i+2)]);
ylabel('幅值'); xlabel('帧长');
tlabel=i+3;
subplot 414; plot((tlabel-1)*inc+1:(tlabel-1)*inc+wlen,signal(:,tlabel),'b'); axis tight% 画出时间波形
xlim([(i-1)*inc+1 (i+2)*inc+wlen])
ylim([-0.1,0.1])
title(['(d)当前波形帧号:', num2str(i+3)]);
ylabel('幅值'); xlabel('帧长');
% 分帧函数
function frameout=enframe(x,win,inc)
nx=length(x(:)); % 取数据长度
nwin=length(win); % 取窗长
if (nwin == 1) % 判断窗长是否为1,若为1,即表示没有设窗函数
len = win; % 是,帧长=win
else
len = nwin; % 否,帧长=窗长
end
if (nargin < 3) % 如果只有两个参数,设帧inc=帧长
inc = len;
end
nf = fix((nx-len+inc)/inc); % 计算帧数
frameout=zeros(nf,len); % 初始化
indf= inc*(0:(nf-1)).'; % 设置每帧在x中的位移量位置
inds = (1:len); % 每帧数据对应1:len
frameout(:) = x(indf(:,ones(1,len))+inds(ones(nf,1),:)); % 对数据分帧
if (nwin > 1) % 若参数中包括窗函数,把每帧乘以窗函数
w = win(:)'; % 把win转成行数据
frameout = frameout .* w(ones(nf,1),:); % 乘窗函数
end
结果: