基于短时时域处理中短时能量和过零率的语音端点检测方法


1.背景

在语音信号处理中检测出语音的端点是相当重要的。语音端点的检测是指从包含语音的一段信号中确定的起始点和结束点位置,因为在某些语音特性检测和处理中,只对有话段检测或处理。例如,在语音减噪和增强中,对有话段和无话段可能采取不同的处理方法;在语音识别和语音编码中同样有类似的处理。
处理没有噪声的情况下的语音端点检测,用短时平均能量就可以检测出语音的端点。但实际处理语音往往处于复杂的噪声环境中,这时,判别语音段的起始点和终止点的问题主要归结为区别语音和噪声的问题。
所以本项目实现的是短时平均能量和短时平均过零率的方法,同时简单介绍在低信噪比条件下端点的检测。

2.主要内容

2.1、画出“f.m4a”和“b.m4a”的语音信号波形和它的短时能量图

2.2、画出“f.m4a”和“b.m4a”的语音信号波形和它的短时平均零交叉率图

2.3、利用2.2和2.3短时能量和短时平均零交叉率进行端点检测两级判决法示意图。

3.具体实验内容

3.1短时能量

设语音波形时域信号为x(n),加窗函数w(n),分帧处理后得到的第i帧语音信号为yi(n),则yi(n)满足:

式中,w(n)为窗函数,一般为矩形窗或汉明窗;yi(n)是一帧的数值,n=1,2,…,L, i=1,2,…,fn,L为帧长;inc为帧移长度;fn为分帧后的总帧数。
计算第i帧语音信号yi(n)的短时能量公式为:

这里给出核心代码解释:

% 所用到的函数
% function frameTime=frame2time(frameNum,framelen,inc,fs)
% 分帧后计算每帧对应的时间
% frameTime=(((1:frameNum)-1)*inc+framelen/2)/fs;
% end
%f和b的时域图与短时能量图
clear all;
[x,fs]=audioread('..\input\语音数据\f.m4a');         %读取音频
x=x(:,1);                                                  %提取一个通道
wlen=960;                                                  %设置窗长
win=hanning(wlen);                                         %设置海宁窗
inc=400;                                                   %设置帧移
lx=length(x);
xf=enframe(x,win,inc)';                                    %分帧、加海宁窗
fnx=size(xf,2);                                            %帧数
tx=(0:lx-1)/fs;
frametimex=frame2time(fnx,wlen,inc,fs);
for i=1:fnxxf1=xf(:,i);xe=xf1.*xf1;Enx(i)=sum(xe);
end

结果展示:

3.2平均幅度

语音信号的平均幅度定义为

M(i)也是一帧信号能量大小的表征,它与E(i)的区别在于计算时不论采样值的大小,不会因取二次方而造成较大的差异,在某些领域中会带来一些好处。
短时能量和短时平均幅度函数的主要用途有:区分浊音段和轻音段,因为浊音时E(i)值比轻音时大得多;区分声母和韵母的分界和无话段与有话段的分界。

3.3短时平均过零率

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

短时平均过零率为

式中,sgn[]是符号函数,即

在实际计算短时平均过零率时,需要十分注意的一个问题是,如果输入信号中包含漂移,即信号在通往AD转换器前就有个直流分量,使AD转换后继续带有这个直流分量。因为直流分量的存在影响了短时平均过零率的正确估算,所以建议在语音信号处理前先消除直流分量。
理论上短时平均过零率是按上式计算,而在MATLAB编程中,却用另一种方法 。按上述过零的描述,即离散信号相邻的取样值改变符号,那它们的乘积一定为负数,即:

这里给出核心代码解释:

[x,fs]=audioread('G:\语音处理项目\语音处理大作业\语音数据\f.m4a');
x=x(:,1);
wlen=960;
win=hanning(wlen);
inc=400;
xx=x-mean(x);
lxx=length(xx);
txx=(0:lxx-1)/fs;
xxf=enframe(xx,win,inc)';
fnxx=size(xxf,2);
zcrx=zeros(1,fnxx);
for i=1:fnxxxxf1=xxf(:,i);for j=1:(wlen-1)if xxf1(j)*xxf1(j+1)<0zcrx(i)=zcrx(i)+1;endend
end

结果展示:

3.4语音端点检测原理

双门限法
双门限法最初是基于短时平均能量和短时平均过零率而提出的,其原理是汉语的韵母中 有元音,能量较大,所以可以从短时平均能量中找到韵母,而声母是辅音,它们的频率较高,相应的短时平均过零率较大,所以用这两个特点找出声母和韵母,等于找出完整的汉语音节。双门限法是使用二级判决来实现的。

以上图为例,图(a)是语音的波形,图(b)是该语音的短时平均能量,图(c)是该语音的短时平均过零率。进行判决的具体步骤如下:

1.第一级判决

①根据在语音短时能量包络线上选取的一个较高阈值(门限)T2 (图中以虚水平线表示) 进行一次粗判,就是高于该T2阈值肯定是语音(即在CD段之间肯定是语音),而语音起止点应位于该阈值与短时能量包络交点所对应的时间点之外(即在CD段之外)。
②在平均能量上确定一个较低的阈值(门限)(图中以实水平线表示),并从C点往左、从D点往右搜索,分别找到短时能量包络与阈值T1相交的两个点B和E,于是BE段就是用双门限法根据短时能量所判定的语音段的起止点位置。

2.第二级判决

以短时平均过零率为准,从B点往左和从E点往右搜索,找到短时平均过零率低于某个阈值(门限)T3的两点A和F (图中T3以水平虚线表示),这便是语音段的起止点。
根据这两级判决,求出了语音的起始点位置A和结束点位置F。但考虑到语音发音时单 词之间的静音区会有一个最小长度表示发音间的停顿,就是在小于阈值T3满足这样一个最小长度后才判断为该语音段结束,实际上相当于延长了语音尾音的长度,如图中在语音波形图上标出语音的起止点分别为A和F+(从图中看出终止点位置为F,而实际处理中延长到 F+)。
在端点检测的具体运行中,首先是对语音分帧(实验二已做过介绍),在分帧基础上方能求出短时平均能量和短时平均过零率,然后逐帧地依阈值进行比较和判断。

这里给出几个核心函数代码:

function frameTime=frame2time(frameNum,framelen,inc,fs)
% 分帧后计算每帧对应的时间
frameTime=(((1:frameNum)-1)*inc+framelen/2)/fs;
function [voiceseg,vsl,SF,NF]=vad_ezm1(x,wlen,inc,NIS)
x=x(:);                                 % 把x转换成列数组
maxsilence = 15;                        % 初始化
minlen  = 5;
status  = 0;
count   = 0;
silence = 0;y=enframe(x,wlen,inc)';                 % 分帧
fn=size(y,2);                           % 帧数
amp=sum(y.^2);                          % 求取短时平均能量
zcr=zc2(y,fn);                          % 计算短时平均过零率
ampth=mean(amp(1:NIS));                 % 计算初始无话段区间能量和过零率的平均值
zcrth=mean(zcr(1:NIS));
amp2=2*ampth; amp1=4*ampth;             % 设置能量和过零率的阈值
zcr2=2*zcrth;%开始端点检测
xn=1;
for n=1:fnswitch statuscase {0,1}                           % 0 = 静音, 1 = 可能开始if amp(n) > amp1                  % 确信进入语音段x1(xn) = max(n-count(xn)-1,1);status  = 2;silence(xn) = 0;count(xn)   = count(xn) + 1;elseif amp(n) > amp2 | ...        % 可能处于语音段zcr(n) > zcr2status = 1;count(xn)  = count(xn) + 1;else                              % 静音状态status  = 0;count(xn)   = 0;x1(xn)=0;x2(xn)=0;endcase 2,                              % 2 = 语音段if amp(n) > amp2 & ...            % 保持在语音段zcr(n) > zcr2count(xn) = count(xn) + 1;silence(xn) = 0;else                              % 语音将结束silence(xn) = silence(xn)+1;if silence(xn) < maxsilence    % 静音还不够长,语音尚未结束count(xn)  = count(xn) + 1;elseif count(xn) < minlen      % 语音长度太短,认为是静音或噪声status  = 0;silence(xn) = 0;count(xn)   = 0;else                           % 语音结束status  = 3;x2(xn)=x1(xn)+count(xn);endendcase 3,                              % 语音结束,为下一个语音准备status  = 0;          xn=xn+1; count(xn)   = 0;silence(xn)=0;x1(xn)=0;x2(xn)=0;end
end el=length(x1);
if x1(el)==0, el=el-1; end              % 获得x1的实际长度
if x2(el)==0                            % 如果x2最后一个值为0,对它设置为fnfprintf('Error: Not find endding point!\n');x2(el)=fn;
end
SF=zeros(1,fn);                         % 按x1和x2,对SF和NF赋值
NF=ones(1,fn);
for i=1 : elSF(x1(i):x2(i))=1;NF(x1(i):x2(i))=0;
end
speechIndex=find(SF==1);                % 计算voiceseg
voiceseg=findSegment(speechIndex);
vsl=length(voiceseg);
function zcr=zc2(y,fn)
if size(y,2)~=fn, y=y'; end
wlen=size(y,1);                            % 设置帧长
zcr=zeros(1,fn);                           % 初始化
delta=0.01;                                % 设置一个很小的阈值
for i=1:fnyn=y(:,i);                             % 取来一帧for k=1 : wlen                         % 中心截幅处理if yn(k)>=deltaym(k)=yn(k)-delta;elseif yn(k)<-deltaym(k)=yn(k)+delta;elseym(k)=0;endendzcr(i)=sum(ym(1:end-1).*ym(2:end)<0);  % 取得处理后的一帧数据寻找过零率
end

注:
① 输入参数:x是语音信号的序列,为了要分帧,设置帧长为wlen和帧移为inc,NIS是前导无话段的帧数。

② 在语音处理中为了能估算噪声的情况,往往在一段语音的前部有一段前导无话语段,在以后会有不少程序利用该段前导无话语段来估算噪声的特性。在实际,有时可能不知道前导无语段的帧数,但从语音信号的波形图中可以估算出前导无话段的时长IS(单位为s),有了IS就能计算出前导无语段的帧数NIS:

③ 为了保证过零率计算的稳定,排除信号可能会有的一些微小的零漂移,所以当输入加窗分帧后的语音信号xi(m)时,做中心截幅处理(或称过门限率),得

式中,是个很小的值。
中心截幅处理后再计算每一帧的过零率:

式中

④ 先对前导无话语段计算噪声短时平均能量和短时平均过零率:

再在这两值的基础上设置能量的两个阈值amp2(T1)和amp(T2),以及过零点的阈值zcr2(T3):

在这里阈值不是一个固定的值,将会随着前导话语段计算噪声的情况 动态地变动。有了阈值以后就能按双门限法进行检测了。
⑤ 在函数中的maxsilence(表示一段语音结束时静音区的最小长度),minlen(表示有话语段的最小长度)参数就和语速有关。所以这些参数可以改变,可以按实际情况进行调整。

结果展示:
例一:

例二:

基于短时时域处理中短时能量和过零率的语音端点检测方法相关推荐

  1. python (语音)信号拆分为数据块,计算短期能量和过零率

    学习目标(ILO): 您应该 了解如何将(语音)信号拆分为数据块(帧)并在这些块上进行分析/转换 计算短期能量和过零率并将它们可视化以区分浊音和清音语音部分 了解相关性的基础知识并能够实现相关性估计器 ...

  2. 【数字语音处理】Part3 语音信号的短时时域分析:短时平均、短时自相关、语音端点检测、基音周期估值

    Part3 语音信号的短时时域分析 一.帧和加窗的概念 二.短时平均能量 三.短时平均幅度函数 四.短时平均过零率 五.短时自相关分析 六.基于能量和过零率的语音端点检测 七.基音周期估值 八.总结 ...

  3. 基于短时能量的语音端点检测算法

    1 带噪语音信号 日常生活中噪声无处不在,说话声.风声.雨声.打字声.机器运行的声音等都可定义为噪声.噪声的种类也很多,每种都有其各自的特点,对有用信息的影响程度也不同.噪音主要包括稳定噪音和非稳定噪 ...

  4. matlab浊音段和清音段,基于Matlab编写的语音端点检测1

    wavread 基于Matlab编写的语音端点检测 专业: 班级: 姓名: 指导教师: 2011年6月18日 一.实验目的 1.学会MATLAB的使用,掌握MATLAB的程序设计方法: 3.掌握语音处 ...

  5. matlab浊音段和清音段,语音端点检测及其在Matlab中的实现

    文献 计算机时代2005年第8期 25 语音端点检测及其在Matlab中的实现 刘 羽 (桂林工学院科技处,广西桂林541004) 摘要:介绍了语音的基本特征和语音端点检测的基本方法,对基于Matla ...

  6. 基于双门限法的语音端点检测及语音分割

    voice_activity_detection Audio Split 基于双门限法的语音端点检测及语音分割 代码在我的github上voice_activity_detection 如果您觉得有一 ...

  7. 语音端点检测 matlab 论文,基于MATLAB的语音端点检测

    求助,哪位高手帮忙看看以下程序全不? 基于Matlab编写的语音端点检测程序 function [x1,x2] = vad(x) %幅度归一化到[-1,1] x = double(x); x = x ...

  8. 语音信号端点检测 matlab,matlab中语音端点检测

    首先在matlab中装好voicebox工具箱,里面有一些需要用到的.m文件 具体程序如下: x=readwav('D:/hao.wav'); t=x; N=size(x) x=double(x); ...

  9. 【目标检测论文解读复现NO.25】基于改进Yolov5的地铁隧道附属设施与衬砌表观病害检测方法

    前言 此前出了目标改进算法专栏,但是对于应用于什么场景,需要什么改进方法对应与自己的应用场景有效果,并且多少改进点能发什么水平的文章,为解决大家的困惑,此系列文章旨在给大家解读最新目标检测算法论文,帮 ...

  10. 基于双门限法的端点检测

    基于双门限法的端点检测 代码+论文+PPT+仿真结果下载地址:下载地址 摘要 语音端点检测是指从一段语音信号中准确的找出语音信号的起始点和结束点,它的目的是为了使有效的语音信号和无用的噪声信号得以分离 ...

最新文章

  1. linux uname 命令简介
  2. 软件工程白盒测试的流图怎么画_功能安全理论 | 黑盒 与 白盒
  3. 成都理工大学计算机报告,[2017年整理]成都理工大学通信工程计算机网络综合课程设计报告.doc...
  4. Golang 入门笔记(二)上
  5. 信号捕捉(signal、sigaction)
  6. Unity - Humanoid设置Bip骨骼导入报错
  7. python 无序列表中第k大元素_查询无序列表中第K小元素
  8. 按home键退出的activity可以不进入stop模式码_用了几年的iPhone,竟然不知道苹果手机还有“游戏模式”?...
  9. web前端开发面临挑战有哪些?
  10. (转)金融从业人员的核心竞争力在哪里?
  11. mysql5.6二进制包_MySQL 5.6版本二进制包多实例安装
  12. C++ 求指定函数的定积分问题
  13. 被反爬虫搞到心态崩溃
  14. C#保存图片、压缩图片大小、缩放图片比例
  15. 基于web的网页问卷调查设计_Python3菜鸟教程丨基于Web模块的轻量级接口设计基础...
  16. 服务器上的VGA切换原理,什么是VGA接口 原理及特点是什么
  17. PPT调整同一行字符间距的三种常用方法
  18. jQuery官网下载文档的步骤
  19. 怎样使用JS代码代码跳转的方法
  20. JavaScript:使用Canvas绘图

热门文章

  1. electron 自定义标题栏_如何在Electron Framework中创建自定义标题栏(灵感来自Visual Studio Code标题栏)...
  2. 涉密计算机信息系统的安全审计,涉密计算机信息系统安全审计.doc
  3. Java培训后如何找工作?
  4. Gitter---高颜值GitHub小程序客户端诞生记,2021年安卓社招面试题精选
  5. Unity3D架构设计NavMesh寻路
  6. cassandra cqlsh 使用实际IP或者locahost都可以进入命令行
  7. php的表达爱意的一句代码,表达爱意的诗句(精选50句)
  8. nginx 漏洞修复
  9. 文科生 python 简书_文科生学 Python 系列 15:泰坦尼克数据 1
  10. HDU4609 3-idiots fft