语音信号短时时域分析

语音信号短时时域分析

类型

短时能量

  • 对数
    在这里插入图片描述
  • 平方和
    在这里插入图片描述
  • 绝对值
    在这里插入图片描述

短时平均过零率
在这里插入图片描述

短时自相关分析
在这里插入图片描述

说明

语音信号的分帧处理,实际上就是对各帧进行某种变换或运算。
T[ ]:表示这种变换或运算
x(n):输入语音信号
w(n):窗序列
h(n):是与w(n)有关的滤波器
则各帧经处理后的输出可以表示为:
在这里插入图片描述

几种常见的短时处理方法:

  • Qn对应于短时能量
    在这里插入图片描述
  • Qn对应于平均过零率
    在这里插入图片描述
  • Qn对应于自相关函数
    在这里插入图片描述
短时平均能量

定义n时刻某语音信号的短时平均能力En为:
在这里插入图片描述

  • 因为在窗函数外是为0,所以求和范围只需在窗函数内

当窗函数为矩形窗时:
在这里插入图片描述
若令h(n)=w2(n),则短时平均能量就可以写成:
在这里插入图片描述

实现框图:
在这里插入图片描述

En反映语音信号的幅度或能量随时间缓慢变化的规律。窗的长短对于能否由短时能量反映语音信号的幅度变化,起着决定性影响。

操作小记

描述:不同矩形窗长N时的短时能量函数
代码

fid=fopen('zqq.txt','rt');          %读入语音文件,r表示读,t表示以文本方式打开。
                                    %fid是文件代号,为正整数,若为-1表示打开文件失败
x=fscanf(fid,'%d');         %读入数据,%f是小数点形式的浮点数,此处也可改为%d(整数)
fclose(fid);

%计算N=50,帧移=50时的语音能量
s=fra(50,50,x)              %fra为自定义的分帧函数。需要放到同一个文件夹下 
s2=s.^2;                    %一帧内各样点的能量
energy=sum(s2,2)            %求一帧能量
subplot(2,2,1)               %定义画图数量和布局 
plot(energy)                %画N=50时的语音能量图
xlabel('帧数')               %横坐标
ylabel('短时能量 E')         %纵坐标
legend('N=50')              %曲线标识
axis([0,1500,0,2*10^10])      %定义横纵坐标范围。
                               %文件共66000个数据,66000/50=1320,横坐标取0~1500。
%计算N=100,帧移=100时的语音能量
s=fra(100,100,x)            
s2=s.^2;
energy=sum(s2,2)            
subplot(2,2,2)              
plot(energy)                %画N=100时的语音能量图
xlabel('帧数')
ylabel('短时能量 E')
legend('N=100')
axis([0,750,0,4*10^10])       %定义横纵坐标范围

%计算N=400,帧移=400时的语音能量
s=fra(400,400,x)            
s2=s.^2;
energy=sum(s2,2)
subplot(2,2,3)               
plot(energy)                %画N=400时的语音能量图
xlabel('帧数')
ylabel('短时能量 E')
legend('N=400')
axis([0,190,0,1.5*10^11])        %定义横纵坐标范围

%计算N=800,帧移=800时的语音能量
s=fra(800,800,x)             
s2=s.^2;
energy=sum(s2,2)
subplot(2,2,4)               
plot(energy)                 %画N=800时的语音能量图
xlabel('帧数')
ylabel('短时能量 E')
legend('N=800')
axis([0,95,0,3*10^11])        %定义横纵坐标范围

----
%fra.m文件
function f=fra(len,inc,x)
fh=fix(((size(x,1)-len)/inc)+1) %fix为向0取整函数
f=zeros(fh,len);
i=1;n=1;
while i<=fh
    j=1;
    while j<=len
        f(i,j)=x(n);
        j=j+1;n=n+1;
    end
    n=n-len+inc;
    i=i+1;
end

效果
在这里插入图片描述

短时平均能量的主要用途

  • 作为区分清音和浊音的特征参数
  • 在信噪比较高的情况下,作为区分有声和无声的依据
  • 作为辅助的特征参数用于语音识别中
短时平均幅度

为了克服短时能量函数计算x2(m)的缺点(定点计算容易溢出),定义了短时平均幅度函数:
在这里插入图片描述
实现框图:
在这里插入图片描述

操作小记

描述:不同矩形窗长N时的短时能量函数
代码

fid=fopen('zqq.txt','rt')                %读入语音文件
x=fscanf(fid,'%f')
fclose(fid)

s=fra(50,50,x)                       %语音短时平均幅度图
s3=abs(s) 							 %求绝对值
avap=sum(s3,2)
subplot(2,2,1)
plot(avap)
xlabel('帧数')
ylabel('短时平均幅度 M')
legend('N=50')
axis([0,1500,0,10*10^5])

s=fra(100,100,x)
s3=abs(s)
avap=sum(s3,2)
subplot(2,2,2)
plot(avap)
xlabel('帧数')
ylabel('短时平均幅度 M')
legend('N=100')
axis([0,750,0,2*10^6])

s=fra(400,400,x)
s3=abs(s)
avap=sum(s3,2)
subplot(2,2,3)
plot(avap)
xlabel('帧数')
ylabel('短时平均幅度 M')
legend('N=400')
axis([0,190,0,7*10^6])

s=fra(800,800,x)
s3=abs(s)
avap=sum(s3,2)
subplot(2,2,4)
plot(avap)
xlabel('帧数')
ylabel('短时平均幅度 M')
legend('N=800')
axis([0,95,0,14*10^6]) 

----
%fra.m文件
function f=fra(len,inc,x)
fh=fix(((size(x,1)-len)/inc)+1) %fix为向0取整函数
f=zeros(fh,len);
i=1;n=1;
while i<=fh
    j=1;
    while j<=len
        f(i,j)=x(n);
        j=j+1;n=n+1;
    end
    n=n-len+inc;
    i=i+1;
end

效果
在这里插入图片描述
Mn与En的比较
在这里插入图片描述

  • Mn能较好地反映清音范围内的幅度变化
  • Mn所能反映幅度变化的动态范围比En
  • Mn反映清音和浊音之间的电平差次与En
短时平均过零率

在离散时间语音信号情况下,如果相邻的采样具有不同的代数符号就称为发生了过零。单位时间内过零的次数就称为过零率。短时平均过零率的定义为:
在这里插入图片描述
其中:
在这里插入图片描述
用1/2N作为幅值,考虑了对该窗口范围内的过零数取平均

另外:考虑到w(n-m)的非零值范围为n-m大于等于0,以及n-m小于等于N-1,所以短时平均过零率可以改写为:
在这里插入图片描述
实现框图
在这里插入图片描述

操作小记

描述:女声“我到北京去”的短时平均过零次数的变化曲线
代码:(chapter3_6.m)

clear all
fid=fopen('beijing.txt','rt')
x1=fscanf(fid,'%f');
fclose(fid);
x=awgn(x1,15,'measured');   %加入15dB的噪声。awgn将高斯白噪声添加到信号中,
                %'15'指定每一个采样点信号与噪声的比率,单位为dB。
                %'measured'在添加噪声之前测量了x的能量
s=fra(220,110,x);			%分帧,帧移110
zcr=zcro(s);				%自定义函数,求过零率
figure(1);					%画图
subplot(2,1,1)				%第一个子图
plot(x);					%画原始图
title('原始信号');			%图标题
xlabel('样点数');			%横坐标名称
ylabel('幅度');				%纵坐标名称
axis([0,39760,-2*10^4,2*10^4]);	%限定横、纵坐标范围
subplot(2,1,2)				%画第二个子图
plot(zcr);					%原始信号的过零率
xlabel('帧数');				%横坐标名称
ylabel('过零次数');			%纵坐标名称
title('原始信号的过零率');		%图标题
axis([0,360,0,200]);		%限定横、纵坐标范围

效果:
在这里插入图片描述

短时过零率的应用:
端点检测可以从包含语音的一段信号中确定出语音的起点及结束点
在这里插入图片描述

  • 清音过零率高,浊音过零率低
  • 局限性:浊音和清音重叠区域只根据短时平均过零率不可能明确地判别清、浊音
基于能量和过零率的语音端点检测

语音端点检测就是指从包含语音的一段信号中确定出语音的起始点和结束点。
正确的端点检测对于语音识别和语音编码系统都有重要的意义
检测方法:两级判决法(双门限法)

两级判决法示意图
在这里插入图片描述
具体如下:
第一级判决:

  • 先根据语音短时能量的轮廓选取一个较高的门限T1,进行一次判决:语音起止点位于该门限与短时能量包络 交点所对应的时间间隔之外(即AB段之外)。
  • 根据背景噪声的平均能量确定一个较低的门限T2 , 并从A点往左、从B点往右搜索,分别找到短时能量包 络与门限T2相交的两个点C和D,于是CD段就是用双门 限方法根据短时能量所判定的语音段。

第二级判决:

  • 以短时平均过零率为标准,从C点往左和从D点往右搜索,找到短时平均过零率低于某个门限T3的两点E和F,这便是语音段的起止点。门限T3是由背景噪声的平均过零率所确定的。

注意:门限T2,T3都是由背景噪声特性确定的,因此,在进行起止点判决前,T1,T2,T3,三个门限值的确定还应当通过多次实验

短时自相关函数

时域离散确定信号的自相关函数定义为:
在这里插入图片描述

时域离散随机信号的自相关函数定义为:
在这里插入图片描述

自相关函数性质

  • 对称性R(k)= R(-k)
  • 在k = 0处为最大值,即对于所有k来说,|R(k)|≤R(0)
  • 对于确定信号,R(0)对应于能量
  • 对于随机信号,R(0)对应于平均功率
语音信号的短时自相关函数

采用短时分析方法,定义语音信号短时自相关函数为:
在这里插入图片描述
因为 Rn(-k)=Rn(k),所以:
在这里插入图片描述
若定义hk(n)=w(n)w(n+k),则短时自相关函数可以写成:
在这里插入图片描述
上式子表明,序列x(n)x(n-k)经过一个冲激响应为hk(n)的数字滤波器滤波即得到短时自相关函数Rn(k),也可采用直接运算的方法得到Rn(k),如下式子:
在这里插入图片描述

实现框图:
在这里插入图片描述

操作小记

代码:浊音的短时自相关函数(chapter3_7.m)

fid=fopen('voice.txt','rt')
x=fscanf(fid,'%f');
fclose(fid);

s1=x(1:320);                                  %选择一段320点的语音段
N=320;                                      %选择的窗长

A=[];                                        %加N=320的矩形窗
for k=1:320;
    sum=0;
    for m=1:N-k+1;
        sum=sum+s1(m)*s1(m+k-1);   %计算自相关,因为k从1开始,所以是m+k-1
    end
    A(k)=sum;
end
for k=1:320
A1(k)=A(k)/A(1);   %归一化A(k);
end

f=zeros(1,320);                                %加N=320的汉明窗
n=1;j=1;
   while j<=320
      f(1,j)=x(n)*[0.54-0.46*cos(2*pi*n/300)]; %汉明窗公式
      j=j+1;n=n+1;
   end
B=[];
for k=1:320;
    sum=0;
    for m=1:N-k+1;
        sum=sum+f(m)*f(m+k-1); %自相关函数
    end
    B(k)=sum;
end

for k=1:320
    B1(k)=B(k)/B(1);%归一化B(k)
end
s2=s1/max(s1);

figure(1)           %画图
subplot(3,1,1)      %第一个子图
plot(s2)            %画一帧语音信号
title('一帧语音信号')%图标题
xlabel('样点数')     %横坐标名称
ylabel('幅值')       %纵坐标名称
axis([0,320,-1,1]);%限定横、纵坐标范围

subplot(3,1,2)
plot(A1);
title('加矩形窗的自相关函数')
xlabel('延时 k')
ylabel('R(k)')
axis([0,320,-1,1]);

subplot(3,1,3)
plot(B1);
title('加哈明窗的自相关函数')
xlabel('延时 k')
ylabel('R(k)')
axis([0,320,-1,1]);

效果:浊音的短时自相关函数
在这里插入图片描述


代码:清音的短时自相关函数

fid=fopen('qingyin1.txt','rt')
x=fscanf(fid,'%f');
fclose(fid);

s1=x(1:320);                                  %选择一段320点的语音段
N=320;                                      %选择的窗长

A=[];                                        %加N=320的矩形窗
for k=1:320;
sum=0;
for m=1:N-k+1;
sum=sum+s1(m)*s1(m+k-1);                     %计算自相关
end
A(k)=sum;
end
for k=1:320
A1(k)=A(k)/A(1);   %归一化A(k);
end

f=zeros(1,320);                                %加N=320的哈明窗
n=1;j=1;
   while j<=320
      f(1,j)=x(n)*[0.54-0.46*cos(2*pi*n/300)];
      j=j+1;n=n+1;
   end
B=[];
for k=1:320;
sum=0;
for m=1:N-k+1;
sum=sum+f(m)*f(m+k-1);
end
B(k)=sum;
end
for k=1:320
B1(k)=B(k)/B(1);%归一化B(k)
end
s2=s1/max(s1);
figure(1)
subplot(3,1,1)
plot(s2)
title('一帧语音信号')
xlabel('样点数')
ylabel('幅值')
axis([0,320,-1,1]);

subplot(3,1,2)
plot(A1);
title('加矩形窗的自相关函数')
xlabel('延时 k')
ylabel('R(k)')
axis([0,320,-1,1]);

subplot(3,1,3)
plot(B1);
title('加哈明窗的自相关函数')
xlabel('延时 k')
ylabel('R(k)')
axis([0,320,-1,1]);

效果:清音的短时自相关函数
在这里插入图片描述
浊音和清音的短时自相关函数特点:

  • 短时自相关函数可以很明显的反映出浊音信号的周期性
  • 清音的短时自相关函数没有周期性,也不具有明显突出的峰值,其性质类似于噪声
  • 不同的窗对短时自相关函数结果有一定的影响

代码:不同矩形窗长时的短时自相关函数

fid=fopen('voice.txt','rt')
x=fscanf(fid,'%f');
fclose(fid);

s1=x(1:320);
N=320;                                    %选择的窗长,加N=320的矩形窗
A=[];
for k=1:320;
sum=0;
for m=1:N-(k-1);
sum=sum+s1(m)*s1(m+k-1);                  %计算自相关
end
A(k)=sum;
end
for k=1:320
A1(k)=A(k)/A(1);                           %归一化A(k);
end

N=160;                                   %选择的窗长, %加N=160的矩形窗
B=[];
for k=1:320;
sum=0;
for m=1:N-(k-1);
sum=sum+s1(m)*s1(m+k-1);                 %计算自相关
end
B(k)=sum;
end
for k=1:320
B1(k)=B(k)/B(1);                           %归一化B(k);
end

N=70;                                    %选择的窗长,加N=70的矩形窗
C=[];
for k=1:320;
sum=0;
for m=1:N-(k-1);
sum=sum+s1(m)*s1(m+k-1);                  %计算自相关
end
C(k)=sum;
end
for k=1:320
C1(k)=C(k)/C(1);                            %归一化C(k);
end

figure(1)
subplot(3,1,1)
plot(A1)
xlabel('延时 k')
ylabel('R(k)')
axis([0,320,-1,1]);
legend('N=320')

subplot(3,1,2)
plot(B1);
xlabel('延时 k')
ylabel('R(k)')
axis([0,320,-1,1]);
legend('N=160')

subplot(3,1,3)
plot(C1);
xlabel('延时 k')
ylabel('R(k)')
axis([0,320,-1,1]);
legend('N=70')

效果:不同矩形窗长时的短时自相关函数
在这里插入图片描述
长基音周期、窄窗:得不到预期的基音周期
短基音周期、长窗:函数对多个周期平均,模糊语音的短时特性

修正的短时自相关函数:使用较窄的窗,同时避免短时自相关函数随k增加而衰减 ,修正的短时自相关函数可以写成:
在这里插入图片描述
因为求和上限是N-1,与k无关,故当k增加时,Rn(k)值不下降

代码:修正的短时自相关函数

fid=fopen('voice.txt','rt')
x=fscanf(fid,'%f');
fclose(fid);

s1=x(1:320);                                  %选择一段320点的语音段
N=320;                                      %选择的窗长

A=[];                                        %加N=320的矩形窗
for k=1:320;
    sum=0;
    for m=1:N-k+1;
        sum=sum+s1(m)*s1(m+k-1);   %计算自相关,因为k从1开始,所以是m+k-1
    end
    A(k)=sum;
end
for k=1:320
A1(k)=A(k)/A(1);   %归一化A(k);
end

f=zeros(1,320);                                %加N=320的哈明窗
n=1;j=1;
   while j<=320
      f(1,j)=x(n)*[0.54-0.46*cos(2*pi*n/300)];
      j=j+1;n=n+1;
   end
B=[];
for k=1:320;
    sum=0;
    for m=1:N-k+1;
        sum=sum+f(m)*f(m+k-1);
    end
    B(k)=sum;
end
for k=1:320
B1(k)=B(k)/B(1);%归一化B(k)
end
s2=s1/max(s1);

figure(1)
subplot(3,1,1)
plot(s2)
title('一帧语音信号')
xlabel('样点数')
ylabel('幅值')
axis([0,320,-1,1]);

subplot(3,1,2)
plot(A1);
title('加矩形窗的自相关函数')
xlabel('延时 k')
ylabel('R(k)')
axis([0,320,-1,1]);

subplot(3,1,3)
plot(B1);
title('加哈明窗的自相关函数')
xlabel('延时 k')
ylabel('R(k)')
axis([0,320,-1,1]);

效果:修正的短时自相关函数
在这里插入图片描述

基音周期估值

基音周期估值在语音信号处理应用中具有十分重要的作用
语音信号基音周期估值最基本的两种方法:

  • 基于短时自相关法的基音周期估值
  • 基于短时平均幅度差函数法的基音周期估值
基于短时自相关法的基音周期估值

语音的浊音信号具有准周期性,其自相关函数在基 音周期的整数倍处取最大值

计算两相邻最大峰值间的距离,可估计出基音周期。为了减小运算量,需要对语音信号进行适当预处理。

预处理的两种方法:

  • 先对语音信号进行低通滤波,再进行自相关计算
    • 语音信号包括丰富的谐音分量
    • 基音频率范围一般在50~500Hz,女高音不超过 1kHz
    • 采用1kHz的低通滤波器先对语音信号进行滤波, 保留基音频率;再用2kHz采样频率进行采样,最后用 2~20ms的滞后时间计算短时自相关,帧长取10~20ms,即可估计出基音周期
  • 先对语音信号进行中心削波处理,再进行自相关计算
    • 中心削波:削波后的序列用短时自相关函数估计基音周期,在基音周期处峰值更加尖锐,可减少倍频或半频错误。中 心削波函数为(xL一般取本帧信号最大幅度的60%~70%):
      在这里插入图片描述
    • 三电平削波 :为了克服短时自相关函数计算量大的问题,在中心削波法的基础上,还可以采用三电平削波法,削波函数为:
      在这里插入图片描述

基音周期估值的后处理

  • 在提取基音时,提取的基音频率轨迹与真实的基音频率轨迹不可能完全吻合。通常在实际基音频率的倍频或分频处发生偏离,产生“野点”。
  • 为了去除 “野点”,常用的平滑技术主要有:中值滤波平滑处理、线性平滑、动态规划平滑处理
操作小记

代码:中心削波

% 本程序运行结果为中心削波前后的语音波形,以及削波前后的自相关波形
%读入数据 采样fs=8KHz 采样位数16bit 长度320样点
fid=fopen('voice.txt','rt');               %打开语音文件
[a,count]=fscanf(fid,'%f',[1,inf]);         %读语音文件
L=length(a);                         %测定语音的长度
m=max(a);
for i=1:L
a(i)=a(i)/m;                        %数据归一化
end

%找到归一化以后数据的最大值和最小值
m=max(a);                          %找到最大的正值
n=min(a);                           %找到最小的负值
%为保证幅度值与横坐标轴对称,采用计算公式是n+(m-n)/2,合并为(m+n)/2
ht=(m+n)/2;
for i=1:L;                           %数据中心下移 保持和横坐标轴对称
a(i)=a(i)-ht;
end
figure(1);                           %画第一幅图
subplot(2,1,1);                       %第一个子图
plot(a,'k');
axis([0,1711,-1,1]);                   %确定横、纵坐标的范围
title('中心削波前语音波形');           %图标题
xlabel('样点数');                     %横坐标
ylabel('幅度');                     %纵坐标

coeff=0.7;                          %中心削波函数系数取0.7
th0=max(a)*coeff;                    %求中心削波函数门限(threshold)
for k=1:L ;                          %中心削波
    if a(k)>=th0
        a(k)=a(k)-th0;
    elseif a(k)<=(-th0);
        a(k)=a(k)+th0;
    else
        a(k)=0;
    end      
end
m=max(a);                 
for i=1:L;                        %中心削波函数幅度的归一化
a(i)=a(i)/m;
end
subplot(2,1,2);                    %第二个子图
plot(a,'k');
axis([0,1711,-1,1]);               %确定横、纵坐标的范围
title('中心削波后语音波形');       %图标题
xlabel('样点数');                 %横坐标
ylabel('幅度');                 %纵坐标
fclose(fid);                      %关闭文件

%没有经过中心削波的修正自相关计算
fid=fopen('voice.txt','rt');
[b,count]=fscanf(fid,'%f',[1,inf]);
fclose(fid);
N=320;                          %选择的窗长
A=[];
for k=1:320;                    %选择延迟长度
sum=0;
for m=1:N;
sum=sum+b(m)*b(m+k-1);        %计算自相关
end
A(k)=sum;
end
for k=1:320  
    B(k)=A(k)/A(1);               %自相关归一化
end

figure(2);                         %画第二幅图
subplot(2,1,1);                     %第一个子图
plot(B,'k');
title('中心削波前修正自相关');       %图标题
xlabel('延时k');                    %横坐标
ylabel('幅度');                    %纵坐标
axis([0,320,-1,1]); 

%中心削波函数和修正的自相关方法结合
N=320;                          %选择的窗长
A=[];
for k=1:320;                    %选择延迟长度
sum=0;
for m=1:N;
sum=sum+a(m)*a(m+k-1);        %对削波后的函数计算自相关
end
A(k)=sum;
end
for k=1:320  
    C(k)=A(k)/A(1);               %自相关归一化
end

subplot(2,1,2);                     %第二个子图
plot(C,'k');
title('中心削波后修正自相关');       %图标题
xlabel('延时k');                    %横坐标
ylabel('幅度');                    %纵坐标
axis([0,320,-1,1]); 

效果:中心削波
在这里插入图片描述

附录
相关练习之选择题
  1. 小明和谁打台球了?(%^&$%^#$%@$ 题^_^)
    答案:小丽
  2. 卷积不能用于以下哪个场景?
    答案:计算炒股受益
  3. 预加重是为了提升语音信号( )部分,去除口唇辐射的影响。
    答案:高频
  4. 对信号进行分帧加窗后的频谱( )。
    答案:会多出一些原来没有的频率成分
  5. 以下哪项的本质意义与其它三项不同?
    答案:
    在这里插入图片描述
  6. 可以用来分辨清音和浊音的是( )
    答案:以上皆可
  7. 使用两级判别法进行语音端点检测,需要设置( )个门限值。
    答案:3
  8. 先对语音信号进行中心削波处理,再进行自相关计算,是为了更好地计算( )。
    答案:基音周期
相关练习之简答题
  1. 为什么对语音信号进行分析之前要分帧?
    答案:为了方便对语音信号进行分析,假设假设语音信号在10~30ms短时间内是平稳的。可把语音信号分帧进行处理。采用可移动的有限长度窗口进行加权实现分帧
  2. 为什么浊音的自相关函数具有周期性?
    答案:因为浊音具有周期性
  3. chapter3_6.m 代码及注释,粘贴到这里
    答案:参看上面代码
  4. chapter3_7.m 代码及注释,粘贴到这里
    答案:参看上面代码
发布了138 篇原创文章 · 获赞 68 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_40626497/article/details/105203454