上篇(webRTC中語音降噪模塊ANS細節(jié)詳解(一))講了維納濾波的基本原理。本篇先給出webRTC中ANS的基本處理過程,然后講其中兩步(即時域轉(zhuǎn)頻域和頻域轉(zhuǎn)時域)中的一些處理細節(jié)。
?
ANS的基本處理過程如下圖1:
?
???????????????????????????????????????? 圖1
從圖1可以看出,處理過程主要分6步,具體如下:
1)? 把輸入的帶噪信號從時域轉(zhuǎn)到頻域,主要包括分幀、加窗和短時傅里葉變換(STFT)等
2)? 做初始噪聲估計,基于估計出的噪聲算先驗信噪比和后驗信噪比
3)? 計算分類特征,這些特征包括似然比檢驗(LRT)、頻譜平坦度和頻譜差異。根據(jù)這些特征確定語音/噪聲概率,從而判定當前信號是語音還是噪聲。
4)? 根據(jù)算出來的語音/噪聲概率去更新噪聲估計
5)? 基于維納濾波去噪
6)? 把去噪后的信號從頻域轉(zhuǎn)換回時域,主要包括短時傅里葉逆變換(ISTFT)、加窗和重疊相加等。
?
我用于理解和調(diào)試的版本是以前的C版本,里面又分為浮點和定點兩種實現(xiàn)方式。對于算法理解來說,最好看浮點實現(xiàn)的版本,因為它能和算法原理中的數(shù)學(xué)表達式很好的聯(lián)系起來。定點實現(xiàn)中有很多諸如定標等工程實現(xiàn)上的技巧,跟數(shù)學(xué)表達式很難直接聯(lián)系。部署時如有l(wèi)oad等制約因素,最好用定點的實現(xiàn),因為通常定點實現(xiàn)的load比浮點實現(xiàn)的小不少。ANS支持8k/16k/32k HZ等三種采樣率。對于語音來說,最常用的是16k HZ的,本文以及后續(xù)的均設(shè)定采用率為16k HZ。語音信號處理時以幀為單位,ANS中一幀為10 ms,可以算出一幀是160個采樣點。語音信號處理又通常在頻域下進行的,因此先要把時域信號變成頻域信號,處理后再把頻域信號變回時域信號。時域信號變頻域信號在ANS降噪處理過程的開始部分,頻域信號變時域信號在ANS降噪處理過程的結(jié)束部分,但它們是相對稱的,且它們與降噪處理算法無關(guān),因此把它們放在一起講。下面講講時頻互轉(zhuǎn)中的一些細節(jié)。
?
先看從時域信號變成頻域信號。主要步驟是分幀、加窗和做短時傅里葉變換(STFT)。分幀上面說過,10 ms一幀,每幀160個采樣點。加窗的目的是避免頻譜泄漏。有多種窗函數(shù),常見的有矩形窗、三角窗、漢寧(hanning)窗和海明(hamming)窗等。語音處理中常用的是漢寧窗和海明窗。ANS中用的是漢寧窗和矩形窗混在一起的混合窗。做STFT要求點數(shù)是2的N次方,現(xiàn)在每幀160個點,大于160的最近的2的N次方是256,所以STFT一次處理256個點(這也是代碼中256(#define ANAL_BLOCKL_MAX ?256)的由來)?,F(xiàn)在每幀160個點,需要補成256個點。一種做法是在160個點后面補零補成256個點。ANS用了一種更好的方法。用上一幀的尾部的96個點來補從而形成256個點。這樣從時域信號變成頻域信號的處理流程如下圖2:
???????????????????????????????????????????????????? 圖2
因為對256點做STFT,所以加窗的點數(shù)也是256。ANS用的是窗是漢寧和矩形混合窗。漢寧窗函數(shù)是w(n) = 0.5 * (1 + cos(2*pi*n / (N-1))),范圍是(0,1),波形如下圖3。
??????????????????????????????????? 圖3
這個混合窗是把192(96*2)點的漢寧窗在頂點處插入64點的幅值為1的矩形窗,從而形成256(256 = 192 + 64)點的混合窗,波形如下圖4。
??????????????????????????????????????? 圖4
至于為什么要這么做,后面講頻域轉(zhuǎn)換到時域時再說。256個點的值與相應(yīng)的窗函數(shù)相乘,得到要送進STFT處理的值。STFT處理后得到256個頻點的值,這些值除了第0點和第N/2點(N=256,即第128點)點是實數(shù)外,其余點都是復(fù)數(shù),且關(guān)于第N/2點共軛對稱。因為共軛對稱,一個點知道了,它的對稱點就可以求出來。所以STFT處理后有(N/2 + 1)個點的值。這里N=256,STFT的輸出是129個點的值。這也是代碼中129(#define HALF_ANAL_BLOCKL ?129)的由來。得到129個頻點的值后還要算每個頻點的幅度譜和能量等,用于后面降噪算法,具體處理如下面代碼,已給出詳細的注釋,就不細說了。
在頻域做完降噪處理后需要把信號從頻域變回時域,即信號的重建或者合成,主要步驟是做短時傅里葉反變換(ISTFT)、加窗和重疊相加(overlap add, OLA)等,處理流程如下圖5。
??????????????????????????????????? 圖5
先做ISTFT(短時傅里葉反變換),得到256點的實數(shù)值。這256點包括上一幀的尾部的96點,即有重疊。該怎么拼接保證聲音連貫?zāi)??上面講從時域到頻域變換時用的窗是漢寧矩形混合窗,漢寧窗前半部分(頭部96點)類似于做正弦操作,后半部分(尾部96點)類似于做余弦操作。重疊部分是在上一幀的尾部,加窗做的是類余弦操作,在當前幀是頭部,加窗做的是類正弦操作。信號重建疊加時一般要求能量或者幅值不變,能量是幅值的平方。那些重疊的點(假設(shè)幅值為m)在上一幀中加窗時做了類余弦操作,加窗后幅值變成了m*cosθ,在當前幀中加窗時做了類正弦操作,加窗后幅值變成了m*sinθ,能量和為m2*cos2θ + m2*sin2θ, 正好等于m2(原信號的能量),這說明只要把重疊部分相加就可以保證語音信號的連貫了。這就解釋了代碼中把ISTFT后的值再做一次加窗操作并把重疊部分相加的原因。具體代碼見下圖6。
?????????????????????????????????????????????????? 圖6
至于矩形窗部分,幅值為1,即加窗后信號幅值不變,因而不需要做處理,直接填上就可以了。需要注意的是圖6中還有一個能量縮放因子factor。它在前200幀默認為1,后續(xù)幀按如下邏輯關(guān)系得到。
圖7給出了做完ISTFT后數(shù)據(jù)拼接的示意圖。做完ISTFT后有256點數(shù)據(jù),當前幀的頭部96點數(shù)據(jù)與上一幀的尾部96點數(shù)據(jù)相加,中間64點數(shù)據(jù)不變,當前幀尾部96點數(shù)據(jù)與下一幀的頭部96點數(shù)據(jù)相加,這樣就能很好的拼接處連貫的語音數(shù)據(jù)了。
????????????????????????????????????????????????? 圖7
下篇將講噪聲的初始估計以及基于估計出來的噪聲算先驗信噪比和后驗信噪比。
?
?
本文摘自 :https://www.cnblogs.com/