3.短时时域处理
3.1 短时能量
设语音波形时域信号为x(n)、加窗函数w(n)分帧处理后得到的第i帧语音信号为yi(n),则yi(n)满足
KaTeX parse error: Undefined control sequence: \leqsl at position 58: … 1 \leqslant n \̲l̲e̲q̲s̲l̲
̲ant L, \quad 1 …
式中,w(n)为窗函数,一般为矩形窗或汉明窗;yi(n)是一帧的数值,n=1,2…,L,i=1,
2…,fn,L为帧长;inc为帧移长度;fn为分帧后的总帧数。
计算第i帧语音信号yi(n)的短时能量公式为
例:读入语音文件C2_2_y.wav(内容为"我,到,北,京,去")中的数据,计算能量谱
实现代码
%语音分帧,平画出它的短时能量谱
clear all; clc;
close all;
[x,Fs]=audioread('C2_2_y.wav'); % 读入数据文件
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,'b'); % 画出时间波形
title('语音波形');
ylabel('幅值'); xlabel(['时间/s' 10 '(a)']);
frameTime=frame2time(fn,wlen,inc,Fs); % 求出每帧对应的时间
subplot 212; plot(frameTime,En,'k') % 画出短时能量图
title('短时能量');
ylabel('幅值'); xlabel(['时间/s' 10 '(b)']);
运行结果
程序中调用了frame2time函数,用于计算分帧后每一帧对应的时间。
名称:frame2time
功能:计算分帧后每一帧对应的时间
调用格式:frameTime=frame2time(framelum,framelen,inc,fs)
说明:输入参数framelNum是总帧数;framelen是帧长;inc是帧移;fs是采样频率.输出参数frameTime是每帧的时间,即取这一帧数据中间位置的时间.
语音信号的平均幅度定义为
M(i)也是一帧语音信号能量大小的表征,它与E(i)的区别在于计算时不论采样值的大小,不会因取二次方而造成较大差异,在某些应用领域中会带来一些好处.
短时能量和短时平均幅度函数的主要用途有:
区分浊音段与清音段,因为浊音时E(i)值比清音时大得多;
区分声母与韵母的分界和无话段与有话段的分界
3.2短时平均过零率
短时平均过零率表示一帧语音中语音信号波形穿过横轴(零电平)的次数。过零率分析是语音时域分析中最简单的一种。对于连续语音信号,过零即意味着时域波形通过时间轴;而对于离散信号,如果相邻的取样值改变符号,则称为过零。短时平均过零率就是样本数值改变符号的次数。
定义语音信号x(n)分帧后有yi(n),帧长为L,短时平均过零率为
理论上平均过零率按上式计算,但在MATLAB中,可表示为离散信号相邻的取样值改变符号,那么它们的乘积为负数
将语音信号分帧,分帧后的数组为X,其中每列数据表示一帧的数值,帧长为wlen,用zcr表示短时平均过零率
实现代码
zcr=zeros(1,fn); %初始化
fori=1:fn
z=X(:,i); %取得一帧数据
forj=1:(wlen-1); %在一帧内寻找过零点
if z(j)*z(j+1)<0 %判断是否为过零点
zcr(i)=zcr(i)+1; %是过零点,记录1次
end
end
end
例 读入语音文件C2_2_y.wav(内容为“我,到,北,京,去”)中的数据,分帧后计算短时平均过零率。
实现代码
%短时平均过零率
clear all; clc; close all;
[xx,Fs]=audioread('C2_2_y.wav'); % 读入数据文件
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,'b'); grid;
title('语音波形');
ylabel('幅值'); xlabel(['时间/s' 10 '(a)']);
subplot 212; plot(frameTime,zcr1,'k'); grid;
title('短时平均过零率');
ylabel('幅值'); xlabel(['时间/s' 10 '(b)']);
运行结果
通过分析语音信号发现,发浊音时,尽管声道有若干共振峰,但由于声门波引起谱的高频跌落;而发清音时,多数能量出现在较高频率上。因为高频意味着高的短时平均过零率,低频意味着低的平均过零率,所以认为,浊音时具有较低的过零率,而清音时具有较高的过零率(相当于白噪声)。这种高仅是相对而言的,没有精确的数值关系。
应用短时平均过零率的作用
利用短时平均过零率可以从背景噪声中找出语音信号,可用于判断寂静无话段与有话段的起点和终点位置。
在背景噪声较小时,用平均能量识别较为有效
在背景噪声较大时,用短时平均过零率识别较为有效
主要应用短时平均过零率来判别清音和浊音、有话段与无话段
3.3短时自相关函数
1.自相关函数的定义和性质
能量有限信号x(n)的自相关函数定义为
如果x(n)是随机或周期性的离散信号,不是能量有限的,则其相关函数定义为
信号的自相关函数具有以下性质
①偶函数特性:Ф(k)=Ф((一k).
②| Ф(k)|<|Ф(0)|,即零延迟的自相关值最大.
③若x(n)为能量有限信号,则其能量即为Ф(0);若x(n)为随机信号或周期性信号,则Ф(0)为其平均功率.
④如果x(n)是周期性信号,则Ф(k)也是周期性信号,并且其周期与x(n)的周期相同.
2.短时自相关函数的定义和性质
自相关函数具有一些性质(如它是偶函数;假设序列具有周期性,则其自相关函数也是同周期的周期函数等)。对于浊音语音可以用自相关函数求出语音波形序列的基音周期。在进行语音信号的线性预测分析时,也要用到自相关函数。语音信号x(m)的短时自相关函数R(k))的计算式如下:
其中N表示为语音分帧的长度,K表示最大延迟数
短时自相关函数具有以下性质:
(1)如果Xn(m)是周期的(设周期为Np),则自相关函数是同周期的周期函数,即Rn(k)=Rn(k+Np)
(2)Rn(k)是偶函数,即Rn(k)+Rn(-k)
(3)当k=0时,自相关函数具有最大值,即Rn(0)>=| Rn(k) |,并且Rn(0)为信号序列的能量或随机性序列的平均功率
语音信号的自相关函数主要应用于端点检测和基音的提取,在韵母基音频率整数倍处将出现峰值特性,通常根据除Rτ(0)外的第一峰值点来估计基音,而在声母的短时自相关函数中看不到明显的峰值。
若已知分帧后的数据在 中,则取每一帧的数据都可以来做短时自相关函数的分析:
u=X(:,i); %取出一帧
R=xcorr(u); %利用xcorr函数求出自相关函数
R=R(wlen:end); %只取k值为正值的自相关函数
例,实现一段语音信号的短时自相关(使用汉宁窗窗函数的情况,读取“我,到,北,京, 去”,设置帧长为200,帧移为80
实现代码
%短时自相关函数
clear all; clc; close all;
[Y,Fs]=audioread('C2_2_y.wav'); % 读入数据文件
x=Y-mean(Y); % 消除直流分量
wlen=200; inc=80; % 设置帧长、帧移
win=hanning(wlen); % 窗函数设置为汉宁窗
N=length(x); % 求数据长度
X=enframe(x,win,inc)'; % 分帧
xn=X(:);
Ac1=STAc(X); %计算短时自相关函数
Ac1=Ac1(:);
time=(0:N-1)/Fs; % 计算时间座标
% 作图
subplot 211;
plot(xn,'b'); grid;
title('语音波形');
ylabel('幅值'); xlabel(['时间/s' 10 '(a)']);
subplot 212;
plot(Ac1,'k');
grid;
title('短时自相关函数');
ylabel('幅值'); xlabel(['时间/s' 10 '(b)']);
%定义短时自相关函数
function y=STAc(X)
y=zeros(size(X));
fn=size(X,2); %求出帧数
wlen=size(X,1); %求帧长
for i=1:fn
u=X(:,i); %取出一帧
R=xcorr(u); %短时自相关计算
y(:,i)=R(wlen,end); %只取k为正值的自相关函数
end
end
运行结果
3.4短时平均幅度差
短时自相关函数是语音信号时域分析的重要参量。
但是计算自相关函数的计算量很大,其乘法运算所需时间较长。利用FFT等简化计算方法都无法避免乘法运算。为了避免乘法,一个简单的方法就是利用差值。所以采用另一种与自相关函数有类似作用的参量,即短时平均幅度差函数。
平均幅度差函数代替自相关函数进行语音分析的原因是:如果信号是完全的周期信号(设周期为Np),则相距为周期的整数倍的样点上的幅值是相等的,差值为零。
对于实际的语音信号,d(n)虽不为零,但其值很小。这些极小值将出现在整数倍周期的位置上。为此,可定义短时平均幅度差函数:
平均幅度差函数和自相关函数有密切的关系,两者之间的关系可由下式表达:
β(k)对不同的语音段在0.6-1.0之间变化,但是对一个特定的语音段,它随k值变化并不明显。
显然,计算Fn(k)只需加、减法和取绝对值的运算,与自相关函数的加法与乘法相比,其运算量大大减少,尤其在用硬件实现语音信号分析时有很大好处。
例,实现一段语音信号的短时平均幅度差(使用汉宁窗窗函数的情况,读取“我,到,北,京, 去”,设置帧长为200,帧移为100
实现代码
%短时平均幅度差
clear all; clc; close all;
[Y,Fs]=audioread('C2_2_y.wav'); % 读入数据文件
wlen=200; inc=100; % 设置帧长、帧移
win=hanning(wlen); % 窗函数设置为汉宁窗
N=length(Y); % 求数据长度
X=enframe(Y,win,inc)'; % 分帧
xn=X(:);
Amdf=STAmdf(X); %计算短时幅度差
Amdf=Amdf(:);
time=(0:N-1)/Fs; % 计算时间座标
% 作图
subplot 211;
plot(xn,'b'); grid;
title('语音波形');
ylabel('幅值'); xlabel(['点数' 10]);
subplot 212;
plot(Amdf,'k');
grid;
title('短时平均幅度差');
ylabel('幅值'); xlabel(['点数' 10]);
%短时平均幅度差函数
function y=STAmdf(X)
y=zeros(size(X));
fn=size(X,2); %帧数
wlen=size(X,1); %帧长
for i=1:fn
u=X(:,i); %取出一帧
for k=1:wlen
y(:,k)=sum(abs(u(k:end)-u(1:end-k+1)));%求每个样本点的幅度差
end
end
end
运行结果