基于MATLAB的语音信号的时域特性分析(二)——短时能量、短时平均过零率

  语音信号分帧以后,可以在时域中处理,也可以在频域中处理。这里主要介绍时域处理中提取语音信号的特性。
  设语音波形时域信号为 x ( n ) 、加窗函数 w ( n ) 分帧处理后得到的第i帧语音信号为 y i ( n ) ,则 y i ( n ) 满足:

y i ( n ) = w ( n ) x ( ( i 1 ) i n c + n ) , 1 n L , 1 i f n

式中, w ( n ) 为窗函数,一般为矩形窗或汉明窗; y i ( n ) 是一帧的数值, n = 1 , 2 , L , i = 1 , 2 , f n L 为帧长;inc为帧移长度;fn为分帧后的总帧数。

1、短时能量

   计算第i帧语音信号 y i ( n ) 的短时能量公式为

E ( i ) = n = 0 L 1 y i 2 ( n ) , 1 i f n

具体代码如下:

% 短时能量
filedir=[];                % 设置路径
filename='F:\音频\wav\MORSE.wav';   % 设置文件名
fle=[filedir filename];    % 构成完整的路径和文件名
[x,Fs]=wavread(fle);       % 读入数据文件

wlen=200; inc=80;          % 给出帧长和帧移
win=hanning(wlen);         % 给出海宁窗
N=length(x);               % 信号长度
X=enframe(x,win,inc)';     % 分帧
fn=size(X,2);              % 求出帧数
time=(0:N-1)/Fs;           % 计算出信号的时间刻度
for i=1 : fn
    u=X(:,i);              % 取出一帧
    u2=u.*u;               % 求出能量
    En(i)=sum(u2);         % 对一帧累加求和
end
subplot 211; plot(time,x); % 画出时间波形 
title('MORSE语音波形');
ylabel('幅值'); xlabel(['时间/s' 10 '(a)']);
frameTime=frame2time(fn,wlen,inc,Fs);   % 求出每帧对应的时间
subplot 212; plot(frameTime,En)     % 画出短时能量图
title('短时能量');
ylabel('幅值'); xlabel(['时间/s' 10 '(b)']);

运行程序后求出的短时能量图如图所示:
这里写图片描述
附: 程序中调用了frame2time函数,用于计算分帧后每一帧对应的时间。具体代码如下:

function frameTime=frame2time(frameNum,framelen,inc,fs)
% 分帧后计算每帧对应的时间
frameTime=(((1:frameNum)-1)*inc+framelen/2)/fs;

2、短时平均过零率

  短时平均过零率表示一帧语音中语音信号波形穿过横轴(零点平)的次数。对于联系语音信号,过零即意味着时域波形通过时间轴;而对于离散信号,如果相邻的取样值改变符号,则称为过零。短时平均过零率就是样本数值改变符号的次数。
  短时平均过零率为

Z ( i ) = 1 2 n = 0 L 1 | s g n [ y i ( n ) ] s g n [ y i ( n 1 ) ] | , 1 i f n

式中, s g n [ ] 是符号函数,即

这里写图片描述

  理论上短时平均过零率是按上式计算,而在MATLAB编程中,却用另一种方法。按上述过零的描述,即离散信号相邻的取样值改变符号,那它们的乘积一定为负数,即
y i ( n ) y i ( n + 1 ) < 0

具体代码如下:

%短时平均过零率
filedir=[];                       % 设置路径
filename='F:\音频\wav\MORSE.wav';          % 设置文件名
fle=[filedir filename];           % 构成完整的路径和文件名
[xx,Fs]=wavread(fle);             % 读入数据文件
x=xx-mean(xx);                    % 消除直流分量
wlen=200; inc=80;                 % 设置帧长、帧移
win=hanning(wlen);                % 窗函数
N=length(x);                      % 求数据长度
X=enframe(x,win,inc)';            % 分帧
fn=size(X,2);                     % 获取帧数
zcr1=zeros(1,fn);                 % 初始化
for i=1:fn
    z=X(:,i);                     % 取得一帧数据
    for j=1: (wlen- 1) ;          % 在一帧内寻找过零点
         if z(j)* z(j+1)< 0       % 判断是否为过零点
             zcr1(i)=zcr1(i)+1;   % 是过零点,记录1次
         end
    end
end
time=(0:N-1)/Fs;                  % 计算时间坐标
frameTime=frame2time(fn,wlen,inc,Fs);  % 求出每帧对应的时间
% 作图
subplot 211; plot(time,x); grid;
title('MORSE语音波形');
ylabel('幅值'); xlabel(['时间/s' 10 '(a)']);
subplot 212; plot(frameTime,zcr1); grid;
title('短时平均过零率');
ylabel('幅值'); xlabel(['时间/s' 10 '(b)']);

运行程序后求出的短时平均过零率如图所示:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_39516859/article/details/80166842