天天看點

webRTC AEC 遠場濾波器

最後幾句代碼将遠場經過濾波之後加到了傳入的yf(合成回聲信号)中,但是在調用本濾波器之前已經将yf全部設定為0了,是以輸出的合成回聲信号就是濾波器的輸出。

static void FilterFarSSE2(AecCore* aec, float yf[2][PART_LEN1]) {
  int i;
  // 設定分塊數
  const int num_partitions = aec->num_partitions;
  // 按塊循環計算
  for (i = 0; i < num_partitions; i++) {
    int j;
	// 指針指向目前塊的開始位置
    int xPos = (i + aec->xfBufBlockPos) * PART_LEN1;
    int pos = i * PART_LEN1;
    // 邊界檢查,如果超出了邊界則回到第一塊的開始
    if (i + aec->xfBufBlockPos >= num_partitions) {
      xPos -= num_partitions * (PART_LEN1);
    }

    // 向量計算
    for (j = 0; j + 3 < PART_LEN1; j += 4) {
		// 載入遠場資料的實部、虛部
      const __m128 xfBuf_re = _mm_loadu_ps(&aec->xfBuf[0][xPos + j]);
      const __m128 xfBuf_im = _mm_loadu_ps(&aec->xfBuf[1][xPos + j]);
	  // 載入權值系數的實部、虛部
      const __m128 wfBuf_re = _mm_loadu_ps(&aec->wfBuf[0][pos + j]);
      const __m128 wfBuf_im = _mm_loadu_ps(&aec->wfBuf[1][pos + j]);
	  // 載入合成回聲的實部、虛部
      const __m128 yf_re = _mm_loadu_ps(&yf[0][j]);
      const __m128 yf_im = _mm_loadu_ps(&yf[1][j]);
	  // 複數*複數 = 實部*實部 + 虛部*虛部 + 虛實交叉相乘 + 實虛交叉相乘
      const __m128 a = _mm_mul_ps(xfBuf_re, wfBuf_re);
      const __m128 b = _mm_mul_ps(xfBuf_im, wfBuf_im);
      const __m128 c = _mm_mul_ps(xfBuf_re, wfBuf_im);
      const __m128 d = _mm_mul_ps(xfBuf_im, wfBuf_re);
	  // e=實數結果
      const __m128 e = _mm_sub_ps(a, b);
	  // f=虛數結果
      const __m128 f = _mm_add_ps(c, d);
	  // 實數結果加到合成回聲的實部,虛數結果加到合成回聲的虛部,
	  //但是在調用本濾波器之前memset(yf, 0, sizeof(yf));已經設定為0了
      const __m128 g = _mm_add_ps(yf_re, e);
      const __m128 h = _mm_add_ps(yf_im, f);
	  // 将計算結果存儲到合成回聲中
      _mm_storeu_ps(&yf[0][j], g);
      _mm_storeu_ps(&yf[1][j], h);
    }
    // scalar code for the remaining items.
    for (; j < PART_LEN1; j++) {
      yf[0][j] += MulRe(aec->xfBuf[0][xPos + j],
                        aec->xfBuf[1][xPos + j],
                        aec->wfBuf[0][pos + j],
                        aec->wfBuf[1][pos + j]);
      yf[1][j] += MulIm(aec->xfBuf[0][xPos + j],
                        aec->xfBuf[1][xPos + j],
                        aec->wfBuf[0][pos + j],
                        aec->wfBuf[1][pos + j]);
    }
  }
}
           

繼續閱讀