上篇(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就讲完了。对核心降噪部分简单总结下,先利用分位数噪声估计法得到噪声的初始估计并基于这个估计出来的噪声算后验信噪比和先验信噪比,然后基于先后验信噪比算似然比以及在带噪语音和特征条件下得到语音和噪声的概率,再利用得到的语音和噪声的概率去更新噪声的估计,从而得到更准确的噪声估计,最后基于更新后的噪声估计重新算后验信噪比和先验信噪比,根据基于先验信噪比的维纳滤波表达式去得到降噪后的语音。