webRTC中语音降噪模块ANS细节详解(四)
上篇(webRTC中语音降噪模块ANS细节详解(三))讲了噪声的初始估计方法以及怎么算先验SNR和后验SNR。 本篇开始讲基于带噪语音和特征的语音和噪声的概率计算方法和噪声估计更新以及基于维纳滤波的降噪。
一, 带噪语音和特征条件下的语音概率
先看怎么算带噪语音和特征条件下的语音概率。其中会用到先前算好的先验SNR和后验SNR,也会用到特征条件下的语音概率,从而涉及到怎么算特征条件下的语音概率,有了特征条件下的语音概率后结合先前算好的先验SNR和后验SNR带噪语音和特征条件下的语音概率就好算了。
1, 带噪语音和特征条件下的语音概率
令H1(k, m)表示第m帧的第k个频点上是语音状态,表示H0(k, m)第m帧的第k个频点上是噪声状态,Y(k,m)表示第m帧的第k个频点上的幅度谱,{F}表示特征集合。为方便书写,简写为H1、H0、Y和F。P(H1 | Y F)表示在带噪语音和特征条件下是语音的概率,其他类推。因为只有语音和噪声两种类型,所以有式1和2(P(•)表示概率):
(1)
(2)
对式1展开得式3:
(3)
因为
所以得到式4:
(4)
还可得到式5:
(5)
在带噪语音和特征条件下是语音的概率为P(H1 | YF) ,把式4和5带入得到式6:
(6)
在式2中,令P(H1 | F) = q(k, m),这里简计为q,则P(H0| F) = 1 – q。
再令Δ(k, m) = 为似然比, 所以得到式7:
(7)
看怎么求似然比。这里会用到复高斯分布,先了解一下什么是复高斯分布。假设实随机高斯变量x和y的均值分别为mx与my,方差为σ2,则x的概率密度函数为
y的概率密度函数为
若x与y相互独立,则x与y的联合概率密度函数为
定义 z = x + iy,则z为复高斯随机变量。求z的均值和方差如下(E(•)表示期望):
对于干净语音和噪声来说,转换到频域后是复数,一般假设服从零均值的复高斯分布,所以
mz= 0, 从而 mx + imy= 0,所以 mx = 0,my = 0。
把mx = 0,my = 0以及σ2 z = 2σ2带入,得到
这就是干净语音和噪声的概率密度函数。
在H0下(即噪声下),Y(k,m) = N(k,m),由于噪声服从均值为0的复高斯分布,可得f(Y | H0)为与噪声有相同方差的高斯分布,所以在噪声条件下带噪语音的条件概率密度函数表示如式8:
(8)
在H1下(即语音下),Y(k,m) = S(k,m) + N(k,m),由于语音和噪声均服从均值为0的复高斯分布,以及S(k,m)和N(k,m)相互独立,可得f(Y | H1)也为高斯分布,方差为语音和噪声的方差和,所以在语音条件下带噪语音的条件概率密度函数表示如式9:
(9)
所以
软件实现时同计算先后验信噪比一样,用幅值代替能量,从而
用上篇(webRTC中语音降噪模块ANS细节详解(三))计算出的先验信噪比和后验信噪比表示就可以写成式10:
(10)
为方便计算,对似然比取自然对数得到式11:
(11)
软件实现时,没有严格按照这个表达式来,而是用2ρ(k, m)代替了ρ(k, m), 用(1+ σ(k, m))代替了σ(k, m)。所以式11变成了式12:
(12)
为了防止帧间频变导致似然比波动较大,对似然比进行了平滑,并将式12带入得到表达式13(为平滑系数):
(13)
ln(Δ(k,m))能算出,取自然指数就算出Δ(k,m)了。回看在带噪语音和特征条件下算语音的概率如式7:
Δ(k,m)已算出,只要再算出q(q = P(H1 | F) ,特征条件下是语音的概率),就可算出在带噪语音和特征条件下的语音概率了。下面看怎么算在特征条件下语音的概率。
2, 特征条件下的语音概率
webRTC用到的特征有似然比检验(Likelihood Rate Test, LRT)均值、频谱平坦度(Spectral Flatness)和频谱模板差异度(Spectral Difference)。先看这些特征,然后看怎么算在这些特征条件下的语音概率。
1) LRT均值特征
似然比Δ(k,m)上面已算出,定义F1为LRT均值特征,如下式14:
(14)
N为频点数,当采样率为16k HZ时,N = 129,下同。
2) 频谱平坦度特征
语音比噪声的谐波多,其表现是语音频谱通常在基频和谐波中出现能量峰值,而噪声频谱则相对平坦,因此频谱平坦度可以区分语音和噪声。定义F2为频谱平坦度特征,频谱平坦度算法是几何平均除以算术平均,计算如式15:
(15)
由于不太方便计算,软件实现时先取对数,变成加法运算,加法算好后再取指数从而得到几何平均,具体如下,令
所以
算出F2后还要做一个平滑处理。
3)频谱模板差异度特征
先定义五个变量:avgMagn/varMagn (magnitude的均值和方差均值)和avgPause/varPause(conservative noise spectrum的均值和方差均值),以及covMagnPause(magn和pause的协方差均值)
定义F3为频谱模板差异度特征,表达式如式16:
(16)
同频谱平坦度一样,最后也要做一个平滑。
三个特征得到后,特征条件下的语音概率P(H1 | F)或者q(k, m)的更新模型可用式17表示:
(17)
其中β为平滑系数,M(F)为映射函数,宜用非线性函数,如人工智能(AI)中常用做激活函数的S函数(sigmoid)和双曲正切(tanh)等,因为它们都把函数的取值范围压在了(0, 1)或者(-1, 1)范围内。映射函数根据特征、阈值和宽度参数,将频点划分为语音(M接近1)或者噪声(M接近0)。WebRTC中用的是tanh。这里简单说一下tanh,它的定义式如下:
可以证明它的取值范围是(-1, 1), 并且是单调递增的。tanh的波形图如下图:
实现中M(F) = 0.5 * [tanh(ω*|F - T|) + 1.0],因为tanh的取值范围是(-1, 1),所以M(F)的取值范围是(0,1)。这里F表示特征,T是阈值,参数ω代表映射函数的形状和宽度。当有多个特征后,每个特征都有一定的权重,这时q(k, m)的更新模型变为式18:
(18)
再回看在带噪语音和特征条件下算语音的概率如式7:
似然比Δ(k,m)已求出,特征(F1/F2/F3)条件下语音的概率q(k, m)也求出,在带噪语音和特征条件下算语音的概率P(H1 | YF)就算出来了,代码如下:
q = inst->priorSpeechProb, Δ = inst->logLrtTimeAvg
根据代码,
所以语音概率,跟式7是一致的。
P(H1 | YF)求出,在带噪语音和特征条件下噪声的概率P(H0 | YF) = 1 - P(H1 | YF) 也就求出来了。
二,噪声估计更新
在带噪语音和特征条件下语音和噪声的概率求出来后就可以去更新噪声的估计了(因为先前的估计是初始估计,不太准)。表达式如式19:
(19)
其中N(k, m)为本帧将要估计出来的噪声,N(k, m-1)为上帧已估计出来的更新过的噪声,Y(k,m-1)为本帧带噪的语音,γ为平滑系数,P(H1 | YF)为是语音的概率,P(H0 | YF)为是噪声的概率。
三,基于维纳滤波降噪
因为估计出来的噪声更新了,应该是噪声估计的更准了,有必要重新算一下先验信噪比和后验信噪比。计算方法依旧是用webRTC中语音降噪模块ANS细节详解(三)中提到的方法,这里再把数学表达式列一下:
利用后验信噪比和DD方法算先验信噪比:
在webRTC中语音降噪模块ANS细节详解(一)中讲过,维纳滤波的标准表达式是式20:
(20)
具体软件实现时对对H(k, m)做了一定的改进,如式21:
(21)
即用β替代1。β是根据设定的降噪程度来取值的,设定的降噪程度越厉害,β取值越大。同时对H(k, m)做一定的防越界处理,最大值是1(即不降噪),最小值也是根据设定的降噪程度来取值的,比如取0.5。算出的H(k, m)保存在数组inst->smooth里。
得到H(k, m)后,降噪后的语音就可以利用表达式 S(k, m) = H(k, m)Y(k,m)求出来了。
至此webRTC里的ANS就讲完了。对核心降噪部分简单总结下,先利用分位数噪声估计法得到噪声的初始估计并基于这个估计出来的噪声算后验信噪比和先验信噪比,然后基于先后验信噪比算似然比以及在带噪语音和特征条件下得到语音和噪声的概率,再利用得到的语音和噪声的概率去更新噪声的估计,从而得到更准确的噪声估计,最后基于更新后的噪声估计重新算后验信噪比和先验信噪比,根据基于先验信噪比的维纳滤波表达式去得到降噪后的语音。
webRTC中语音降噪模块ANS细节详解(四)的更多相关文章
- webRTC中语音降噪模块ANS细节详解(二)
上篇(webRTC中语音降噪模块ANS细节详解(一))讲了维纳滤波的基本原理.本篇先给出webRTC中ANS的基本处理过程,然后讲其中两步(即时域转频域和频域转时域)中的一些处理细节. ANS的基本处 ...
- webRTC中语音降噪模块ANS细节详解(三)
上篇(webRTC中语音降噪模块ANS细节详解(二))讲了ANS的处理流程和语音在时域和频域的相互转换.本篇开始讲语音降噪的核心部分,首先讲噪声的初始估计以及基于估计出来的噪声算先验信噪比和后验信噪比 ...
- webRTC中语音降噪模块ANS细节详解(一)
ANS(adaptive noise suppression) 是webRTC中音频相关的核心模块之一,为众多公司所使用.从2015年开始,我在几个产品中使用了webRTC的3A(AEC/ANS/AG ...
- python中argparse模块用法实例详解
python中argparse模块用法实例详解 这篇文章主要介绍了python中argparse模块用法,以实例形式较为详细的分析了argparse模块解析命令行参数的使用技巧,需要的朋友可以参考下 ...
- Python中random模块生成随机数详解
Python中random模块生成随机数详解 本文给大家汇总了一下在Python中random模块中最常用的生成随机数的方法,有需要的小伙伴可以参考下 Python中的random模块用于生成随机数. ...
- Java中堆内存和栈内存详解2
Java中堆内存和栈内存详解 Java把内存分成两种,一种叫做栈内存,一种叫做堆内存 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,ja ...
- angular-ngSanitize模块-$sanitize服务详解
本篇主要讲解angular中的$sanitize这个服务.此服务依赖于ngSanitize模块. 要学习这个服务,先要了解另一个指令: ng-bing-html. 顾名思义,ng-bind-html和 ...
- angular-ngSanitize模块-linky过滤器详解
本篇主要讲解angular中的linky这个过滤器.此过滤器依赖于ngSanitize模块. linky能找出文本中的链接,然后把它转换成html链接.什么意思,就是说,一段文本里有一个链接,但是这个 ...
- View绘制详解(五),draw方法细节详解之View的滚动/滑动问题
关于View绘制系列的文章已经完成了四篇了,前面四篇文章主要带小伙伴们熟悉一下View的体系的整体框架.View的测量以及布局等过程,从本篇博客开始,我们就来看看View的绘制过程.View的绘制涉及 ...
随机推荐
- FastAPI(44)- 操作关系型数据库
ORM FastAPI 可与任何数据库和任何样式的库配合使用并和数据库通信 object-relational mapping 对象关系映射 ORM 具有在代码和数据库表(关系)中的对象之间进行转换( ...
- RAC使用auto rolling的方式打补丁
11.2.0.4 RAC 某系统主库使用auto rolling的方式打补丁在一节点执行1-5,结束后然后在二节点执行1-5,结束后最后再在某个节点执行6. 1.backup GI_HOME& ...
- Blazor Webassembly多标签页开发
最近准备用Blazor Webassembly做后台开发要用到多标签页,找了半天发现绝大多数都是Blazor Server的多标签没有Webassembly.没办法只能自己想办法造轮子了. 查了许多资 ...
- PHP审计之POP链挖掘
PHP审计之POP链挖掘 前言 续上文中的php反序列化,继续来看,这个POP的挖掘思路.在其中一直构思基于AST去自动化挖掘POP链,迫于开发能力有限.没有进展,随后找到了一个别的师傅已经实现好的项 ...
- 阿里云 Serverless 再升级,从体验上拉开差距
差距都在细节上. Serverless 要成就云计算的下一个 10 年,不仅需要在技术上持续精进,也需要在产品体验上精耕细作. 近日,阿里云 Serverless 再度升级,发布了一系列围绕产品体验方 ...
- Spatial Analyst Tools(Spatial Analyst 工具)
Spatial Analyst Tools 1.区域分析 # Process: 以表格显示分区几何统计 arcpy.gp.ZonalGeometryAsTable_sa("", & ...
- 洛谷4366——最短路(dijkstra,思维,异或)
题目大意 给定一个n个点,m条边的图,每条边有边权,而每个点\(i\)也可以直接到达\(j\),代价是\(i\ xor\ j\),给定一个S和T,求S到T的最小代价 其中\(n\le100000,m\ ...
- Shell 编程 基础用法
Shell 编程 更改shell脚本权限 chmod u+x shell.sh 标准头部写法 #! /bin/bash #! /bin/dash 变量使用 a=10 print $a 读取命令行参数 ...
- Kubernetes List-Watch 机制原理与实现 - chunked
概述http chunkedwatch api 概述 Kubernetes 中主要通过 List-Watch 机制实现组件间的异步消息通信,List-Watch 机制的实现原理值得深入分析下 . 在 ...
- Java:包装类小记
Java:包装类 对 Java 中的 包装类 这个概念,做一个微不足道的小小小小记 基本数据&包装类 四类八种基本数据类型: 数据类型 关键字 内存占用 取值范围 字节型 byte 1个字节 ...