语音增强的整个过程,通常假设噪声为加性随机平稳噪声,且语音短时平稳,下面的原理描述中,都是在这两个假设前提之下来做的。整个语音增强的流程大致可以分为两大部分
一、噪声估计
二、衰减因子(有的地方也叫做增益因子)的计算
最后,把衰减因子应用于带噪语音,就可以得到我们期望的“纯净语音”。语音增强最难的部分,应该是噪声估计,而不是衰减因子的确定。因些这里重点说下噪声估计部分,要进行噪声估计的话,先要了解带噪语音的特点,根据这些特点进行噪声的估计,那么,带噪语音都有哪些特点呢?
(1)噪所对语音频谱的影响在频率上是不均匀的,有的频谱区域影响大,有的频谱区域影响小,很自然就可以想到,可以利用各频带来估计噪声,当特定频带的信噪比或者语音存在概率比较低时,可以独立更新噪声谱,这就是时间递归平均型噪声估计算法的出发点
(2)即便是在语音活动期间,单个频带的带噪语音功率通常都会衰减到噪声的功率水平,这是最小值跟踪噪声估计算法的出发点。通过在每个频带跟踪带噪语音功率的最小值,可以得到该频带噪声水平的一个粗略估计。
speex使用的噪声估计算法结合了这两个特性,我们分别说下根据上面两个特性延伸出来的两个噪声估计算法:最小值跟踪、时间递归平均。先说下最小值跟踪噪声估计算法,这类估计算法主要有三种:最小值统计、最小值搜索、连续谱最小值跟踪。
最小值统计算法是通过统计过去D帧的各频点最小值、计算相应的偏差因子来估计噪声的,具体内容请参考论文:Noise Power Spectral Density Estimation Based on Optimal Smoothing and Minimum Statistics。这里不再详细阐述。
最小值搜索是以遍历的方式查找过去D帧各频点的最小值来估计噪声的,这种方法有的地方也称为最小值查找
连续谱最小值跟踪具体内容请参考一个频域语音降噪算法实现及改进方法中的内容,这里同样也不再详述。
下面再说下时间递归平均型噪声估计算法。这种方法是要用以下的通用形式来估计噪声
\[\hat \sigma _d^2(\lambda ,k) = \alpha (\lambda ,k)\hat \sigma _d^2(\lambda - 1,k) + [1 - \alpha (\lambda ,k)]|Y(\lambda ,k){|^2}\]
这里lamda表示帧数,k表示频点索引,Y表示频域的带噪语音谱,sigma表示噪声谱,alpha表示平滑因子,这类噪声估计算法就是要求出时频相关平滑因子,然后就可以用上式来估计噪声,平滑因子可以基于信噪比来求,也可以是一个固定的值。但更常用的是基于频点k处语音存在或不存在的概率来计算,随后可以看到这个平滑因子与语音存在概率之间的关系。
先简单说下基于信噪比的递归平均噪声估计算法,他的主要思想是,当信噪比大时(表示有语音的可能性大),使平滑因子趋向于1,即倾向于使用前一帧的噪声来做为当前帧的噪声估计,当信噪比小时(表示没有语音,全是噪声可能性大),使平滑因子趋向于0,表示尽可能的用当前帧的功率来做为噪声估计。这种方法主要工作考虑是如何在信噪比与平滑因子之间建立函数关系或者分段函数关系。
再重点说下基于信号存在概率的递归平均算法。我们先看把条件概率引入时,计算噪声的方式如何变化,我们首先把噪声功率谱密度表示为
\[\sigma _d^2(\lambda ,k) = E\{ |D(\lambda ,k){|^2}\} \]
那么,在最小均方误差意义上最优的噪声功率谱密度可以表示为
\[\sigma _d^2(\lambda ,k) = E[\sigma _d^2(\lambda ,k)|Y(\lambda ,k)] = E[\sigma _d^2(\lambda ,k)|{H_0}]P({H_0}|Y(\lambda ,k)] + E[\sigma _d^2(\lambda ,k)|{H_1}]P({H_1}|Y(\lambda ,k))\]
也就是说,当引入概率时,噪声功率谱密度可以由带噪语音谱在频点k不存在语音的条件概率和存在语音的条件概率分别对不存在语音条件下的噪声功率谱密度、存在语音条件下的噪声功率谱密度进行加权、然后求和得到。
我们可以根据贝叶斯定理很容易的计算上面式子中的两个条件概率。如下所示
\[\begin{array}{l}
r \buildrel \Delta \over = P(H_1^k)/P(H_0^k) \\
\Lambda (\lambda ,k) \buildrel \Delta \over = \frac{{P(Y(\lambda ,k)|H_1^k)}}{{P(Y(\lambda ,k)|H_0^k)}} \\
P(H_0^k|Y(\lambda ,k)) = \frac{{P(Y(\lambda ,k)|H_0^k)P(H_0^k)}}{{P(Y(\lambda ,k)|H_0^k)P(H_0^k) + P(Y(\lambda ,k)|H_1^k)P(H_1^k)}} = \frac{1}{{1 + r\Lambda (\lambda ,k)}} \\
P(H_1^k|Y(\lambda ,k)) = \frac{{r\Lambda (\lambda ,k)}}{{1 + r\Lambda (\lambda ,k)}} \\
\end{array}\]
上面的4个式子中,第一个式子r表示存在语音的先验概率与不存在语音的先验概率之比、第二个式子被称为似然比。第三个式子和第四个式子分别代表频点k不存在语音的条件概率、频点k存在语音的条件概率。把上面的两个条件概率代入到求噪声功率谱密度的式子中,得到新的噪声功率谱密度估计
\[\sigma _d^2(\lambda ,k) = \frac{1}{{1 + r\Lambda (\lambda ,k)}}E[\sigma _d^2(\lambda ,k)|{H_0}] + \frac{{r\Lambda (\lambda ,k)}}{{1 + r\Lambda (\lambda ,k)}}E[\sigma _d^2(\lambda ,k)|{H_1}]\]
当频点k不存在语音时,我们可以将不存在语音条件下的噪声功率谱均值用当前频点的短时功率谱近似、当频点k存在语音时,我们可以将存在语音条件下的噪声功率谱均值近似为前一帧的噪声估计,如下所示:
\[\begin{array}{l}
E[\sigma _d^2(\lambda ,k)|{H_0}] \Rightarrow |Y(\lambda ,k){|^2} \\
E[\sigma _d^2(\lambda ,k)|{H_1}] \Rightarrow \sigma _d^2(\lambda - 1,k) \\
\end{array}\]
这样,估计噪声就变成了如下的形式
\[\sigma _d^2(\lambda ,k) = \frac{{r\Lambda (\lambda ,k)}}{{1 + r\Lambda (\lambda ,k)}}\sigma _d^2(\lambda - 1,k) + \frac{1}{{1 + r\Lambda (\lambda ,k)}}|Y(\lambda ,k){|^2}\]
对比上述的递归表达式与时间递归平均噪声估计的通用形式可以发现,时频相关平滑因子alpha在意义上代表频点k存在语音的条件概率。即:
\[\begin{array}{*{20}{c}}
{\alpha (\lambda ,k) = \frac{{r\Lambda (\lambda ,k)}}{{1 + r\Lambda (\lambda ,k)}}} & {1 - \alpha (\lambda ,k) = \frac{1}{{1 + r\Lambda (\lambda ,k)}}} \\
\end{array}\]
也就是说,平滑因子是似然比的函数,并与语音存在的概率相关,当频点k存在语音的条件概率越大时,越倾向于使用前一帧的噪声估计,相当于越倾向于停止噪声估计。反之,就越倾向于继续使用当前频点k的功率来估计噪声。
现在我们已经介绍了最小值跟踪、时间递归平均两类噪声估计方法。那么,能不能同时使用这两种估计方法来使得噪声的估计更加准确呢。还真是可以的,这种方法就是最小值控制的递归平均(MCRA)算法。下面就来看下,这种方法的思路及出发点。这里噪声更新的思路是:当语音不存在时,更新噪声的估计,当语音存在时,用前一帧的噪声估计值做为当前帧的噪声估计值。如下所示
\[\begin{array}{l}
H_0^k:\hat \sigma _D^2(\lambda ,k) = \alpha \hat \sigma _D^2(\lambda - 1,k) + (1 - \alpha )|Y(\lambda ,k){|^2} \\
H_1^k:\hat \sigma _D^2(\lambda ,k) = \hat \sigma _D^2(\lambda - 1,k) \\
\end{array}\]
于是,噪声功率谱密度的均方估计可以表示如下:
\[\begin{array}{l}
\hat \sigma _d^2(\lambda ,k) = E[\sigma _d^2(\lambda ,k)|Y(\lambda ,k)] \\
= E[\sigma _d^2(\lambda ,k)|H_0^k]p(H_0^k|Y(\lambda ,k)) + E[\sigma _d^2(\lambda ,k)|H_0^k]p(H_1^k|Y(\lambda ,k)) \\
= [\alpha \hat \sigma _D^2(\lambda - 1,k) + (1 - \alpha )|Y(\lambda ,k){|^2}]p(H_0^k|Y(\lambda ,k)) + \hat \sigma _D^2(\lambda - 1,k)p(H_1^k|Y(\lambda ,k)) \\
= [\alpha \hat \sigma _D^2(\lambda - 1,k) + (1 - \alpha )|Y(\lambda ,k){|^2}](1 - p(\lambda ,k)) + \hat \sigma _D^2(\lambda - 1,k)p(\lambda ,k) \\
= [\alpha \hat \sigma _D^2(\lambda - 1,k)(1 - p(\lambda ,k)) + \hat \sigma _D^2(\lambda - 1,k)p(\lambda ,k)] + (1 - \alpha )|Y(\lambda ,k){|^2}(1 - p(\lambda ,k)) \\
= [\alpha (1 - p(\lambda ,k)) + p(\lambda ,k)]\hat \sigma _D^2(\lambda - 1,k) + [(1 - \alpha )(1 - p(\lambda ,k))]|Y(\lambda ,k){|^2} \\
= [\alpha + \alpha p(\lambda ,k) + p(\lambda ,k)]\hat \sigma _D^2(\lambda - 1,k) + [1 - p(\lambda ,k) - \alpha + \alpha p(\lambda ,k)]|Y(\lambda ,k){|^2} \\
= [\alpha + (1 - \alpha )p(\lambda ,k)]\hat \sigma _D^2(\lambda - 1,k) + [1 - \alpha - (1 - \alpha )p(\lambda ,k)]|Y(\lambda ,k){|^2} \\
= [\alpha + (1 - \alpha )p(\lambda ,k)]\hat \sigma _D^2(\lambda - 1,k) + [1 - (\alpha + (1 - \alpha )p(\lambda ,k)]|Y(\lambda ,k){|^2} \\
\end{array}\]
其中,上式中的
\[p(\lambda ,k) = p(H_1^k|Y(\lambda ,k))\]
表示语音存在的概率。最终,噪声功率谱密度的均方估计可以化简为:
\[\begin{array}{*{20}{c}}
{\hat \sigma _d^2(\lambda ,k) = {\alpha _d}(\lambda ,k)\hat \sigma _d^2(\lambda - 1,k) + [1 - {\alpha _d}(\lambda ,k)]|Y(\lambda ,k){|^2}} & {{\alpha _d}(\lambda ,k) \buildrel \Delta \over = \alpha + (1 - \alpha )p(\lambda ,k)} \\
\end{array}\]
从上面的推导过程我们可以看到,MCRA算法的主要流程是:
(1)先用最小值跟踪法获得带噪语音的最小值,它代表的是对噪声的初步估计
(2)再利用这个最小值来计算语音存在的概率p
(3)根据上式计算噪声估计的平滑因子
(4)利用递归平均来估计噪声
speex的噪声估计就是采用的这种思路,具体细节就不多说了,详细问题可以到下面的群里讨论!