先驗信噪比估計
很多降噪算法如維納濾波、MMSE估計器等都依賴先驗信噪比(priori SNR)信息
定義先驗信噪比(priori SNR)、後驗信噪比(posteriori SNR)如下
上式中的爲目標信號的幅度譜、爲噪聲的功率譜,這裏先假定噪聲平穩且可以在無語音段估計得到。
假設噪聲和語音不相關且爲加性噪聲,則可以寫成下式
一般所說的SNR就是指先驗信噪比,維納濾波器就是關於先驗信噪比的函數
後驗信噪比也叫瞬時信噪比,如譜減公式中用到的就是後驗信噪比
因爲譜減法是直接使用瞬時信噪比,因此會更容易產生音樂噪聲,當然,也有很多的改進方法減小音樂噪聲的影響。
合併(1)、(3)兩式得到以下形式
這裏還有一個煩人的期望符號,還是老方法,用一階遞歸平滑代替時間平均,則估計得到的爲下式:
其中表示上一幀的幅度估計值。
(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.
}