你好,我是建元。今天我们来聊聊噪声的分类与常见的降噪方法。
听到噪声,很多人可能首先想到的是深夜的广场舞曲、呼啸的东北风、车水马龙的呼啸而过。但其实噪声是一个相对的概念。如果你想听的目标只有人们说话的声音,那么所有其它的声音包括音乐、 风声等其就都是噪声,而如果你想听鸟语虫鸣,那人声对你来说也是噪声。
在这里我们主要聊的是当保留目标是人声时,噪声会有哪些分类,它们有什么特点,以及我们如何更好地保留人声去除噪声。这也是音视频工程师的主要工作场景。
从通信系统的角度来说,噪声可以分为加性噪声和乘性噪声。
加性噪声与信号之间满足加性条件,即加噪信号是由噪声和源信号相加得到的,这种情况下信号和噪声是不相关的,我们常见的自然噪声、人造的噪声如电子元器件发出的热噪声等都是这种。
乘性噪声则是,噪声和信号是相关联的,比如信号的衰减、房间的混响、多普勒效应等。这类噪声往往是以信号乘积的形式出现,而且往往是从信道传输中产生,所以也叫信道噪声。我们这里主要讲的是人声与其它不相关的噪声的处理,所以主要是针对加性噪声来讲。
加性噪声的种类如果按照声源,比如风声、汽笛声、键盘敲击声等,种类则成千上万,但从降噪方法的选择角度上来说,我们可以按照噪声是否平稳,把噪声分为两类:稳态噪声和非稳态噪声。
稳态噪声和非稳态噪声的时域图和频域图如图1所示:
很显然,稳态噪声由于在时间维度上没有变化,我们很容易通过对之前出现过的噪声进行建模,然后用相同的模型来对以后出现的噪声来进行抑制。而非稳态噪声尤其是瞬态噪声,则需要更多的依靠来区分其和正常语音之间的差异。如果更像是语音,则将其保留,反之则将其抑制。
值得注意的是,这些噪声往往不是单独存在的,可能你的手机底噪是一直存在的,同时你又在人声鼎沸的地铁站,那这时候稳态和瞬态噪声就都会存在。
清楚了噪声的分类后,接下来让我们看看目前有哪些常见的降噪算法,以及它们在降噪的能力上有哪些不同。这里我们重点介绍基于统计模型的实时降噪算法,这是因为在实时音频降噪处理时主要应用的就是这种算法。另外,基于机器学习的降噪是基于AI的,因此之后会单独开一讲。至于其他三种算法,这里你有个简单了解就足够了。
这在一些音频采集硬件的噪声处理中十分常见,因为硬件厂商知道自己的硬件噪声特性。比如由于电路设计在一些频段会有持续的电流声,这时可以采用一些比如高通滤波器来消除低频噪声、用一些陷波滤波器来消除某些频段的持续噪声。
线性滤波器的处理方法算力要求十分低,但必须事先知道噪声会在哪个频段出现。所以在实际使用中一般会先做噪声频段检测,看看噪声出现在哪个或哪些频段,再设计线性滤波器或滤波器组来消除噪声。
谱减法的核心思想是先取一段非人声段音频,记录下噪声的频谱能量,然后从所有的音频频谱中减去这个噪声频谱能量。这种方法对稳态噪声比较有效果。但如果是非稳态噪声就会导致有的地方频谱减少了噪声有残留,有的地方频谱减多了人声有损伤。所以谱减法一般用于离线稳态噪声的降噪处理。离线的时候可以人工对音频进行分片处理,在每一个分片中噪声可以控制成稳态的。而在实时音频处理的时候,噪声状态经常是随时间变化的,我们很难让噪声一直保持绝对稳态。
这类算法是实时音频降噪时最常用的算法类别。算法的思想就是利用统计的方法估算出音频频谱中每个频点所对应的噪声和语音的分量。基于统计的降噪方法其实都是针对相对平稳的噪声进行去除,且为了方便找出噪声和人声的直观统计区别,一般都需要基于两个假设。
第一个假设:噪声相对于人声一定是在时域和频域上的声学统计特性都更平稳。
第二个假设: 所有的噪声都满足加性条件。
所以基于这两个假设,我们就可以解释很多我们平时在使用这些降噪算法时所遇到的现象。比如噪声中的瞬态噪声很难被抑制,比如敲桌子的声音、键盘声之类的。再比如在一些混响比较大的房间,听不出混响,且人声的失真也比较严重。了解了以上特性之后,让我们看看常见的几种基于统计的降噪。
这里我主要介绍一下常用的分位数噪声估计和维纳滤波(Quantile Noise Estimation and Winner Filter)以及一些改进方法,比如OMLSA & IMCRA(Optimally Modified Log-Spectral Amplitude Estimator and Improved Minima Controlled Recursive Averaging)。分位数噪声估计和维纳滤波这种方法是WebRTC中自带的降噪算法。
维纳滤波是根据最小均方误差MMSE准则(滤波器的输出信号与需要信号之差的均方值最小)设计的线性滤波器。我们这里用到的是实时频域维纳滤波器,目标就是求出当前帧每个频点的能量有多少占比是语音,即语音的先验信噪比(SNR)。我们把当前帧的含噪信号与噪声的信噪比叫做后验信噪比,而纯净语音信号与噪声的信噪比叫先验信噪比。
因为在实时处理时没有纯净的参考信号,所以先验信噪比通常为后验信噪比结合判决引导的方法来估算。那么根据维纳滤波的原理降噪的步骤也就变成了从动态平滑的噪声模型得到噪声信号,然后根据含噪信号和噪声模型经过维纳滤波器进行降噪。
WebRTC中的降噪流程如图2所示。
首先,做短时傅里叶变换(STFT),即对带噪信号加窗。接着,做快速傅里叶变换(FFT)再求模得到带噪信号的功率谱。然后,利用功率谱进行分位数噪声估计(Quantile Noise Estimation)、语音存在概率(Speech Presence Probability)估计、噪声更新(Noise Update)以及噪声抑制系数计算(Spectral Gain Computation)。最后,把得到的每个频点的抑制系数乘以带噪信号的频率谱得到降噪后的频率谱。再做逆短时傅里叶变换(ISTFT)即可得到降噪后的时域信号。
这里就不一一展开了,内容很多,具体每一步怎么做你可以参考Google的WIPO 专利(Noise Suppression Method and Apparatus Using Multiple Feature Modeling for Speech/noise Likelihood),里面和WebRTC开源库中的代码基本可以一一对应。
我们这里主要讲一下使用分位数噪声估计和维纳滤波的降噪算法逻辑背后的思考。
基于统计的降噪最主要的是对噪声进行实时建模,这个建模基于假设一,也就是说只对稳态的噪声进行建模。噪声模型迭代不能太快,比如这里WebRTC所用的分位数噪声估计都是在时频域上进行更新,且其更新周期大概为700ms左右。从听感上来说,如果噪声发生了变化,比如突然变大了,模型可能需要约500ms~4s来收敛到新的噪声模型,在这期间我们可能会听到一些噪声的残余。
这里降噪的理念和我们之前讲的谱减法有些类似,就是利用无人声段进行噪声的估计。这样在实时处理中就需要在无人声段进行噪声模型的迭代。即更新噪声模型以适应非稳态噪声的时变性。
那么为了区分人声和非人声就需要做一个人声判别也就是我们常说的VAD(Voice Activity Detection)。这里的VAD就是利用几个人工提取的特征来进行统计得出的语音存在概率来判断的。这几个特征包括:频谱平坦度(Spectral Flatness ), 频谱差异度(Spectral Difference),以及根据先验、后验信噪比的差异得出的似然因子LR(Likelihood Ratio)Factor。具体如图3所示:
似然因子在频域计算log均值得到indicator 0,而根据频谱平坦度和差异度则可以分别得到indicator 1 和 2。语音概率值就是根据这几个指标的加权平均(对应图中的combination)和当前帧的似然因子来更新的。在实际计算中,当这个概率比较大时,也就是语音存在的可能性比较大,噪声模型的更新就很缓慢,反之则更新速度比较快。
噪声模型则是通过分位数噪声估计来得到。“Quantile”是英文中1/4的意思。这里也就是通过一个经验假设在噪声能量谱中,里面能量最小的1/4是稳态噪声。我们应该用这个部分来迭代更新初始噪声模型。
利用初始噪声模型以及含噪语音就可以得到频谱平坦度、频谱差异度,以及对数似然比特征,进而得到语音存在概率。有了语音存在概率,就可以更新噪声模型。有了噪声模型和含噪信号,那么根据加性假设,干净的语谱则是含噪信号减去噪声信号或者说含噪频谱乘以频谱增益。
了解了算法原理后,我们基本上就可以总结出WebRTC原生降噪算法的3个特点了:
这里简单介绍一下改进方法OMLSA&IMCRA算法。
它是由Israel Cohen提出的音频降噪算法。OMLSA是对人声进行估计,通过先验无声概率及先验信噪比SNR的估计来得到有声条件概率,从而实现了对人声谱的估计。IMCRA则是通过信号的最小值跟踪,得到先验无声概率估计和先验信噪比估计,来计算得到条件有声概率,进而获取噪声谱的估计。
将OMLSA同IMCRA相结合最后相当于是功率谱中最小点的追踪。这样藏在谐波之间的音乐噪声的能量由于明显小于谐波的能量就可以被去除了,这也是为什么这一算法可以有效减少音乐噪声。
关于WebRTC原生降噪和OMLSA&IMCRA降噪的对比如图4所示:
从上图可以看出通过OMLSA&IMCRA降噪比WebRTC原生降噪得到的语谱更干净,残留噪声更少。
子空间算法主要是针对一些已知噪声类型,量身定做一个降噪算法。其思想就是把噪声和人声投影到一个高纬度的空间,让本来不容易分离的信号变成在高纬度占据一个可分的子空间,从而可分的信号。这类算法包括非负矩阵分解和字典法建模等。
什么时候会用到这种算法呢?比如你只是要去除风噪这一种噪声,你可以用非负矩阵分解的方式单独为风噪建模,从而模型会自动消除音频中的风噪。这个在去风噪的场景下效果也是不错的。但这类方法缺点也很明显,每一种噪声都得单独建模,在噪声类型不定的情况下就很难穷尽达到好的效果。这里我们可以看一下基于非负矩阵分解的降噪。如图5所示:
从上图可以看出通过非负矩阵分解来消除鼠标声,降噪之后的那些鼠标点击产生的黑色竖条就被消除了。
这块最近还是比较火热的。它是通过数据训练的方式,训练人工神经网络来进行降噪。特点是噪声鲁棒性好,能兼顾稳态、非稳态甚至是瞬态噪声。比如图6中咖啡馆的噪声属于混合类型的噪声,传统降噪算法对语谱的损伤就很大,很多高频信息都丢失了,而使用AI算法在保留语谱的同时又起到了比较好的降噪效果。这块我会在下节课带你详细了解一番。
这里讲了很多噪声的类型以及如何消灭它们的方法。其实如果宏观地从整条音频链路的角度上来说,我们在实时音频中大部分采集的音频就是单通道了,这里介绍的算法也都是单通道降噪算法。如果采集的时候可以用多个麦克风或者麦克风阵列,则可以使用波束形成的方法先锁定声源方向来收音,比如选择说话人的方向来收音。这样采集来的信号,信噪比就比较高了,再通过单通道降噪就可以事半功倍。
这里我们用图7来总结一下噪声分类和5种降噪算法及其适用范围:
你可以针对不同的噪声类型选择合适的降噪算法。在实际使用的时候还必须结合应用场景的需要来权衡算法的复杂度来解决主要矛盾。比如,现在很多TWS耳机都是自带降噪算法的,但是耳机上的DSP芯片的算力有限,可能就用单个子空间算法来解决一下耳机常见的风噪就可以了。
还有一些音乐场景我们可能需要牺牲一些降噪性能对降噪的幅度做限制。比如,每个频点最多只能降3dB,这样来保证音乐信号不会被削弱。所以你在实际的使用中可以从全局出发多问问自己:我应用的场景是什么?我最关心的效果是哪些?
现在请你思考一下,你在平时的远程会议里,或者微信电话里的噪声是什么类型的?在使用不同的实时互动App的时候,你也可以试试键盘或者鼠标的声音是否还能听得见,是不是可以根据降噪效果猜一下这些App里面用的是什么样的降噪算法?
你可以把你的答案和感受写下来,分享到留言区,与我一起讨论。我们下节课再见。