原因:由于需要对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
总结:通过源码调用可以看出核心需要涉及到多个算法实现,后续单独分析。