先驗信噪比估計

先驗信噪比估計

很多降噪算法如維納濾波、MMSE估計器等都依賴先驗信噪比(priori SNR)信息

定義先驗信噪比(priori SNR)、後驗信噪比(posteriori SNR)如下
ξk(n)=E{Ak2(n)}λd(k,n)(1) \xi_{k}(n)=\frac{E\left\{A_{k}^{2}(n)\right\}}{\lambda_{d}(k, n)}\tag1

γk(n)=Yk2(n)λd(k,n)(2) \gamma_k(n)=\frac{{Y_{k}^{2}(n)}}{\lambda_{d}(k, n)}\tag2

上式中的Ak(n)A_{k}(n)爲目標信號的幅度譜、λd(n)\lambda_d(n)爲噪聲的功率譜,這裏先假定噪聲平穩且可以在無語音段估計得到。

假設噪聲和語音不相關且爲加性噪聲,則ξk\xi_k可以寫成下式
ξk(n)=E{Ak2(n)}λd(k,n)=E{Yk2(n)λd(k,n)}λd(k,n)=E{Yk2(n)}λd(k,n)1=E{λk(n)1}(3) \begin{aligned}\xi_{k}(n)&=\frac{E\left\{A_{k}^{2}(n)\right\}}{\lambda_{d}(k, n)}\\&=\frac{E\left\{Y_{k}^{2}(n)-\lambda_d(k,n)\right\}}{\lambda_{d}(k, n)}\\&=\frac{E\left\{Y_{k}^{2}(n)\right\}}{\lambda_{d}(k, n)}-1\\&=E\left\{\lambda_{k}(n)-1\right\}\end{aligned}\tag3

一般所說的SNR就是指先驗信噪比,維納濾波器就是關於先驗信噪比的函數
W=ξ1+ξ(4) W=\frac{\xi}{1+\xi}\tag4
後驗信噪比也叫瞬時信噪比,如譜減公式中用到的就是後驗信噪比
A2=Y2λd=1λd(γ1)(5) \begin{aligned}A^2&=|Y|^2-\lambda_d\\&=\frac{1}{\lambda_d}(\gamma-1)\end{aligned}\tag5
因爲譜減法是直接使用瞬時信噪比,因此會更容易產生音樂噪聲,當然,也有很多的改進方法減小音樂噪聲的影響。

合併(1)、(3)兩式得到以下形式
ξk(n)=E{12Ak2(n)λd(k,n)+12[γk(n)1]}(6) \xi_k(n)=E\begin{Bmatrix}\frac{1}{2}\frac{A_{k}^{2}(n)}{\lambda_{d}(k, n)}+\frac{1}{2}[\gamma_k(n)-1]\end{Bmatrix}\tag6
這裏還有一個煩人的期望符號EE,還是老方法,用一階遞歸平滑代替時間平均,則估計得到的ξk(n)\xi_k(n)爲下式:
ξk^(n)=αA^k2(n1)λd(k,n1)+(1α)max(γk(n)1,0)(7) \hat{\xi_k}(n)=\alpha\frac{\hat{A}_k^2(n-1)}{\lambda_d(k,n-1)}+(1-\alpha)max(\gamma_k(n)-1,0)\tag7
其中A^k2(n1)\hat{A}_k^2(n-1)表示上一幀的幅度估計值。

(7)式就是著名的判決引導(Dicision-Directed)公式,被廣泛用在了降噪算法的大街小巷裏

例如,webrtc的單通道降噪算法源碼裏可以看到如下模塊

// Compute prior and post SNR based on quantile noise estimation.
// Compute DD estimate of prior SNR.
// Inputs:
//   * |magn| is the signal magnitude spectrum estimate.
//   * |noise| is the magnitude noise spectrum estimate.
// Outputs:
//   * |snrLocPrior| is the computed prior SNR.
//   * |snrLocPost| is the computed post SNR.
static void ComputeSnr(const NoiseSuppressionC *self,
                       const float *magn,
                       const float *noise,
                       float *snrLocPrior, float *logSnrLocPrior,
                       float *snrLocPost) {
    size_t i;

    for (i = 0; i < self->magnLen; i++) {
        // Previous post SNR.
        // Previous estimate: based on previous frame with gain filter.
        float previousEstimateStsa = self->magnPrevAnalyze[i] /
                                     (self->noisePrev[i] + 0.0001f) * self->smooth[i];
        // Post SNR.
        snrLocPost[i] = 0.f;
        if (magn[i] > noise[i]) {
            snrLocPost[i] = magn[i] / (noise[i] + 0.0001f) - 1.f;
        }
        // DD estimate is sum of two terms: current estimate and previous estimate.
        // Directed decision update of snrPrior.
        snrLocPrior[i] = 2.f * (
                DD_PR_SNR * previousEstimateStsa + (1.f - DD_PR_SNR) * snrLocPost[i]);
        logSnrLocPrior[i] = logf(snrLocPrior[i] + 1.0f);
    }  // End of loop over frequencies.
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章