1.概要
WebRTCで雑音抑圧処理用の関数は基本下記になります:
WebRtcNs_Create
WebRtcNs_Init
WebRtcNs_set_policy
WebRtcNs_Analyze
WebRtcNs_Process
WebRtcNs_Free
初期化と最後のフリーを除いて、中心の処理は下記の二つになります:
WebRtcNs_Analyze
WebRtcNs_Process
2.雑音抑圧の基本アルゴリズム
2.1 雑音抑圧の実行関数
WebRtcNs_Processで呼び出されたWebRtcNs_ProcessCore
2.2 処理ロジック
1.インプットした音声データ(RTP payload)により、音声コンテキストを更新する
2.音声データに対して、高速フーリエ変換(FFT)を行う
3.音声データをWienerフィルタに入力し、雑音抑圧を行う(ComputeDdBasedWienerFilter)
4.音声データに対して、逆高速フーリエ変換(IFFT)を行う
※波形調整関連の処理は省略
2.3 Wienerフィルタの実現コード
static void ComputeDdBasedWienerFilter(const NoiseSuppressionC* self, const float* magn, float* theFilter)
{
size_t i;
float snrPrior, previousEstimateStsa, currentEstimateStsa;
for (i = 0; i < self->magnLen; i++) {
// Previous estimate: based on previous frame with gain filter.
previousEstimateStsa = self->magnPrevProcess[i] /
(self->noisePrev[i] + 0.0001f) * self->smooth[i];
// Post and prior SNR.
currentEstimateStsa = 0.f;
if (magn[i] > self->noise[i]) {
currentEstimateStsa = magn[i] / (self->noise[i] + 0.0001f) - 1.f;
}
// DD estimate is sum of two terms: current estimate and previous estimate.
// Directed decision update of |snrPrior|.
snrPrior = DD_PR_SNR * previousEstimateStsa +
(1.f - DD_PR_SNR) * currentEstimateStsa;
// Gain filter.
theFilter[i] = snrPrior / (self->overdrive + snrPrior);
} // End of loop over frequencies.
}
3.雑音抑圧の効果
3.1 雑音抑圧無し
3.2 雑音抑圧あり
雑音抑圧無しと比較して、下の波形では、明らかにノイズが抑制されています。
一番下の波形図の黒い枠のところはフィルタの学習フェーズであり、赤い枠のところは作業フェーズです。
通話開始時や音声が著しく変化する場合、フィルタの学習にはある程度の時間がかかり、この時の雑音抑圧効果は比較的弱いことがわかります。これは、Wienerフィルタの性質とも一致しています。