小奥的学习笔记

  • Home
  • Learning & Working
    • Speech Enhancement Notes
    • Programming language
    • Computer & DL
    • MOOC
  • Life
    • Life Time
    • Thinking & Comprehension
    • Volunteer
    • Plan
    • Travel
  • Footprints
  • GuestBook
  • About
    • About Me
    • 个人履历
    • 隐私策略
  1. 首页
  2. Study-notes
  3. Computer & DL
  4. 语音处理学习笔记
  5. 正文

WebRTC VAD模块分析

2019年7月15日 3698点热度 0人点赞 3条评论

WebRTC Voice Activity Detection

1 关于WebRTC VAD

1.1 WebRTC VAD简介

其实在WebRTC的VAD中用到了一个很重要的方法的思想,这个方法就是聚类。实际上我们都可以知道,分出来的只有两个类,一是语音二是噪声。我们要对每一帧信号都求语音和噪声的概率,然后根据概率来进行聚类。那么,选择怎样的特征来作为高斯分布的输入呢?这种特征的选取可是关系着VAD性能是好是坏。我们的思想就是寻找噪声和语音相差最大的特征,或者说尽可能大的特征。

众所周知,信号的处理分类主要有时域、频域和空域。首先从空域上看,WebRTC的VAD是基于单个麦克风的,噪声和语音没有空间区分度的概念;然后从时域上看,是时变信号,且短时信号变化率比较小,所以总的来说,频域的区分度是比较好的。

我们可以发现,噪声和语音在频谱上差异还是非常大的,且以一个一个的波峰和波谷来表现。基于此,WebRTC VAD将频带分为了6个子带:80Hz~250Hz,250Hz~500Hz,500Hz~1K,1K~2K,2K~3K,3K~4K,在程序里面分别对应了分别对应于feature_vector [0],feature_vector [1],feature_vector [2],feature_vector [3],feature_vector [4],feature_vector [5]。之所以最高为4k是因为,WebRTC在处理的时候采样率统一调整为了8kHz,所以根据奈奎斯特定理,用于的频率就是4kHz以下。

可以看到以1KHz为分界,向下500HZ,250Hz以及170HZ三个段,向上也有三个段,每个段是1KHz,这一频段涵盖了语音中绝大部分的信号能量,且能量越大的子带的区分度越细致。由于我国交流电标准是220V~50Hz,电源50Hz的干扰会混入麦克风采集到的数据中且物理震动也会带来影响,所以取了80Hz以上的信号。

WebRTC VAD使用的是GMM(高斯混合模型)进行分类,使Noise作为一类,Speech作为一类,两类求求后验概率,并且实时更新GMM参数。

WebRTC VAD只能工作在采样率为8000Hz的模式下,故对16kHz、32kHz、48kHz都需要进行重新采样来转换到8000Hz。目前程序仅支持8000Hz、16kHz、32kHz和48kHz。

总的来说,WebRTC VAD分为以下几步:

1.创建句柄(WebRtcVad_Create())。

2.初始化句柄(WebRtcVad_Init())。

3.设置VAD的工作模式(WebRtcVad_set_mode()),VAD的工作模式主要有以下四种:

表1.1 VAD的工作模式

4.判断当前语音文件的采样率,若采样率小于8000Hz,直接退出;若采样率不为8000Hz,则进行下采样,将高采样率重新采样到8000Hz,然后进行VAD判决;若采样率为8000Hz,则直接进行VAD判决。

5.进行VAD判决。首先计算6个子带的能量,分别保存到feature_vector[0]~feature_vector[5](WebRtcVad_CalculateFeatures())。然后通过高斯混合模型分别计算语音和非语音的概率,使用假设检验的方法确定信号的类型(GmmProbability())。首先通过高斯模型计算假设检验中的H0和H1(C代码是用h0_test和h1_test表示),通过门限判决vadflag; 然后更新概率计算所需要的语音均值(speech_means)、噪声的均值(noise_means)、语音方差(speech_stds) 和噪声方差(noise_stds)。

1.2 整体函数框图

图1.1 整体系统框图

2 函数关系图谱

2.1 主体函数关系

图2.1 主体函数关系

2.2 核心处理函数关系

图2.2 核心函数关系

3 逐个函数的讲解

3.1 WebRtcVad_CalculateFeatures()

WebRTC VAD中,对上面划分的每一个子带计算其能量,然后计算到目前为止总的能量(total_energy)。如果total_energy没有超过kMinEnergy,则对total_energy进行更新,更新的方法就是在kMinEnergy上面加个数字(程序里面是+1)。total_energy是在GmmProbability()中用作能量的指示符。

    这个函数里面用到了两个滤波器,一个滤波器是子带划分滤波器SplitFilter(),它就是将频率范围内数据分隔成两个频率范围,用于子带划分;一个是高通滤波器HighPassFilter(),用来过滤到0~80Hz信号的。

3.2 GmmProbability();

    首先需要设置一些阈值,然后判断total_power是否大于所设置的可以处理的能量标准kMinEnergy,如果不大于,自然没办法处理,如果大于则可以进行处理。处理主要有两部分:一、计算语音的可能性,然后根据此得出VAD判决;二、更新底层模型,做出决定。

具体来说,我们将每一个频率子带称为一个“通道”,假设噪声是H0,语音是H1。

那么对于每一个通道,我们使用由kNumGaussians组成的GMM对概率进行建模,每一个通道都具有不同的均值和标准差,具体取决于H0或H1。

第一步,计算出noise_probability和speech_probability。

第二步,计算对数似然比

可以近似处理为

shifts_h0-shifts_h1+log2(1+b1)-log2(1+b0)~= shifts_h0 - shifts_h1

注意:b0和b1都小于1,因此0<=log2(1+b0)<1.

第三步,使用谱均衡更新sum_log_likelihood_ratios,以用于更新全局VAD判决。

第四步,做出本地VAD判决。

第五步,计算更新GMM后使用的局部噪声概率,然后计算稍后在更新GMM时使用的本地语音概率。

对于每一个通道处理完之后,又要做以下操作:

第一步,做出全局VAD判决。

第二步,然后更新模型参数。

第三步,如果模型太过于接近,将它们分离。

第四步,控制语音和噪声均值不要漂移太多。

在完成上述处理之后,对结果进行平滑处理。具体框图如下:

图3.1 GmmProbability()函数的流程图

此文章为个人学习笔记整理所得,如有转载,敬请注明。下一期将更新关于WebRTC中AGC(自动增益控制)的学习笔记,敬请期待。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: WebRTC
最后更新:2019年7月15日

davidcheung

这个人很懒,什么都没留下

打赏 点赞
< 上一篇
下一篇 >

文章评论

  • Nolan

    您的笔记非常有帮助。贴图不显示了,可以更新一下吗?

    2023年7月25日
    回复
    • davidcheung

      @Nolan 我得找一下我之前整理的word文档看一下,如果找到了我就更新一下这篇文章。

      2023年8月16日
      回复
  • razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
    取消回复

    搜索
    欢迎关注我的个人公众号
    最新 热点 随机
    最新 热点 随机
    DEEPFILTERNET:一种基于深度滤波的全频带音频低复杂度语音增强框架 奥地利匈牙利九日游旅程 论文阅读之Study of the General Kalman Filter for Echo Cancellation 小奥看房之鸿荣源珈誉府 杭州往返旅途及西溪喜来登和万怡的体验报告 2022年的第一篇碎碎念
    奥地利匈牙利九日游旅程小奥看房之鸿荣源珈誉府论文阅读之Study of the General Kalman Filter for Echo CancellationDEEPFILTERNET:一种基于深度滤波的全频带音频低复杂度语音增强框架
    Java语言程序设计(进阶)(第八章)整理 又是一个大年三十到 个人用VB制作了一个计算器,大家来捧场吧 Deep Learning in Neural Networks: An Overview(自己翻译版) ULTRAMAN XERO将做部分修改 A very interesting View
    标签聚合
    python学习 高中 生活 鸟哥的linux私房菜 学习 Java 算法 leetcode Python linux
    最近评论
    davidcheung 发布于 5 个月前(02月09日) The problem has been fixed. May I ask if you can s...
    tk88 发布于 5 个月前(02月07日) Hmm is anyone else having problems with the pictur...
    cuicui 发布于 9 个月前(10月20日) :wink:
    niming 发布于 10 个月前(09月19日) 同级校友,能刷到太巧了
    davidcheung 发布于 2 年前(08月16日) 我得找一下我之前整理的word文档看一下,如果找到了我就更新一下这篇文章。
    Nolan 发布于 2 年前(07月25日) 您的笔记非常有帮助。贴图不显示了,可以更新一下吗?
    davidcheung 发布于 3 年前(06月19日) 到没有看webrtc的代码。现在主要在看我们公司的代码了。。。只是偶尔看一看webrtc的东西。。。
    aobai 发布于 3 年前(03月13日) gain_change_hangover_ 应该是每三个block 只能够调整一次,这样保证每帧...
    匿名 发布于 5 年前(12月30日) 烫
    小奥 发布于 5 年前(12月12日) webRTC里面的NS本身我记得就是在C++里面呀

    COPYRIGHT © 2025 小奥的学习笔记. ALL RIGHTS RESERVED.

    Theme Kratos Made By Seaton Jiang

    陕ICP备19003234号-1

    鲁公网安备37120202000100号