回声消除简单分析

 

原因:由于需要对webRTC源码中audio_processing模块中回声消除验证,故在此进行模块分析。

概况:通过将audio_processing模块单独调用,通过wavapi进行播放和采集用于测试回声消除模块。

回声消除介绍:实时语音通话中,子所以会产生回声的原因是A通话者的声音被麦克风采集后通过网络发送到远端B,远端B扬声器播放出来的声音又被麦克风进行采集后通过网络发送给A,由于网络延迟和数据处理耗时等使得A能够从扬声器中听到自己的说话,故就产生了回声。所以回声消除的简单理解便是在B采集后的数据中除去A声音.

伪代码如下:

填充接收到的远端视频数据,目前为10ms数据长度也就是160个sample.

/*
 * Inserts an 80 or 160 sample block of data into the farend buffer.
 *
 * Inputs                       Description
 * -------------------------------------------------------------------
 * void*          aecInst       Pointer to the AEC instance
 * const float*   farend        In buffer containing one frame of
 *                              farend signal for L band
 * int16_t        nrOfSamples   Number of samples in farend buffer
 *
 * Outputs                      Description
 * -------------------------------------------------------------------
 * int32_t        return        0: OK
 *                              12000-12050: error code
 */
int32_t WebRtcAec_BufferFarend(void* aecInst,
                               const float* farend,
                               size_t nrOfSamples);

 添加近端采集的数据,内部包含回声,重点为延时时间的获取。

/*
 * Runs the echo canceller on an 80 or 160 sample blocks of data.
 *
 * Inputs                       Description
 * -------------------------------------------------------------------
 * void*         aecInst        Pointer to the AEC instance
 * float* const* nearend        In buffer containing one frame of
 *                              nearend+echo signal for each band
 * int           num_bands      Number of bands in nearend buffer
 * int16_t       nrOfSamples    Number of samples in nearend buffer
 * int16_t       msInSndCardBuf Delay estimate for sound card and
 *                              system buffers
 * int16_t       skew           Difference between number of samples played
 *                              and recorded at the soundcard (for clock skew
 *                              compensation)
 *
 * Outputs                      Description
 * -------------------------------------------------------------------
 * float* const* out            Out buffer, one frame of processed nearend
 *                              for each band
 * int32_t       return         0: OK
 *                              12000-12050: error code
 */
int32_t WebRtcAec_Process(void* aecInst,
                          const float* const* nearend,
                          size_t num_bands,
                          float* const* out,
                          size_t nrOfSamples,
                          int16_t msInSndCardBuf,
                          int32_t skew);

回声消除内部主要实现了四个模块:

回声延时估计:伪代码如下

// Estimates and returns the delay between the far-end and near-end blocks. The
// value will be offset by the lookahead (i.e. the lookahead should be
// subtracted from the returned value).
// Inputs:
//      - handle        : Pointer to the delay estimation instance.
//      - near_spectrum : Pointer to the near-end spectrum data of the current
//                        block.
//      - spectrum_size : The size of the data arrays (same for both far- and
//                        near-end).
//      - near_q        : The Q-domain of the near-end data.
//
// Output:
//      - handle        : Updated instance.
//
// Return value:
//      - delay         :  >= 0 - Calculated delay value.
//                        -1    - Error.
//                        -2    - Insufficient data for estimation.
int WebRtc_DelayEstimatorProcessFix(void* handle,
                                    const uint16_t* near_spectrum,
                                    int spectrum_size,
                                    int near_q);

NLMS:归一化均方最小自适应滤波算法,伪代码如下

// WebRtcAecm_UpdateChannel(...)
//
// This function performs channel estimation. NLMS and decision on channel storage.
//
//
// @param  aecm         [i/o]   Handle of the AECM instance.
// @param  far_spectrum [in]    Absolute value of the farend signal in Q(far_q)
// @param  far_q        [in]    Q-domain of the farend signal
// @param  dfa          [in]    Absolute value of the nearend signal (Q[aecm->dfaQDomain])
// @param  mu           [in]    NLMS step size.
// @param  echoEst      [i/o]   Estimated echo in Q(far_q+RESOLUTION_CHANNEL16).
//
void WebRtcAecm_UpdateChannel(AecmCore* aecm,
                              const uint16_t* far_spectrum,
                              const int16_t far_q,
                              const uint16_t* const dfa,
                              const int16_t mu,
                              int32_t* echoEst) {

NLP(非线性滤波)使用wiener滤波器伪代码如下

// CalcSuppressionGain(...)
//
// This function calculates the suppression gain that is used in the Wiener filter.
//
//
// @param  aecm     [i/n]   Handle of the AECM instance.
// @param  supGain  [out]   (Return value) Suppression gain with which to scale the noise
//                          level (Q14).
//
//
int16_t WebRtcAecm_CalcSuppressionGain(AecmCore* const aecm) {

CNG(舒适噪声产生),伪代码如下

 // Add comfort noise.
  ComfortNoise(aec->num_bands > 1, &aec->seed, efw, comfortNoiseHband,
               aec->noisePow, hNl);

模块的简单调用地址如下:https://github.com/quanwstone/WebRTC

总结:通过源码调用可以看出核心需要涉及到多个算法实现,后续单独分析。

你可能感兴趣的:(WebRTC)