您的位置:首页 > 其它

语音信号处理基础——简易VAD函数

2016-06-03 05:33 274 查看
Voice Activity Detection (VAD) 在语音信号处理中,例如语音增强,语音识别等领域有着非常重要的作用。它的作用是从一段语音(纯净或带噪)信号中标识出语音片段与非语音片段。

 

例如,在语音增强中,我们希望从带噪语音信号中剔除噪音,得到纯净的语音信号,第一步就是提取噪音信息。通常的思路是通过VAD函数得到非语音片段,而非语音片段可以认为是纯噪音片段。从而可以从纯噪音信号中提取出有用信息,例如进行傅里叶变换得到噪音频谱等,再进而做下一步处理。例如谱减法,维纳滤波。此处不作讨论。

 

VAD有很多种方法,此处介绍一种最简单直接的办法。 通过short timeenergy (STE)和zero cross counter (ZCC) 来测定。(实际上精确度高的VAD会提取4种或更多的特征进行判断,这里只介绍两种特征的基本方法)。

 

l  STE: 短时能量,即一帧语音信号的能量

l  ZCC: 过零率,即一帧语音时域信号穿过0(时间轴)的次数。

 

理论基础是在信噪比(SNR)不是很低的情况下,语音片段的STE相对较大,而ZCC相对较小;而非语音片段的STE相对较小,但是ZCC相对较大。因为语音信号能量绝大部分包含在低频带内,而噪音信号通常能量较小且含有较高频段的信息。

 

故而可以通过测量语音信号的这两个特征并且与两个门限(阈值)进行对比,从而判断语音信号与非语音信号。

 
通常对语音信号分帧时取一帧20ms (因为一般会进行短时傅里叶变换,时域和频域的分辨率需要一个平衡,20ms为平衡点,此处不用考虑)。此处输入信号采样率为8000HZ。因此每一帧长度为160 samples.

 

STE的计算方法是 , 即帧内信号的平方和。

在本文中ZCC的计算方法是,将帧内所有sample平移1,再对应点做乘积,符号为负的则说明此处过零,只需将帧内所有负数乘积数目求出则得到该帧的过零率。

 

附Matlab 代码

 

clc;clear;closeall;
[s,fs]=audioread('sp8k.wav');
%s=s+(rand(length(s),1)-0.5)*sqrt(12*0.0001);
t=20;
frameL=fs*t/1000;
for i=1:length(s)/frameL
tmp=s((i-1)*frameL+1:i*frameL);
ste(i)=sum(tmp.^2);
zcc(i)=sum(tmp(1:end-1).*tmp(2:end)<0);
end
subplot(311);plot(s);title('Speech Signal');xlabel('Sample');
subplot(312);plot(ste);title('Short time energy');xlabel('Frame');
subplot(313);plot(zcc);title('Zerocrossing counter');xlabel('Frame');
t_e=0.05; % threshold of STE
t_z=40;   % threshold of ZCC
vad=(ste>t_e).*(zcc<t_z);
detect=ones(length(s),1);
for i=1:length(ste);
detect((i-1)*frameL+1:i*frameL)=vad(i);
end
figure;plot(s),holdon; plot(detect*0.5);
title('Signal and VAD');legend('Signal','VAD');xlabel('sample');
hold off;
figure;speech=s(detect==1);plot(speech);
title('non-speech signal removed');
 
结果如图



 


 

 


 
欢迎扫码关注Larry’sLab, 一块学习讨论与分享

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  语音处理 DSP